2020-7-5 스프링 MVC(2)
Springboot
- springboot 기본설정에서 dispatcherServlet의 doservice 디버거를 찍어보면 handlerMapping의 5개의 핸들러매핑이 등록되있다.
- HandlerMapping : requestMappingHandlerMapping, BeanNameUrlHandlerMapping, RouterFunctinoMapping, SimpleUrlHandlerMapping, WelcomepageHandlerMapping
- handlerAdopter
- ViewSolver : ContentNegotiation이라는 viewResolver가 viewResolver이름에 대해서 처리
- 자동설정에 대한 모든 설정은 spring.factories에 저장되어있다.
- 스프링부트의 주관이 적용된 자동설정이 동작
- JSP보단 Thymleaf선호
- JSON지원
- 정적리소스지원(welcomepage, favicon)
- MVC커스터마이징
- application.properties : ResourceProperties 클래스에 들어가면 설정관련된 메서드들이 있다. application.properties에 설정하기 위해서는 ResourceProperties 클래스를 잘봐라. => 가장 베스트
- @Configuration + Implements WebMvcConfigure : 스프링부트의 MVC자동설정 + 추가설정
- @Configuration + @EnableWebMvc : 스프링부트의 스프링MVC자동설정 사용하지 않음. 이때 implements WebMvcConfigure를 구현해야 편하다.
WebMvcConfigurer 설정
-
formatter
-
@RestController public class SampleController { @GetMapping("/hello/{name}") public String hello(@PathVariable String name) { return "hello" + name; } } @WebMvcTest @RunWith(SpringRunner.class) class SampleControllerTest { @Autowired private MockMvc mockMvc; @Test public void hello() throws Exception { this.mockMvc.perform(get("/hello/jimmy")) .andDo(print()) .andExpect(content().string("hello jimmy")); } }
-
@PathVariable이 아니라 Formatter를 이용하면 객체를 문자열, 문자열 => 객체로 변환할 수 있다.
-
@RestController public class SampleController { @GetMapping("/hello/{name}") public String hello(@PathVariable("name") Person person) { return "hello" + person.getName(); } } // springMVC가 name이 Person으로 아직 변환을 못해준다. Formatter를 써야된다.
-
formatter는 printer(객체 => 문자), parser(문자 => 객체)가 합쳐졌다.
-
public class PersonFormatter implements Formatter<Person> { @Override public Person parse(String s, Locale locale) throws ParseException { Person person = new Person(); person.setName(s); return person; } @Override public String print(Person person, Locale locale) { return person.toString(); } } public class WebConfig implements WebMvcConfigurer { @Override public void addFormatters(FormatterRegistry registry) { registry.addFormatter(new PersonFormatter()); } } @RestController public class SampleController { @GetMapping("/hello") public String hello(@RequestParam("name") Person person) { return "hello " + person.getName(); } } @WebMvcTest @RunWith(SpringRunner.class) class SampleControllerTest { @Autowired private MockMvc mockMvc; @Test public void hello() throws Exception { this.mockMvc.perform(get("/hello") .param("name", "jimmy")) .andDo(print()) .andExpect(content().string("hello jimmy")); } }
-
기존에 formatter를 등록하기 위해서는 WebMvcConfigurer를 구현해서 addFormatter를 쓴다.
-
여기서 Converter도 등록할 수 있다.
-
결론 : SpringBoot에서는 Formatter를 Bean으로 등록하면 알아서 등록해준다.
- @WebMvc는 Web과 관련된 빈들만 등록해준다. 따라서 WebConfig를 지우고, PersonFormatter만 빈으로 등록하면 테스트가 깨진다. @SpringBootTest를 사용하면 모든 빈들을 다 등록해준다.
-
-
도메인 클래스 컨버터
-
@SpringBootTest @AutoConfigureMockMvc @RunWith(SpringRunner.class) class SampleControllerTest { @Autowired private MockMvc mockMvc; @Autowired private PersonRepository personRepository; @Test public void hello() throws Exception { Person person = new Person("jimmy"); personRepository.save(person); this.mockMvc.perform(get("/hello") .param("id", "jimmy")) .andDo(print()) .andExpect(content().string("hello jimmy")); } } public interface PersonRepository extends JpaRepository<Person, Long> { }
-
스프링 데이터 JPA는 도메인 클래스 컨버터를 제공한다. Repository를 사용해 ID에 해당하는 엔티티를 읽는다.
- JPA가 도메인 클래스 컨버터를 자동으로 등록해준다.
-
그밖의 설정
-
CORS설정 : CrossOrigin요청 처리 설정, 같은 도메인에서 온 요청이 아니더라도 처리를 허용하고 싶으면 쓴다.
- 리턴값 핸들러설정 : 스프링 MVC가 제공하는 기본 리턴 값 핸들러외에 리턴핸들러를 추가하고 싶을때
- ArgumentResolver : 스프링MVC가 제공하는 기본 argument resolver이외에 커스텀한 리졸버를 추가하고 싶을때
- 뷰컨트롤러 : 단순하게 요청 URL을 특정 뷰로 연결하고 싶을때.
- 비동기설정 : 비동기 요청 처리에 사용할 타임아웃이나 TaskExecutor를 사용할 수 있다.
- 뷰리졸버 : 핸들러에서 리턴하는 뷰 이름에 해당하는 문자열을 view 인스턴스로 바꿔줄 뷰 리솔져를 설정
- Content Negotiation : 요청 본문, 응답 본문을 어떤 MIME타입으로 보내야하는지 결정
Written on July 5, 2020