[F-Lab] 모각코 챌린지 7일차

tree·2023년 5월 7일
0

요청 매핑

  • @RestController

    • @Controller 는 반환 값이 String 이면 뷰 이름으로 인식. 뷰를 찾고 뷰가 랜더링.
    • @RestController 는 반환 값으로 뷰를 찾지 않고, HTTP 메시지 바디에 바로 입력.
    • @ResponseBody 와 관련있다.
  • @RequestMapping("/hello-basic")

    • /hello-basic URL 호출이 오면 이 메서드가 실행되도록 매핑.
    • 다중 설정이 가능. {"/hello-basic", "/hello-go"}
  • URL 구분

    • 스프링 부트 3.0 이전
      • /hello-basic/hello-basic/은 같은 url로 간주.
    • 스프링 부트 3.0 이후
      • /hello-basic/hello-basic/은 별도의 url로 간주.
  • HTTP 메서드

    • @RequestMapping(value = "/mapping-get-v1", method = RequestMethod.GET)
      • 여기에 POST 요청을 하면 스프링 MVC는 HTTP 405 상태코드(Method Not Allowed)를 반환.
    • HTTP 메서드 매핑 축약
      • @GetMapping
      • @PostMapping
      • @PutMapping
      • @DeleteMapping
      • @PatchMapping
  • PathVariable(경로 변수) 사용

    @GetMapping("/mapping/{userId}")
    public String mappingPath(@PathVariable("userId") String data) {
      ...
    }
    • 변수명이 같으면 생략 가능
      • @PathVariable("userId") String userId -> @PathVariable userId
  • 특정 파라미터 조건 매핑

    /**
    * 파라미터로 추가 매핑
    * 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() {
      log.info("mappingParam");
      return "ok";
    }
    • http://localhost:8080/mapping-param?mode=debug로 GET 요청시 위의 메소드가 호출
    • 해당 기능을 잘 사용하지는 않는다.
  • 특정 헤더 조건 매핑

    /**
    * 특정 헤더로 추가 매핑
    * headers="mode",
    * headers="!mode"
    * headers="mode=debug"
    * headers="mode!=debug" (! = )
    */
    @GetMapping(value = "/mapping-header", headers = "mode=debug")
    public String mappingHeader() {
      log.info("mappingHeader");
      return "ok";
    }
    • 파라미터 매핑과 비슷하지만, HTTP 헤더를 사용.
  • 미디어 타입 조건 매핑 - HTTP 요청 Content-Type, consume

    /**
    * 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() {
      log.info("mappingConsumes");
      return "ok";
    }
    • HTTP 요청의 Content-Type 헤더를 기반으로 미디어 타입으로 매핑.
    • 만약 맞지 않으면 HTTP 415 상태코드(Unsupported Media Type)을 반환.
  • 미디어 타입 조건 매핑 - HTTP 요청 Accept, produce

    /**
    * Accept 헤더 기반 Media Type
    * produces = "text/html"
    * produces = "!text/html"
    * produces = "text/*"
    * produces = "*\/*"
    */
    @PostMapping(value = "/mapping-produce", produces = "text/html")
    public String mappingProduces() {
      log.info("mappingProduces");
      return "ok";
    }
    • HTTP 요청의 Accept 헤더를 기반으로 미디어 타입으로 매핑.
    • 만약 맞지 않으면 HTTP 406 상태코드(Not Acceptable)을 반환.

    HTTP 요청 - 기본, 헤더 조회

    @Slf4j
    @RestController
    public class RequestHeaderController {
      @RequestMapping("/headers")
      public String headers(HttpServletRequest request,
                            HttpServletResponse response,
                            HttpMethod httpMethod,
                            Locale locale,
                            @RequestHeader MultiValueMap<String, String> headerMap,
                            @RequestHeader("host") String host,
                            @CookieValue(value = "myCookie", required = false) String cookie
                            ) {
        return "ok";
    }
  • 위와 같이 HttpServletRequest, HttpServletResponse 뿐만 아니라 다양한 정보를 메소드 파라미터로 받을 수 있다.

HTTP 요청 파라미터 - @RequestParam

  • 서블릿을 사용할 때는 GET 요청의 쿼리 파라미터, POST 요청의 메시지 바디의 내용을 조회하기 위해 HttpServletRequest의 getParameter()를 사용했었다.

  • 스프링에서는 더 간편하게 해당 데이터를 조회할 수 있다.

    /**
    * @RequestParam 사용
    * - 파라미터 이름으로 바인딩
    * @ResponseBody 추가
    * - View 조회를 무시하고, HTTP message body에 직접 해당 내용 입력
    */
    @ResponseBody
    @RequestMapping("/request-param-v2")
    public String requestParamV2(
                            @RequestParam("username") String memberName,
                            @RequestParam("age") int memberAge) {
    }
  • 어노테이션 생략

    /**
    * @RequestParam 사용
    * String, int 등의 단순 타입이면 @RequestParam 도 생략 가능
    */
    @ResponseBody
    @RequestMapping("/request-param-v4")
    public String requestParamV4(String username, int age) {
    }
    • String , int , Integer 등의 단순 타입이면 @RequestParam 도 생략 가능
    • @RequestParam 애노테이션을 생략하면 스프링 MVC는 내부에서 required=false 를 적용
  • 파라미터 필수 여부

    /**
    * @RequestParam.required
    * /request-param-required -> username이 없으므로 400 예외
    *
    * 주의!
    * /request-param-required?username= -> 빈문자로 통과
    *
    * 주의!
    * /request-param-required
    * int age -> null을 int에 입력하는 것은 불가능(500 예외 발생), 따라서 Integer   변경해야 함(또는 다음에 나오는
    defaultValue 사용)
    */
    @ResponseBody
    @RequestMapping("/request-param-required")
    public String requestParamRequired(
                          @RequestParam(required = true) String username,
                          @RequestParam(required = false) Integer age) {
    }
  • 기본 값 적용

    /**
    * @RequestParam
    * - defaultValue 사용
    *
    * 참고: defaultValue는 빈 문자의 경우에도 적용
    * /request-param-default?username=
    */
    @ResponseBody
    @RequestMapping("/request-param-default")
    public String requestParamDefault(
                            @RequestParam(required = true, defaultValue =   "guest") String username,
                            @RequestParam(required = false, defaultValue =  "-1") int age) {
    }
    • 파라미터에 값이 없는 경우 defaultValue 를 사용하면 기본 값을 적용할 수 있다.
    • 이미 기본 값이 있기 때문에 required 는 의미가 없다.
  • 파라미터를 Map으로 조회하기

    /**
    * @RequestParam Map, MultiValueMap
    * Map(key=value)
    * MultiValueMap(key=[value1, value2, ...]) ex) (key=userIds, value=[id1,  id2])
    */
    @ResponseBody
    @RequestMapping("/request-param-map")
    public String requestParamMap(@RequestParam Map<String, Object> paramMap) {
    }
    • 파라미터의 값이 1개가 확실하다면 Map 을 사용해도 되지만, 그렇지 않다면 MultiValueMap 을 사용하자.

0개의 댓글