URI, URL, URN 햇갈린다
여러개의 문자열로 매핑할 수도 있다.
@Controller
public class SampleController {
@RequestMapping({"/hello", "/hi"})
@ResponseBody
public String hello(){
return "hello";
}
}
테스트 코드
@RunWith(SpringRunner.class)
@WebMvcTest
public class SampleControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void helloTest() throws Exception{
mockMvc.perform(get("/hello"))
.andDo(print())
.andExpect(status().isOk());
mockMvc.perform(get("/hi"))
.andDo(print())
.andExpect(status().isOk());
}
}
요청 식별자로 맵핑하기
한글자만 맵핑
@Controller
public class SampleController {
@GetMapping("/hello?")
@ResponseBody
public String hello(){
return "hello";
}
}
테스트 코드
@RunWith(SpringRunner.class)
@WebMvcTest
public class SampleControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void helloTest() throws Exception{
mockMvc.perform(get("/hello1"))
.andDo(print())
.andExpect(status().isOk());
}
}
Path가 있고 그 다음에 한 글자가 올 수도 있다.
@Controller
public class SampleController {
@GetMapping("/hello/?")
@ResponseBody
public String hello(){
return "hello";
}
}
테스트 코드
@RunWith(SpringRunner.class)
@WebMvcTest
public class SampleControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void helloTest() throws Exception{
mockMvc.perform(get("/hello/1"))
.andDo(print())
.andExpect(status().isOk());
}
}
여러 글자가 오는 경우
@Controller
public class SampleController {
@GetMapping("/hello/*")
@ResponseBody
public String hello(){
return "hello";
}
}
테스트 코드
@RunWith(SpringRunner.class)
@WebMvcTest
public class SampleControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void helloTest() throws Exception{
mockMvc.perform(get("/hello/123"))
.andDo(print())
.andExpect(status().isOk());
}
}
여러 Path가 오는 경우
@Controller
public class SampleController {
@GetMapping("/hello/**")
@ResponseBody
public String hello(){
return "hello";
}
}
테스트 코드
@RunWith(SpringRunner.class)
@WebMvcTest
public class SampleControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void helloTest() throws Exception{
mockMvc.perform(get("/hello/123/456"))
.andDo(print())
.andExpect(status().isOk());
}
}
클래스에 선언한 @RequestMapping과 조합
@Controller
@RequestMapping("/hello")
public class SampleController {
@GetMapping("/**")
@ResponseBody
public String hello(){
return "hello";
}
}
테스트 코드
@RunWith(SpringRunner.class)
@WebMvcTest
public class SampleControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void helloTest() throws Exception{
mockMvc.perform(get("/hello/123/456"))
.andDo(print())
.andExpect(status().isOk());
}
}
정규 표현식으로 맵핑할 수도 있다.
@Controller
@RequestMapping("/hello")
public class SampleController {
@RequestMapping("/{name:[a-z]+}")
@ResponseBody
public String hello(@PathVariable String name){
return "hello " + name;
}
}
테스트 코드
@RunWith(SpringRunner.class)
@WebMvcTest
public class SampleControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void helloTest() throws Exception{
mockMvc.perform(get("/hello/spring"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().string("hello spring"));
}
}
테스트 코드2 : 영문자가 아닌 숫자를 넣으면 테스트가 깨진다.
@RunWith(SpringRunner.class)
@WebMvcTest
public class EventControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void helloTest() throws Exception{
mockMvc.perform(get("/hello/123"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().string("hello spring"));
}
}
패턴이 중복되는 경우에는?
@Controller
@RequestMapping("/hello")
public class SampleController {
@RequestMapping("/spring")
@ResponseBody
public String hellospring(){
return "hello spring";
}
@RequestMapping("/*")
@ResponseBody
public String hello(){
return "hello";
}
}
테스트 코드
@RunWith(SpringRunner.class)
@WebMvcTest
public class SampleControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void helloTest() throws Exception{
mockMvc.perform(get("/hello/spring"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().string("hello spring"));
}
}
테스트 코드2 : 어떤 핸들러에 매핑되었는지 알고싶다.
@RunWith(SpringRunner.class)
@WebMvcTest
public class SampleControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void helloTest() throws Exception{
mockMvc.perform(get("/hello/spring"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().string("hello spring"))
.andExpect(handler().handlerType(SampleController.class))
.andExpect(handler().methodName("hellospring"));
}
}
URI 확장자 맵핑 지원
스프링 MVC는 암묵적으로 다음과 같은 매핑을 해준다.
@Controller
@RequestMapping("/hello")
public class SampleController {
@RequestMapping({"/spring", "/spring.*"})
@ResponseBody
public String hellospring(){
return "hello spring";
}
}
스프링 MVC에서는 spring.json, spring.html, spring.xml도 처리할 수 있게끔 해준다.
테스트 코드 : 스프링 부트 X, DispatcherServlet /app으로 매핑
@Controller
public class helloController {
@Autowired
HelloService helloService;
@GetMapping("/hello")
@ResponseBody
public String hello(){
return "Hello, " + helloService.getName();
}
}
@Service
public class HelloService {
public String getname(){
return "spring";
}
}
이를 톰캣에서 실행해보면 http://localhost:8080/app/hello, http://localhost:8080/app/hello.json도 실행된다.
RFD Attack
테스트 코드 : 스프링 부트
@Controller
@RequestMapping("/hello")
public class SampleController {
@RequestMapping("/spring")
@ResponseBody
public String hellospring(){
return "hello spring";
}
}
@RunWith(SpringRunner.class)
@WebMvcTest
public class SampleControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void helloTest() throws Exception{
mockMvc.perform(get("/hello/spring.json"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().string("hello spring"))
.andExpect(handler().handlerType(SampleController.class))
.andExpect(handler().methodName("hellospring"));
}
}
@RunWith(SpringRunner.class)
@WebMvcTest
public class SampleControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void helloTest() throws Exception{
mockMvc.perform(get("/hello/spring.json"))
.andDo(print())
.andExpect(status().isNotFound());
}
}
최근의 추세는 Accept 헤더에 어떤 타입을 원한다고 지정을 해두면 확장자를 보지 않더라도 서버가 헤더에 있는 내용을 보고 판단할 수 있다.
또한 헤더가 불편하면 파라미터로 지정하는 방법도 있다. ?type=
또한 확장자가 없는 요청과 같이 지원할 수도 있다. 그러나 이 방법은 권장하지 않는다.
@Controller
@RequestMapping("/hello")
public class SampleController {
@RequestMapping({"/spring", "/spring.*"})
@ResponseBody
public String hellospring(){
return "hello spring";
}
}
@RunWith(SpringRunner.class)
@WebMvcTest
public class SampleControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void helloTest() throws Exception{
mockMvc.perform(get("/hello/spring.xml"))
.andDo(print())
.andExpect(status().isOk());
mockMvc.perform(get("/hello/spring"))
.andDo(print())
.andExpect(status().isOk());
}
}
참고