스프링 MVC를 이용하는 경우 Controller의 특징
=> 각 어노테이션의 의미에 대해 주의하며 학습 @
@Controller
@RequestMapping("/sample")
public class SampleController {
}
작성된 해당 클래스는 자동으로 스프링의 Bean으로 등록이 된다. 무엇때문에?
바로 servlet-context.xml의 태그 때문에 등록이 되는 것.
<context:component-scan base-package="org.zerock.controller" />
해당 파일에서는 component-scan태그를 통해 해당 package내의 클래스들을 조사하면서, Bean설정에 사용되는 어노테이션들을 가진 클래스들을 파악하고, 필요시 객체로 생성 및 관리하기 때문이다.
스프링이 관리해주는 파일은 옆에 S라고 추가된다.
@RequestMapping
현재 클래스내의 모든 메소드들의 기본 URL경로가 된다.
클래스선언뿐만아니라 메소드선언에도 사용 가능하다.
method 속성(GET, POST방식으로 구분할 때 사용)
@GetMapping @PostMapping
클라이언트의 요청에 필요한 데이터를 추출하고, VO 또는 DTO로 변환하는 파라미터 수집 작업! 스프링 MVC는 이를 자동으로 처리해줌 ! => RequestParam 어노테이션으로!
매번 request.getParameter()을 사용하지 않아도 됨.
@Data
public class SampleDTO {
private String name;
private int age;
}
@Log4j
@RequestMapping("/sample/*")
@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
@GetMapping("/ex01")
public String ex01(SampleDTO dto) {
dto.setAge(10);
dto.setName("seongsang");
log.info("" + dto);
return "ex01";
}
INFO : org.zerock.controller.HomeController - SampleDTO(name=seongsang, age=10)
배열, 배열리스트, 객체리스트 처리
//배열
@GetMapping("/ex02Array")
public String ex02Array(@RequestParam("ids") String[] ids) {
log.info("array ids :" + Arrays.deepToString(ids));
return "ex02Array";
}
//배열리스트
@GetMapping("/ex02List")
public String ex02List(@RequestParam("ids")ArrayList<String> ids) {
log.info("ids" + ids);
return "ex02List";
}
객체안의 속성이 제대로 수집됨.(자동으로 타입을 변환해 처리한다!)(set하지 않아도 name은 null, age는 0이 기본값)
http://localhost:8090/sample/ex02List?ids=111&ids=222&ids=333 를 브라우저에 요청하면 각 배열원소를 받을 수 있다.
@RequestParam
객체리스트
@Data
public class SampleDTOList {
private List<SampleDTO> list;
public SampleDTOList() {
list = new ArrayList<>();
}
}
sample/ex02Bean?list%5B0%5D.name=aaa&list%5B2%5D.name=bbb
해당 URL호출시 객체는 3개 생성되고, 각 객체에 대한 정보 출력이 됨.
파라미터 수집 = 바인딩
변환가능 데이터는 자동으로 변환되지만 파라미터를 변환해서 처리해야하는 경우가 발생할 수도 있다. 2020-05-14라는 문자열을 Date타입으로 변환하는 작업이 그 예이다.
위의 예시는 @InitBinder을 이용해 처리할 수 있다.
예를 살펴보자
먼저, TodoDTO 클래스를 작성한다.
@Data
public class TodoDTO {
private String title;
private Date dueData;
}
이를 처리할 initBinder을 이용하는 메소드 작성한다
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
binder.registerCustomEditor(java.util.Date.class, new CustomDateEditor(dateFormat, false));
}
@GetMapping("/ex03")
public String ex03(TodoDTO todo) {
log.info("todo: " + todo);
return "ex03";
}
http://localhost:8090/sample/ex03?title=test&dueData=2020-05-12 ->
또는, @DateTimeFormat을 이용해 변환할 수 있다. 해당 경우엔 @InitBinder이 필요 없다. 형식만 맞으면 변환된다.
@Data
public class TodoDTO {
private String title;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date dueData;
}
Log4j에서 import가 제대로 읽히지 않는 에러가 발생했었다.
Log4j관련 설정 하위에 <scope> runtime</scope>를 지워주니 해결되었다.
runtime : 컴파일 시에는 필요하지 않지만 실행시에 사용되는 경우 사용한다. 이 옵션은 런타임, 테스트 시 classpath에 추가 되지만, 컴파일시에는 추가 되지 않는다.