1. @RequestParam
- 요청의 파라미터를 연결할 매개변수에 붙이는 애너테이션
@RequestMapping("/requestParam2")
// public String main2(@RequestParam(name="year", required=false) String year) { // 아래와 동일
public String main2(String year) {
System.out.printf("[%s]year=[%s]%n", new Date(), year);
return "yoil";
}
(@RequestParam(name="year", required=false) String year) 생략가능.
// http://localhost/ch2/requestParam2 ---->> year=null
// http://localhost/ch2/requestParam2?year ---->> year=""
year = null, year = "" 다름
@RequestMapping("/requestParam3")
// public String main3(@RequestParam(name="year", required=true) String year) {
// 아래와 동일
public String main3(@RequestParam String year) {
System.out.printf("[%s]year=[%s]%n", new Date(), year);
return "yoil";
}
// http://localhost/ch2/requestParam3 ---->> year=null 400 Bad Request. required=true라서
// http://localhost/ch2/requestParam3?year ---->> year=""
400 Bad Request. required가 true라서.. 필수입력이 true 인데 왜안써?
그러니깐 클라이언트가 잘못했네 !! 400번대 오류.
400번대 에러는 클라이언트, 500번대 에러는 서버에러.
@RequestMapping("/requestParam8")
public String main8(@RequestParam(required=false) int year) {
System.out.printf("[%s]year=[%s]%n", new Date(), year);
return "yoil";
}
// http://localhost/ch2/requestParam8 ----
필수 입력이 아니라, 클라이언트 잘못아님. 그래서 서버에러.
null -> int 변환 불가 그래서 에러남.
>> 500 java.lang.IllegalStateException: Optional int parameter 'year' is present but cannot be translated into a null value due to being declared as a primitive type. Consider declaring it as object wrapper for the corresponding primitive type.
값을 주었는데 잘못줌. 그럼 클라이언트 에러.
"" -> int로 변환 불가.
// http://localhost/ch2/requestParam8?year ---->> 400 Bad Request, nested exception is java.lang.NumberFormatException: For input string: ""
@RequestMapping("/requestParam11")
public String main11(@RequestParam(required=false, defaultValue="1") int year) {
System.out.printf("[%s]year=[%s]%n", new Date(), year);
return "yoil";
}
defaultValue값을 "1"로 주었을 때는 입력하지 않아도 에러 안남.
// http://localhost/ch2/requestParam11 ---->> year=1
// http://localhost/ch2/requestParam11?year ---->> year=1
@RequestMapping("/requestParam9")
public String main9(@RequestParam(required=true) int year) {
System.out.printf("[%s]year=[%s]%n", new Date(), year);
return "yoil";
}
필수 입력인데 값을 안줬으니깐 클라이언트 잘못.
// http://localhost/ch2/requestParam9 ---->> 400 Bad Request, Required int parameter 'year' is not present
"" -> int 변환 불가.
// http://localhost/ch2/requestParam9?year ---->> 400 Bad Request, nested exception is java.lang.NumberFormatException: For input string: ""
★한글 필터 등록 web.xml★

<!-- 한글 변환 필터 시작 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 한글 변환 필터 끝 -->

컨트롤러 예외처리.(차후 다시 설명.)
@ExceptionHandler(Exception.class)
public String catcher(Exception ex) {
return "yoilError";
}
log4j.xml 로깅 설정
콘솔 로그에 기록을 남겨주는 파일인가봄.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- Appenders -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: %c - %m%n" />
</layout>
</appender>
<!-- Application Loggers -->
<logger name="com.fastcampus.ch2">
<level value="info" />
</logger>
<!-- 3rdparty Loggers -->
<logger name="org.springframework.core">
<level value="info" />
</logger>
<logger name="org.springframework.beans">
<level value="info" />
</logger>
<logger name="org.springframework.context">
<level value="info" />
</logger>
<logger name="org.springframework.web">
<level value="info" />
</logger>
<!-- Root Logger -->
<root>
<priority value="warn" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
SetterCall.java
package com.fastcampus.ch2;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.springframework.util.StringUtils;
public class SetterCall {
public static void main(String[] args) throws Exception{
Map<String, String> map = new HashMap<>();
map.put("year", "2021");
map.put("month", "10");
map.put("day", "1");
Class<?> type = Class.forName("com.fastcampus.ch2.MyDate");
// MyDate인스턴스를 생성하고, map의 값으로 초기화한다.
Object obj = dataBind(map, type);
System.out.println("obj="+obj); // obj=[year=2021, month=10, day=1]
} // main
private static Object dataBind(Map<String, String> map, Class<?> clazz) throws Exception {
// 1. MyDate인스턴스 생성
// Object obj = clazz.newInstance(); // deprecated method
Object obj = clazz.getDeclaredConstructor().newInstance(new Object[0]);
// 2. MyDate인스턴스의 setter를 호출해서, map의 값으로 MyDate를 초기화
// 2-1. MyDate의 모든 iv를 돌면서 map에 있는지 찾는다.
// 2-2. 찾으면, 찾은 값을 setter로 객체에 저장한다.
Field[] ivArr = clazz.getDeclaredFields();
for(int i=0;i<ivArr.length;i++) {
String name = ivArr[i].getName();
Class<?> type = ivArr[i].getType();
// map에 같은 이름의 key가 있으면 가져와서 setter호출
Object value = map.get(name); // 못찾으면 value의 값은 null
Method method = null;
try { // map에 iv와 일치하는 키가 있을 때만, setter를 호출
if(value==null) continue;
method = clazz.getDeclaredMethod(getSetterName(name), type); // setter의 정보 얻기
System.out.println("method="+method);
method.invoke(obj, convertTo(value, type)); // obj의 setter를 호출
} catch(Exception e) {
e.printStackTrace();
}
}
System.out.println(Arrays.toString(ivArr));
return obj;
}
private static Object convertTo(Object value, Class<?> type) {
// value의 타입과 type의 타입이 같으면 그대로 반환
if(value==null || type==null || type.isInstance(value))
return value;
// value의 타입과 type이 다르면, 변환해서 반환
if(String.class.isInstance(value) && type==int.class) // String -> int
return Integer.valueOf(""+value);
return value;
}
// iv의 이름으로 setter의 이름을 만들어서 반환하는 메서드("day" -> "setDay")
private static String getSetterName(String name) {
// return "set"+name.substring(0,1).toUpperCase()+name.substring(1);
return "set" + StringUtils.capitalize(name); // org.springframework.util.StringUtils
}
}
/*
[실행결과]
method=public void com.fastcampus.ch2.MyDate.setYear(int)
method=public void com.fastcampus.ch2.MyDate.setMonth(int)
method=public void com.fastcampus.ch2.MyDate.setDay(int)
[private int com.fastcampus.ch2.MyDate.year, private int com.fastcampus.ch2.MyDate.month, private int com.fastcampus.ch2.MyDate.day]
obj=[year=2021, month=10, day=1]
*/
'Java & Spring > SpringFramework' 카테고리의 다른 글
| 18. @RequestMapping 21:56 (0) | 2022.08.01 |
|---|---|
| 16. 서블릿과 JSP(4) 21:36 (0) | 2022.08.01 |
| 15. 서블릿과 JSP(3) 39:36 (0) | 2022.08.01 |
| 14. 서블릿과 JSP(2) 25:09 (0) | 2022.08.01 |
| 13. 서블릿과 JSP(1) 31:47 (0) | 2022.08.01 |