[Spring (3)] Http 요청 처리 1 - 작동 원리, 기본구조 (Day 49)

코딩기록·2024년 12월 16일

[ HTTP 요청 처리]

0. 복습 파일 경로

  • com.spring.mvcproject > chap02_3, chap02_5 > score

1. 작동 원리(vs Servlet)

  1. Spring Boot의 초기화
  • Spring application을 실행하면 자동으로 src>main>java에 내장되어 있는 파일이 실행되면서,
    SpringApplication.run() 코드 실행됨
    -> 이에 의해 @Controller가 붙은 클래스가 자동으로 스캔됨
    -> 이 클래스들이 WebApplicationContext(Spring에서 bean을 관리하고 초기화하는 인터페이스)
  • FYI. Servlet 사용 시 :
    i. WAS(Tomcat 등)는 어플리케이션 실행 시 @WebSerlet을 통해 서블릿 스캔 -> 서블릿 객체 생성하여 서블릿 컨테이너에 저장
  1. 클라이언트가 http 요청 보냄
  2. 웹서버에서 요청 수령
  3. 웹서버가 WAS에 동적 페이지에 대한 처리 요청
  4. WAS는 DispatcherServlet에 http 요청 전달 (dispatcher는 자동으로 생성됨)
    -- 일반 Servlet 사용 시 : Servlet 호출

  5. SpringApplication.run() 내부 구현 코드에 의해, DispatcherServlet은 WebApplicationContext를 사용하여 컨트롤러를 요청에 매핑
  6. Controller -> Service -> Repository -> DB 순으로 흐름
    -- 자세한 내용은 별도 post로 다룸
    https://velog.io/@kimmy25312/sdsdf

2. 기본 세팅

1. 클래스명 위에 @Controller 혹은 @RestController 붙이기

  • @RestController : 객체를 @ResponseBody를 합친 기능
  • FYI. @ResponseBody : Mapping되어 호출된 메서드가 반환하는 ResponseEntity 객체의 body를 JSON으로 spring 내부 메커니즘에 의해 바꿔줘라.

2. 한 클래스에서 여러 mapping 처리할 경우, 클래스 명 위에 공통 부분에 대하여 @RequestMapping("resource)

3. @MapMappin, @PutMapping, @GetMapping, @DeleteMapping으로 처리할 케이스 정해주고, 밑에 Mapping이 호출 될 메소드 적기

  • RequestMapping(구버전) : RequestMapping(value="/path", method=RequestMethod.Delete)

  • 메소드 리턴 타입 :
    1) 정적웹페이지로 이동할 경우 : String (String인 이유는 아래 참고)
    2) json으로 응답할 경우(@ResponseBody 붙였을때 ) : ResponseEntity
    // 사용자가 아래 path를 입력하면,
       @GetMapping("/score/page")
       // 1) Spring 내부 메커니즘에 의해, 클라이언트가 요청 보낸 path를 가진 @Mapping 어노테이션을 스캔하여,
       // 2) 그 밑에 있는 함수를 호출해줌
       // 3) 그 다음 단계로
       //    - @responsbody가 붙은 경우 : http 응답 본문을 반환
       //    - 안 붙은 경우 : 리턴된 jsp 파일을 뷰 리졸버를 통해 매핑에서 화면에 렌더링 되도록 함
       public String scorePage() { // String 으로 받는 이유: 받아서 Spring 내부 메커니즘에 의하여 jsp 파일로 이동
           return "score/score-page";
       }

4. Controller -> Service -> Repository 흐름

= 자세한 내용은 별도 포스팅
https://velog.io/@kimmy25312/sdsdf

- Repository



[ @RequestParam, @PathVariable, @RequestBody ]

1) 메서드 생성자로 HttpRequestServlet 가져온 후, getParameter로 스트링 값 가져오기

2) @RequestParam("/path") 데이터타입 변수명

/*
 [Spring에서 클라이언트의 http 요청 다루기]
 - 이 파일에서는 클라이언트의 http 요청을 DispatcherServlet을 통해 받은 후,
   DispatcherServlet이 각 요청을 컨트롤러에 매핑해줄 수 있도록
    1) @Controller를 사용하여 Spring Application 실행 시 @cONTROLLER가 붙은 클래스에 대해 객체가 자동생성될 수 있도록 하고
    2) @GetMapping, @RequestMapping을 통해 '경로가 /000 이면 여기에 있는 메소드를 호출해주세요'라고 하는 것에 대해 정리함
 */

// @Controller :
//    - Spring application 실행하면 자동으로 src>main>java에 내장되어 있는 파일이 실행되면서,
//      SpringApplication.run() 코드 실행됨
//      -> 이에 따라 @Controller가 붙은 클래스가 자동으로 스캔되고,
//         WebApplicationContext(Spring에서 bean을 관리하고 초기화하는 인터페이스)에 등록 되어 자동으로 생성됨
@Controller
public class ProductController_RequestParam {

    // 가상의 메모리 상품 저장소
    private Map<Long, Product> productStore = new HashMap<>();

    public ProductController_RequestParam() {
        productStore.put(1L, new Product(1L, "에어컨", 10000));
        productStore.put(2L, new Product(2L, "세탁기", 10500));
        productStore.put(3L, new Product(3L, "에어프라이어", 26000));
    }


    // 1. @GetMapping("/경로(path)/) : ()안에 있는 path에 대한 요청이 오면 이 메서드를 호출해 주세요.
    @GetMapping("/products")
    public String getProduct(
            /*
               2. 생성자로 ' @RequestParam("스트링쿼리 키 네임") 데이터타입 변수명 ' 전달

                 - 의미 : 요청 경로의 스트링 쿼리(경로?id=1 에서 id=1 부분)을 가져와 주세요.
                 - 아래 코드와 동일한 효력임
                     public getProduct(HttpRequestServlet req) {
                        데이터타입 변수명 = req.getParameter(스트링쿼리Key네임)
                     }
                  - Option
                    i. @RequestParam(value="String Query Key Name", required=false, defaultValue="3")
                       - required=false면 값 안 넣어도 됨
                       - defaultValue = required=false일 때 입력안 할 시 이 값으로 자동으로 넣어줌
                    ii. String Query Key Value 값을  Key Name 과 동일한 이름으로 변수명을 받을 경우,
                        @RequestParam("keyname") 부분은 생략 가능
               */
           Long id,
           @RequestParam(required = false, defaultValue = "1000") int price // int 하면 오류 발생 방지

    ) {
        System.out.println("id = " + id);
        System.out.println("price = " + price);
        return "hello";
    }

}

3) @PathVariable("/path/{path variable}") 데이터타입 변수명

/*
 [Spring에서 클라이언트의 http 요청 다루기]
 - 이 파일에서는 클라이언트의 http 요청을 DispatcherServlet을 통해 받은 후,
   DispatcherServlet이 각 요청을 컨트롤러에 매핑해줄 수 있도록
    1) @Controller를 사용하여 Spring Application 실행 시 @cONTROLLER가 붙은 클래스에 대해 객체가 자동생성될 수 있도록 하고
    2) @GetMapping, @RequestMapping을 통해 '경로가 /000 이면 여기에 있는 메소드를 호출해주세요'라고 하는 것에 대해 정리함
 */

// @Controller :
//    - Spring application 실행하면 자동으로 src>main>java에 내장되어 있는 파일이 실행되면서,
//      SpringApplication.run() 코드 실행됨
//      -> 이에 따라 @Controller가 붙은 클래스가 자동으로 스캔되고,
//         WebApplicationContext(Spring에서 bean을 관리하고 초기화하는 인터페이스)에 등록 되어 자동으로 생성됨
@Controller
public class ProductController_PathVariable {

    // 기본 세팅 : 가상의 메모리 상품 저장소
    private Map<Long, Product> productStore = new HashMap<>();

    // 기본 세팅
    public ProductController_PathVariable() {
        productStore.put(1L, new Product(1L, "에어컨", 10000));
        productStore.put(2L, new Product(2L, "세탁기", 10500));
        productStore.put(3L, new Product(3L, "에어프라이어", 26000));
    }

    // 1. @GetMapping("/경로(path)/{경로변수}) : ()안에 있는 path에 대한 요청이 오면 이 메서드를 호출해 주세요.
    @GetMapping("/products/{id}")
    // @ResponseBody : 메서드가 반환하는 값을 뷰(view)로 전달하지 말고, http 응답으로 바로 전달해주세요.
    //                  -> 개발자도구에서 network의 response에 보이고, 화면에도 렌더링 됨
    //                 @ResponseBody를 쓰지 않으면, Spring에서는 WebApp에서 retur에 있는 파일을 찾으러 감
    @ResponseBody
    public Product getProduct(
            /*
               @PathVariable("id") Long id
                 - 아래 코드와 동일한 효력(HttpRequestServlet을 생성자로 전달해 준 후, HttpRequestServlet에서 parameter값을 가져오는 것)

                 -   public getProduct(HttpRequestServlet req) {
                        String productId = extractPathVariable(request, "id");
                      }
             */
            @PathVariable("id") Long id // 변수명과 변수경로가 같을 경우 생략 가능(@PathVariable Long id)
             ) {
        System.out.println("id = " + id);
        Product product = productStore.get(id);
        return product;
    }



}

4) @RequestBody 객체 객체저장할변수명

- 객체가 생성되면서 객체의 필드값도 세팅됨

0개의 댓글