인프런에서 백기선님의 스프링부트 개념과 활용 강의를 듣고, 개인적으로 공부하며 핵심만 정리한 글입니다.
스프링 웹 MVC 설정
스프링부트는 자동설정을 통해 스프링 웹 MVC 설정들을 기본적으로 제공해준다.
그런데 이 중 일부를 수정하거나, 아니면 내가 원하는대로 완전히 바꾸고 싶을 땐 어떻게 해야할까.
다음과 같은 방법들이 있다.
- 자동설정된 스프링 MVC를 확장하는 경우
@Configuration
+WebMvcConfigurer
- 아예 스프링 MVC를 원하는 대로 재정의 하는 경우
@Configuration
+@EnableWebMvc
HttpMessageConverters
(HTTP 요청 -> 객체) 로 매핑 또는 (객체 -> HTTP 응답) 하는데 사용
예를 들면 다음과 같은 요청이
{
"userName": "heumsi",
"password": 123
}
다음과 같은 객체로 매핑이 되는 과정이다.
class User {
private Long id;
private String userName;
private String password;
}
이를 스프링에서 사용하기 위해서는 @RequestBody
, @ResponseBody
와 같은 어노테이션을 활용한다.
예를 들면 다음과 같다.
@Controller
public class UserController {
@PostMapping("/user")
public @ResponseBody User create(@RequestBody User user) {
return user;
}
}
@Controller
대신 @RestController
를 사용하면, @ResponseBody
를 붙이지 않아도, 이런 HttpMessageConvert 를 자동으로 해준다.
예를 들어 위 코드는 다음과 같다.
@RestController
public class UserController {
@PostMapping("/user")
public User create(@RequestBody User user) {
return user;
}
}
만약 @Controller
를 사용하는데 매핑 리턴 값으로 "heumsi"
와 같은 String
타입을 리턴하면, 이는 ViewNameResolver 가 heumsi
에 해당하는 View 를 찾으라는 의미가 된다.
@RestController 와 @Controller 의 차이
- HTTP Response Body가 생성되는 방식이 다르다.
- @Controller 는 View Page 를 반환하지만
- @RestController 는 객체를 반환하기만 하면 application/json 타입의 HTTP Response 에 객체를 담아 반환한다.
위 코드를 테스팅 코드로 작성하면 다음과 같다.
@RunWith(SpringRunner.class)
@WebMvcTest(UserController.class)
public class UserControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void createUser_JSON() throws Exception{
String userJson = "{\"username\":\"heumsi\", \"password\":\"123\"}";
mockMvc.perform(post("/users/create")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.accept(MediaType.APPLICATION_JSON_UTF8)
.content(userJson))
.andExpect(status().isOk())
.andExpect(jsonPath("$.username", is(equalTo("heumsi"))))
.andExpect(jsonPath("$.password", is(equalTo("123"))));
}
}
ContentNegotiatingViewResolver
서버로 들어오는 요청의 헤더에는 accept
라는 키가 있다.
이 값에는 클라이언트가 원하는 응답의 형태가 값으로 담기는데, 위 테스팅 코드를 살펴보면 APPLICATION_JSON_UTF8
가 보인다.
ContentNegotiatingViewResolver 는 이렇게 요청의 accept
에 맞춰 자동으로 응답을 변환시켜준다. 즉 위에서 application/json
타입으로 변환하는 작업을 한게 바로 이 ContentNegotiatingViewResolver 라는 것이다.
json
의 경우 클래스패스에 내장되어있는 기본 라이브러리를 통해 가능하지만, xml
의 경우, pom.xml
에 별도의 라이브러리를 추가해줘야 한다.
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.9.6</version>
</dependency>
xml
을 accept
로 두고, 테스트 코드를 작성하면 다음과 같다.
@RunWith(SpringRunner.class)
@WebMvcTest(UserController.class)
public class UserControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void createUser_XML() throws Exception{
String userJson = "{\"username\":\"heumsi\", \"password\":\"123\"}";
mockMvc.perform(post("/users/create")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.accept(MediaType.APPLICATION_XML)
.content(userJson))
.andExpect(status().isOk())
.andExpect(xpath("/User/username").string("heumsi"))
.andExpect(xpath("/User/password").string("123"));
}
}
'더 나은 엔지니어가 되기 위해 > 지금은 안쓰는 자바' 카테고리의 다른 글
[스프링 부트 개념과 활용] 웹 MVC 설정 3. ExceptionHandler (0) | 2020.02.06 |
---|---|
[스프링 부트 개념과 활용] 웹 MVC 설정 2. 정적 리소스와 웹 JAR (0) | 2020.02.05 |
[스프링 부트 개념과 활용] 테스트 (0) | 2020.02.04 |
[스프링 부트 개념과 활용] 로깅 (0) | 2020.02.03 |
[스프링 부트 개념과 활용] Profile (0) | 2020.02.03 |