본문 바로가기
Backend/Spring | SpringBoot

[SpringBoot] 스프링 MVC 기본 애노테이션(@Controller, @RequestMapping, @PathVariable)

by 2245 2023. 8. 25.

목차

     

    @Controller

    @Controller     //컴포넌트 스캔을 통해 스프링 빈으로 등록
    public class SpringMemberFormControllerV1 {
        
        @RequestMapping("/springmvc/v1/members/new-form")
        public ModelAndView process() {
            return new ModelAndView("new-form");
        }
    }
    • @Controller
      • 스프링이 자동으로 스프링 빈으로 등록합니다. (내부에 @Component 애노테이션이 있어서 컴포넌트 스캔 대상이 됩니다.)
      • 스프링 MVC에서 애노테이션 기반 컨트롤러로 인식됩니다. 
    • @RequestMapping 
      • 해당 URL이 호출되면, 이 메서드가 호출됩니다. 
      • 다중 설정이 가능합니다. {"/hello-basic", "/hello-go"}
    • ModelAndView 
      • 모델과 뷰 정보를 담아 반환합니다. 
    • HandlerMapping ⇒  RequestMappingHandlerMapping 사용, @Controller가 붙은 컨트롤러를 인식합니다. 
    • HandlerAdapter ⇒ RequestMappingHandlerAdapter 사용, @Controller가 붙은 컨트롤러 어댑터를 인식합니다. 
    참고 mv.addObject("member", member)
    -
    스프링이 제공하는 ModelAndView를 통해 Model 데이터를 추가할 때는 addObject()를 사용하면 됩니다.
    -
    이 데이터는 이후 뷰를 렌더링할 때 사용됩니다. 
    @Controller
    public class SpringMemberSaveControllerV1 {
    
        private MemberRepository memberRepository = MemberRepository.getInstance();
    
        @RequestMapping("/springmvc/v1/members/save")
        public ModelAndView process(HttpServletRequest request, HttpServletResponse response) {
            String username = request.getParameter("username");
            int age = Integer.parseInt(request.getParameter("age"));
    
            Member member = new Member(username, age);
            memberRepository.save(member);
    
            ModelAndView mv = new ModelAndView("save-result");
            mv.addObject("member", member);
            return mv;
        }
    }​

     

     

    @RequestMapping

    클래스 레벨 @RequestMapping

    클래스 레벨의 RequestMapping의 URL과 메서드 레벨의 RequestMapping의 URL을 합친 URL로 호출이 됩니다. 

    /**
     * @RequestMapping 클래스 레벨과 메서드 레벨 조합
     * 클래스 단위 -> 메서드 단위
     */
    
    @Controller
    @RequestMapping("/springmvc/v2/members")
    public class SpringMemberControllerV2 {
    
        @RequestMapping("/new-form")
        public ModelAndView newForm() {
            ...
        }
    
        @RequestMapping("/save")
        public ModelAndView save(HttpServletRequest request, HttpServletResponse response) {
            ...
        }
    
        @RequestMapping
        public ModelAndView members() {
            ...
        }
    }

     

    @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping

    @RequestMapping(method = RequestMethod.GET)을 @GetMapping으로 축약하여 사용할 수 있습니다. 

    @RequestMapping(value = "/mapping-get-v1", method = RequestMethod.GET)
    public String mappingGetV1() {
        log.info("mappingGetV1");
        return "ok";
    }
    /**
     * 편리한 축약 애노테이션 
     * @GetMapping
     * @PostMapping
     * @PutMapping
     * @DeleteMapping
     * @PatchMapping
     */
    @GetMapping(value = "/mapping-get-v2")
    public String mappingGetV2() {
        log.info("mapping-get-v2");
        return "ok";
    }

     

    @*Mapping (params="") : 특정 파라미터 조건 매핑

    요청 URL이 특정 파라미터를 포함하는지, 아닌지 조건을 추가할 수 있습니다.

    (잘 사용하지는 않습니다.)

    //파라미터에 "mode=debug"가 있어야 호출이 된다. 
    @GetMapping(value = "/mapping-param", params = "mode=debug")  
    public String mappingParam() {
        log.info("mappingParam");
        return "ok";
    }
    
    /**
     * 파라미터 추가 매핑
     * params="mode"
     * params="!mode"
     * params="mode=debug"
     * params="mode!=debug" (!=)
     * params={"mode=debug","data=good"}
     */

     

    @*Mapping(headers="") : 특정 헤더 조건 매핑

    헤더에 해당 조건이 있어야 매핑됩니다. 

    //헤더에 mode=debug가 있어야 호출이 된다.
    @GetMapping(value = "/mapping-header", headers="mode=debug")
    public String mappingHeader() {
        log.info("mappingHeader");
        return "ok";
    }
    
    /**
     * 특정 헤더로 추가 매핑
     * headers="mode"
     * headers="!mode"  //mode라는 헤더가 없을 때 
     * headers="mode=debug"  //mode 헤더의 값이 debug일때
     * headers="mode!=debug"
     */

    Postman으로 테스트

     

     

    @*Mapping(consumes="") : 미디어 타입 조건 매핑 (Content-type)

    • HTTP 요청의 Content-type 헤더를 기반으로 미디어 타입을 매핑합니다.
    • HTTP 요청 데이터의 타입이 같을 경우에만 매핑됩니다.
    • 만약, 맞지 않으면 415 상태코드 (Unsupported Media Type)을 반환합니다. 
    //요청의 Content-type이 application/json이어야 호출이 된다.
    @PostMapping(value = "/mapping-consume", consumes = "application/json")
    public String mappingConsumes() {
        log.info("mappingConsumes");
        return "ok";
    }
    
    /**
     * Content-Type 헤더 기반 추가 매핑 Media Type
     * consumes="application/json"
     * consumes="!application/json"
     * consumes="application/*"
     * consumes="*\/*"
     * consumes=MediaType.APPLICATION_JSON_VALUE
     */
    /**
     * consumes="text/plain"
     * consumes={"text/plain", "application/*"}
     * consumes=MediaType.TEXT_PLAIN_VALUE
     */

     

    @*Mapping(produces="") : 미디어 타입 조건 매핑 (Accept)

    • HTTP 요청의 Accept 헤더를 기반으로 미디어 타입을 매핑합니다.
    • 반환 값이 일치할 경우에만 매핑됩니다.
    • 만약, 맞지 않으면 HTTP 406 상태코드(Not Acceptable을 반환합니다.
    //요청의 Accept 헤더가 text/html이어야 호출이 된다.
    @PostMapping(value = "/mapping-produce", produces = "text/html")
    public String mappingProduces() {
        log.info("mappingProduces");
        return "ok";
    }
    
    /**
     * Accept 헤더 기반 Mdedia Type
     * produces = "text/html"
     * produces = "!text/html"
     * produces = "text/*"
     * produces = "*\/*"
     */
    /**
     * produces = "text/plain"
     * produces = {"text/plain", "application/*"}
     * produces = MediaType.TEXT_PLAIN_VALUE
     * produces = "text/plain;charset=UTF-8"
    */

     

     

    @PathVariable

    최근 HTTP API는 리소스 경로에 식별자를 넣는 스타일을 선호합니다.

    • ex) /mapping/userA
    • ex) /users/1

     

    @RequestMapping은 URL 경로를 템플릿화할 수 있는데, @PathVariable을 사용하면 매칭되는 부분을 템플릿으로 사용하여 중복을 제거할 수 있습니다.

    @GetMapping("/mapping/{userId}")
    public String mappingPath(@PathVariable("userId") String data) { //변수명이 같으면 ("userId") 생략 가능 (@PathVariable String userId)
        log.info("mappingPath userId={}", data);
        return "ok";
    }

     

     

    /**
     * PathVariable 사용 다중
     */
    @GetMapping("/mapping/users/{userId}/orders/{orderId}")
    public String mappingPath(@PathVariable String userId, @PathVariable Long orderId) {
        log.info("mappingPath userId={}, orderId={}", userId, orderId);
        return "ok";
    }

     

     


    출처

    https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard

     

    스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

    웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., 원

    www.inflearn.com