DTO
@Data
public class SampleDTO {
private String name;
private int age;
}
컨트롤러
@GetMapping("/autoCollect")
public void parameterAutoCollect(SampleDTO dto) {
SampleDTO parameters = dto;
log.info(parameters);
log.info(parameters.getAge() == 1);
}
이렇게만 해두고 브라우저에
http://localhost:8080/sample/autoCollect?name=cocolee&age=20
를 요청한다.
INFO : com.coco.controller.SampleController - SampleDTO(name=cocolee, age=20)
INFO : com.coco.controller.SampleController - true
보다시피,
parameters.getAge() == 1
의 결과는 true
다.
바이. Integer.parseInt(request.getParamter("age")
클라이언트가 전송하는 파라미터 인자의 이름과, 컨트롤러에 지정한 파라미터의 이름이 다르다면 파라미터를 수집할 수 없다. 그럴 경우, @RequestParam을 이용해서 전달 받을 파라미터의 이름을 지정할 수 있다.
@GetMapping("/paramList")
public void parameterIsList(@RequestParam("alphabet")ArrayList<String> list) {
log.info(list);
}
@GetMapping("/paramArr")
public void parameterIsArray(@RequestParam("alphabet")String[] arr) {
log.info(Arrays.toString(arr));
}
위 두 메서드처럼 같은 이름으로 파라미터를 여러 개 받아야 하는 경우에는 반드시 @RequestParam으로 이름을 지정해야 한다.
브라우저에
http://localhost:8080/sample/paramList?alphabet=a&alphabet=b&alphabet=c&alphabet=b&alphabet=d
를 요청하면
[a, b, c, b, d]
라는 결과를 얻을 수 있다.
❔ SampleDTO는 @RequestParam 없이도 자동 수집이 되는데, List 또는 Array는 왜 안 될까?
개발하다보면 DTO 같은 객체를 한 번에 여러 개 받아야 할 때가 있다.
DTOList클래스
@Data
public class SampleDTOList {
private List<SampleDTO> list;
public SampleDTOList() {
list = new ArrayList<>();
}
}
컨트롤러
@GetMapping("/objectList")
public void objectList(SampleDTOList list) {
log.info(list);
}
http://localhost:8080/sample/objectList?list%5b0%5D.name=cocolee&list%5b0%5D.age=20&list%5b1%5D.name=dodo&list%5b1%5D.age=44&list%5b3%5D.name=dodo&list%5b3%5D.age=123
로 요청하면 원하는 결과를 얻을 수 있다.
결과
INFO : com.coco.controller.SampleController -
SampleDTOList(list=[SampleDTO(name=cocolee, age=20),
SampleDTO(name=dodo, age=44),
SampleDTO(name=null, age=0),
SampleDTO(name=dodo, age=123)])
파라미터를 수집할 때, Date타입은 직접 변환해서 처리해야 한다. 스프링 컨트롤러에서는 파라미터를 바인딩할 때 자동으로 호출하는 @initBinder를 이용해서 변환할 수 있다.
테스트로 쓸 클래스
@Data
public class TodoDTO {
private String title;
private Date dueDate;
}
컨트롤러
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
binder.registerCustomEditor(java.util.Date.class,
new CustomDateEditor(dateFormat, false));
}
@GetMapping("dateBind")
public void dateBind(TodoDTO dto) {
log.info(dto);
}
http://localhost:8080/sample/dateBind?title=dateBindTest&dueDate=2020-08-22
호출 시
INFO : com.coco.controller.SampleController - TodoDTO(title=dateBindTest, dueDate=2020-08-22)
제대로 변환된 결과를 얻을 수 있다.
@DateTimeFormat을 이용하는 경우, @initBinder는 필요하지 않다.
@DateTimeFormat는 파라미터로 사용될 Date타입 인스턴스 위에 달아주면 된다.
@Data
public class TodoDTO {
private String title;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date dueDate;
}