Spring/Spring MVC

[Spring] HTTP 요청 맵핑 - 미디어 타입

TheWing 2020. 11. 15. 16:21

미디어 타입 맵핑

특정한 타입의 데이터를 담고 있는 요청만 처리하는 핸들러

  • @RequestMapping(consumes=MediaType.APPLICATION_JSON_UTF8_VALUE)
  • Content-Type 헤더로 필터링
  • 매치 되는 않는 경우에 415 Unsupported Media Type 응답

특정한 타입의 응답을 만드는 핸들러

  • @RequestMapping(produces=”application/json”)
  • Accept 헤더로 필터링 (하지만 살짝... 오묘함)
  • 매치 되지 않는 경우에 406 Not Acceptable 응답

문자열을 입력하는 대신 MediaType을 사용하면 상수를 (IDE에서) 자동 완성으로 사용할 수 있다.
클래스에 선언한 @RequestMapping에 사용한 것과 조합이 되지 않고 메소드에 사용한
@RequestMapping의 설정으로 덮어쓴다.
Not (!)을 사용해서 특정 미디어 타입이 아닌 경우로 맵핑 할 수도 있다.

예제

@Controller
public class SampleController {

    @RequestMapping(
            value = "/hello",
            consumes = MediaType.APPLICATION_JSON_VALUE
    )
    @ResponseBody
    public String hello() {
        return "hello";
    }

}
@WebMvcTest
public class SampleControllerTest {

    @Autowired
    MockMvc mockMvc;

    @Test
    public void helloTest() throws Exception {
        mockMvc.perform(get("/hello")
                .contentType(MediaType.APPLICATION_JSON))
                .andDo(print())
                .andExpect(status().isOk())
        ;

    }

}

  • 결과가 정상으로나온다

accept를 주는 예시

@WebMvcTest
public class SampleControllerTest {

    @Autowired
    MockMvc mockMvc;

    @Test
    public void helloTest() throws Exception {
        mockMvc.perform(get("/hello")
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON)
        )
                .andDo(print())
                .andExpect(status().isOk())
        ;

    }

}
@Controller
public class SampleController {

    @RequestMapping(
            value = "/hello",
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.TEXT_PLAIN_VALUE

    )
    @ResponseBody
    public String hello() {
        return "hello";
    }
}
  • 이렇게 테스트 했을 때 결과는 실패한다 accept를 json으로 원하는데 컨트롤러는 text로 받는다고 하기 때문이다
@WebMvcTest
public class SampleControllerTest {

    @Autowired
    MockMvc mockMvc;

    @Test
    public void helloTest() throws Exception {
        mockMvc.perform(get("/hello")
                .contentType(MediaType.APPLICATION_JSON)
        )
                .andDo(print())
                .andExpect(status().isOk())
        ;

    }

}
  • accept를 주지 않으면 테스트는 성공한다.
  • 아무렇게 결과를 줘도 상관이 없기 때문이다
@Controller
@RequestMapping(consumes = MediaType.APPLICATION_XML_VALUE)
public class SampleController {

    @RequestMapping(
            value = "/hello",
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.TEXT_PLAIN_VALUE

    )
    @ResponseBody
    public String hello() {
        return "hello";
    }
}
  • 이와 같이 클래스에 consumes를 주면 메소드 자체에서 오버라이딩 하여 사용하기 때문에 @RequestMapping(consumes = MediaType.APPLICATION_XML_VALUE) 이건 적용되지 않는다.

Reference