@RestController
public class MappingController {
private Logger logger = LoggerFactory.getLogger(getClass());
@RequestMapping("/hello-basic")
public String helloBasic() {
logger.info("basic");
return "ok";
}
}
@RequestMapping({"/hello-basic","/hello-go"})
public String helloBasic() {
logger.info("basic");
return "ok";
}
{ } 안에 url를 여러개 넣어서 매핑할 수 있다.
@RequestMapping(value = {"/hello-basic", "/hello-go"}, method = RequestMethod.GET)
public String helloBasic() {
logger.info("basic");
return "ok";
}
위와같이 @RequestMapping으로 method 매핑가능.
@RestController
public class MappingController {
private Logger logger = LoggerFactory.getLogger(getClass());
@RequestMapping(value = "/mapping-get-v1", method = RequestMethod.GET) //@RequestMapping에 method를 매핑하는방식
public String mappingGetV1() {
logger.info("mappingGetV1");
return "ok";
}
@GetMapping("/mapping-get-v2") // 메소드가 축약되어있는 어노테이션을 사용
public String helloBasic() {
logger.info("basic");
return "ok";
}
}
PathVariable(경로변수) 사용
//PathVariable사용 가능하다. url주소 자체안에 값을 변수의 값으로 인식하고 사용한다. (경로변수라고도 한다)
@GetMapping("/mapping/{userId}")
public String mappingPath(
@PathVariable("userId") String data) { // @Pathvariable("파라미터이름")을 이용해서 매개변수로 꺼낼수있다.
logger.info("mappingPath : {}", data);
return "ok";
}
@GetMapping안에 @RequestMapping이 들어있으니 @RequestMapping이라고 부른다. 결국 요청매핑이니까
URL경로의 템플릿화는
"/mapping/{userId}"
처럼 값을 받을수있게끔 한것을 말한다.
@PathVariable의 이름(@PathVariable을 받을 변수의 이름)과 파라미터 이름이 같으면 생략가능하다.
@GetMapping("/mapping/{userId}")
public String mappingPath(
@PathVariable String userId) { //이런식으로 파라미터이름과 Pathvariabe 이름이 같으므로 바로 받을 수 있다.
logger.info("mappingPath : {}", userId);
return "ok";
}
변수명에 맞추고 싶다면 위처럼, 받은 파라미터값과 변수명을 다르게하고싶다면 @PathVariable(파라미터명)으로
PathVariable 사용 - 다중
@GetMapping("/mapping/users/{userId}/orders/{orderId}")
public String mappingPath2(@PathVariable String userId, @PathVariable Long orderId) {
logger.info("mappingPath userId={} orderId={}", userId, orderId);
return "ok";
}
다음과같이 url경로에 PathVariable을 여러개 사용가능하다.
http://localhost:8080/mapping/users/userA/orders/100 식으로 userA이고 주문번호 100으로 들어왔다.
뭔가 users뒤에 유저아이디 들어가고 orders 뒤에 주문번호가 들어가니까 직관적인거 같다.
파라미터 조건 추가 매핑
파라미터 조건을 걸 수 있다.
URL 매핑 + 파라미터 조건 매핑
/**
* 파라미터로 추가 매핑
* params="mode",
* params="!mode"
* params="mode=debug"
* params="mode!=debug" (! = )
* params = {"mode=debug","data=good"}
*/
@GetMapping(value = "/mapping-param", params = "mode=debug")
public String mappingParam() {
logger.info("mappingParam");
return "ok";
}
"mode=debug"라고 되어있으면 mode라는 파라미터 이름에 debug라는 값이 담겨있어야되고
그렇지 않으면 오류가 발생한다. 주석을 보면 다양하게 조건을 넣을 수 있다.
요즘에는 잘 사용하지않는다.
특정 헤더조건 추가 매핑
URL 매핑 + 헤더조건 매핑
/**
* 특정 헤더로 추가 매핑
* headers="mode",
* headers="!mode"
* headers="mode=debug"
* headers="mode!=debug" (! = )
*/
@GetMapping(value = "/mapping-header", headers = "mode=debug")
public String mappingHeader() {
logger.info("mappingHeader");
return "ok";
}
매핑된 헤더를 넣지않고 url호출해보면
헤더가 매핑된대로 키를 mode 값을 debug로 헤더에 넣고 시도하면
주석은 헤더를 매핑하는 다양한 방법을 소개하고있다.
MediaType(미디어타입)조건 추가 매핑 - HTTP 요청 Content-Type, consumes
== Content-Type 헤더 기반 추가 매핑
/**
* Content-Type 헤더 기반 추가 매핑 Media Type
* consumes="application/json"
* consumes="!application/json"
* consumes="application/*"
* consumes="*\/*"
* MediaType.APPLICATION_JSON_VALUE
*/
@PostMapping(value = "/mapping-consume", consumes = "application/json")
public String mappingConsumes() {
logger.info("mappingConsumes");
return "ok";
}
consumes를 이용해서 매핑한다.
타입이 맞지않는다면 415 오류가 발생한다.
JSON으로 보내니 성공하는걸 볼 수 있다.
즉 , http요청할때 Content-Type에 대해 조건을 거는것이다 (consumes)
MediaType(미디어타입)조건 추가 매핑 - HTTP 요청 Accept, produce
Http 요청의 Accept헤더를 기반으로 매핑한다.
컨트롤러가 생산해내는 미디어타입이 클라이언트가 받을 수 있는 타입인지 확인해야한다.
Accept 헤더는 요청한 클라이언트가 받을 수 있는 Content-Type 을 의미한다.
produces에는 컨트롤러가 만들어서 반환하는 미디어타입을 적는다.
/**
* Accept 헤더 기반 Media Type
* produces = "text/html"
* produces = "!text/html" * produces = "text/*"
* produces = "*\/*"
*/
@PostMapping(value = "/mapping-produce", produces = "text/html")
public String mappingProduces() {
logger.info("mappingProduces");
return "ok";
}
produces가 text/html인 상태에서 url호출을 해보았다.
Accpet헤더가 모든 타입을 받는상태라 성공하였다. ( 모든 응답 타입을 받을 수 있다.)
클라이언트가 받을수있는 타입을 application/json으로 바꾸었다.
produces가 text/html이므로 컨트롤러는 text/html타입을 반환할텐데 , 클라이언트는 json형태만 받을 수 있으므로
406오류가 발생하였다.
즉 , produces는 http요청헤더의 Accept기반으로 매핑이 된다.
Content-Type을 문자열로 적지말고 변수를 사용하자.
@PostMapping(value = "/mapping-consume", consumes = "application/json")
@PostMapping(value = "/mapping-produce", produces = "test/html")
에서 Content-Type을 문자열로 적는거보다는
@PostMapping(value = "/mapping-consume", consumes = MediaType.APPLICATION_JSON_VALUE)
@PostMapping(value = "/mapping-produce", produces = MediaType.TEXT_HTML_VALUE)
org.springframework.http.MediaType안에 상수로 정해져있는 변수를 이용하는것이 더 좋다.
Produces 추가
@RequestMapping("/error-page/500")
public String errorPage500(HttpServletRequest request, HttpServletResponse response) {
log.info("errorPage 500");
printErrorInfo(request);
return "error-page/500";
}
@RequestMapping(value = "/error-page/500", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Map<String, Object>> errorPage500Api(
HttpServletRequest request,
HttpServletResponse response) {
log.info("API errorPage 500 ");
Map<String, Object> result = new HashMap<>();
Exception ex = (Exception) request.getAttribute(ERROR_EXCEPTION); // ERROR_EXCEPTION = "jakarta.servlet.error.exception";
//WAS 는 오류 페이지를 단순히 다시 요청(request)만 하는 것이 아니라, 오류 정보를 request 의 attribute 에 추가해서 넘겨준다.
//그 오류정보중 예외를 꺼내서 객체에 담았다.
result.put("status", request.getAttribute(ERROR_STATUS_CODE)); //오류정보중 상태코드를 꺼내서 Map에 넣어준다.
result.put("message", ex.getMessage());
//아래 코드는 상태코드를 받아오는 코드이다. 이 클래스 맨위에 상수로 지정해놓은값들이 RequestDispatcher안에 동일하게 들어있다.
// 나중에 사용할때는 이런식으로 가져오면 될듯하다.
Integer statusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
// Integer statusCheck = (Integer) request.getAttribute(ERROR_STATUS_CODE); <--- 결론적으로 이 코드와 같은코드이다.
return new ResponseEntity<>(result, HttpStatus.valueOf(statusCode));
}
이렇게 매핑url이 같은 2개의 메소드가 있다.
하나의 메소드는 매핑조건이 없는 일반 메소드이고
하나의 메소드는 매핑조건이 있는 메소드이다.
이럴때 http요청 헤더의 Accept가 */* (모든타입받음) 이면 매핑조건이 없는 일반 메소드가 실행되고
http요청 헤더의 Accept가 application/json 일때만 매핑조건이 있는 메소드가 실행된다.
조건매핑이 없는 메소드도 같이 존재할때는
produces매핑조건이 있는 메소드는 Accept가 해당 Content_Type일때만 동작한다.
그렇지않고 매핑조건이 있는 메소드만 있다면
application/json을 받을 수만있다면 그 메소드가 실행될것이다.
'인프런 > 스프링 MVC 1편' 카테고리의 다른 글
11)RequestParam 처리 방법 , HttpRequest 응답 방법 (0) | 2023.01.26 |
---|---|
10)HandlerMethodArgument,RequestParam 처리 방법들 (0) | 2023.01.25 |
8)스프링 MVC - 기본기능, 로깅(logging) (1) | 2023.01.19 |
7)스프링 MVC 시작하기(버전1 ~ 버전3) ,Http api와 Rest api의 차이 (0) | 2023.01.18 |
6)스프링 MVC (구조이해),핸들러 매핑과 핸들러 어댑터,뷰 리졸버 (0) | 2023.01.18 |
댓글