[스프링 인 액션] 2장 Spring MVC : 웹 애플리케이션 개발하기

    2장 웹 애플리케이션 개발하기

    💻 실습 : https://github.com/cusbert/spring-in-action-5th

    🎯 이 장에서 배우는 내용

    • 모델 데이터를 브라우저에 보여주기
    • 폼 입력 처리하고 검사하기
    • 뷰 템플릿 라이브러리 선택하기

    2.1 정보 보여주기

    스프링 MVC 요청 흐름

    • 도메인 클래스 : 타코 식자재의 속성을 정의
    • 컨트롤러 클래스 : 식자재 정보를 가져와 뷰에 전달
    • 뷰 템플릿 : 식자재 내역을 브라우저에 노출

    2.1.1 도메인 설정하기

    Lombok 를 사용하여 코드량을 줄일 수 있다
    Lombok 주요 기능

    • @NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor
      Constructors made to order:
    • @NoArgsConstructor
      Generates constructors that take no arguments
    • @RequiredArgsConstructor
      one argument per final
    • @AllArgsConstructor
      non-nullfield, or one argument for every field
    • @Data
      @ToString, @EqualsAndHashCode, @Getter on all fields, and @Setter on all non-final fields, and @RequiredArgsConstructor!!
    • @Getter/@Setter
      Never write public int getFoo() {return foo;} again.
    • @ToString
      No need to start a debugger to see your fields: Just let lombok generate a toString for you!

    @Data, @ToString, @Setter 등의 기능은 성능 또는 객체 안정성 이슈로 인해 주의하여 사용해야한다.

    2.1.2 컨트롤러 생성하기

    @Slf4j
    @Controller
    @RequestMapping("/orders")
    public class OrderController {
    
        @GetMapping("/current")
        public String orderForm(Model model) {
            model.addAttribute("order", new Order());
            return "orderForm";
        }
    
        @PostMapping
        public String processOrder(@Valid Order order, Errors errors) {
            if (errors.hasErrors()) {
                return "orderForm";
            }
            log.info("Order submitted : " + order);
            return "redirect:/designs";
        }
    }
    • @Controller
      스프링이 해당 클래스를 찾은 후 컨텍스트의 bean 으로 이 클래스의 인스턴스를 자동 생성되게 한다
    • @Slf4j
      Slf4j Logger 생성한다. 아래랑 같은 효과다
    private static final org.slf4j.Logger log =
        org.slf4j.LoggerFactory.getLogger(DesignTacoController.class);

    스프링 MVC 요청-대응 어노테이션

    어노테이션 설명
    @RequestMapping 다목적 요청 처리
    @GetMapping HTTP GET 요청 처리
    @PostMapping HTTP POST 요청 처리
    @PutMapping HTTP PUT 요청 처리
    @DeleteMapping HTTP DELETE 요청 처리
    @PatchMapping HTTP PATCH 요청 처리
    • 요청-대응 어노테이션 선언 시 가급적 특화된 것을 사용하자
    • @RequestMapping 은 기본 경로 지정하기 위해 클래스 수준에서 사용하자
    • 실제 요청 처리 메소드에선 @GetMapping, @PostMapping 사용하자
    • Model은 Controller 와 데이터를 보여주는 뷰 사이에서 데이터를 운반하는 객체이다
    • 궁극적으로 Model 객체 속성에 있는 데이터는 뷰가 알수 있는 서블릿 요청 속성들로 복사된다

    2.1.3 뷰 디자인 하기

    • 스프링은 JSP, Thymeleaf, FreeMarker, Mustache, Groovy 기반 템플릿 등을 제공하여 뷰를 정의한다.

    2.2 폼 제출 처리

        @PostMapping
        public String processDesign(@Valid Taco design, Errors errors) {
            if (errors.hasErrors()) {
                return "design";
            }
            // 타코 디자인(선택된 식자재 내역)을 저장한다…
            log.info("### Processing design: " + design);
            return "redirect:/orders/current"; // 현재 주문 페이지 orders/current 로 리다이렉트
        }

    2.3 유효성 검사하기

    • if-else 로 지저분하게 체크 하지 말고 Bean Validation API 쓰자
    • spring boot 2.3 이상 부터는 spring-boot-starter-validation 라이브러리 추가 필요하다
    <dependency> 
        <groupId>org.springframework.boot</groupId> 
        <artifactId>spring-boot-starter-validation</artifactId> 
    </dependency>

    2.3.1 유효성 검사 규칙 선언하기

    @Entity
    public class User {
    
        @NotBlank(message = "Name is mandatory")
        private String name;
        @NotBlank(message = "Email is mandatory")
        private String email;
        @CreditCardNumber(message = "Not a valid credit card number")
        private String ccNumber;
        @Pattern(regexp = "^0[1-9]|1[0-2]([\\/])([1-9][0-9])$", message = "Must be formatted MM/YY")
        private String ccExpiration;
        @Digits(integer = 3, fraction = 0, message = "Invalid CVV") // integer: 자릿수, fraction: 소수점자리수
        private String ccCVV;
    }

    @NotNull, @NotEmpty, @NotBlank 차이점

    1. String test = null;
    @NotNull: false
    @NotEmpty: false
    @NotBlank: false
    
    2. String test = "";
    @NotNull: true
    @NotEmpty: false
    @NotBlank: false
    
    3. String test = " ";
    @NotNull: true
    @NotEmpty: true
    @NotBlank: false
    
    4. String name = "Some text";
    @NotNull: true
    @NotEmpty: true
    @NotBlank: true

    2.3.2 폼과 바인딜 될 때 유효성 검사 수행하기

    스프링 MVC 예제

    • @Valid 는 Taco 객체가 바인딩 된 후 processDesign() 메서드 실행 전에 유효성 검사를 하라고 스프링 MVC 에게 전달한다
    • 만약 에러가 있으면 Errors 객체에 에러 상세내역이 저장되어 processDesign() 메서드에 전달된다
    @PostMapping
    public String processDesign(@Valid Taco design, Errors errors) {
        if (errors.hasErrors()) {
            return "design";
    
    
        return "redirect:/orders/current";
    }

    RestController 예제

    @RestController
    public class UserController {
        @PostMapping("/users")
        ResponseEntity<String> addUser(@Valid @RequestBody User user) {
            // persisting the user
            return ResponseEntity.ok("User is valid");
        }
    }

    2.4 뷰 컨트롤러로 작업하기

    1. 일반적인 패턴
    • @Controller 를 붙여줌
      Spring component scan 에서 자동으로 찾은 후 컨텍스트의 bean 으로 생성되는 컨트롤러 클래스임을 알려주기 위함
    • @RequestMapping
      컨트롤러는 자신이 처리하는 요청 패턴을 알려줌
    • @GetMapping, @PostMapping
      요런걸 쓰면 어떤 종류의 요청을 처리해야 되는지 알려 줄 수 있음
    1. WebMvcConfigurer 를 통해 간단하게 처리도 가능하다
    • WebMvcConfigurer 인터페이스의 addViewControllers() 오버라이딩해서 사용한다
    • WebMvcConfigurer 인터페이스는 스프링 MVC를 구성하는 메서드를 정의하고 있다
    • addViewControllers() 는 하나 이상의 뷰 컨트롤러를 등록하기 위해 사용할 수 있는 ViewControllerRegistry를 인자로 받는다
    • 개발자가 커스터마이징 해서 쓸 수있다
    • 자세한 내용은 Spring MVC Tutorial
    @Configuration
    class WebConfig implements WebMvcConfigurer {
    
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            // WebMvcConfigurer 로 "/" 경로 요청 시 view 지정
            registry.addViewController("/").setViewName("home");
        }
    }

    📌 요약

    • 스프링 MVC 는 스프링 애플리케이션의 웹 프론트엔드 개발에 사용한다
    • 스프링 MVC 는 애노테이션을 기반으로 한다
    • @RequestMapping, @GetMapping, @PostMapping 등을 사용하여 요청 처리 메소드를 선언 할 수있다
    • 대부분의 요청 처리 메서드는 마지막에 Thymeleaf 템플릿과 같은 논리 뷰 이름을 반환한다
    • 스프링 MVC 는 자바 빈 유효성 검사 API와 Hibernate Validator 등의 유효성 검사 API 구현 컴포넌트를 통해 유효성 검사를 지원한다
    • 모델 데이터가 없거나 처리할 수 필요가 없는 HTTP GET 요청을 처리할 때는 뷰 컨트롤러를 사용할 수 없다
    • Thymeleaf에 추가하여 스프링은 다양햔 뷰 템플릿(FreeMarker, Groovy Template, Mustache 등 ) 을 지원한다

    참고

    반응형

    댓글

    Designed by JB FACTORY