Spring Wev MVC 강의 정리 (1)

패스트 캠퍼스 Spring Web MVC 강의 정리

애노테이션 기반 설계

  • 컨트롤러 클래스
    • MVC 패턴 중 핸들러 메소드를 포함하는 컨트롤러 빈 생성
    • @Controller
      • view 사용할 때 쓰는 애노테이션
      • 템플릿의 기본 경로는 src/main/webapp
      • JspTemplateAvailabilityProvider에서 확인 가능
      • thymeleaf를 사용하게 되면 src/main/resources/templates가 기본 경로
      • WelcomePageHandlerMapping에 정의되어 있어서 src/main/resources/static에 index.html 가 있으면 / url이 해당 html로 매핑됨
    • @RestController = @ResponseBody + @Controller
  • 핸들러 메소드
    • 스프링 웹 서비스가 받는 URI 요청을 컨트롤러의 특정 메소드에 매핑
    • @RequestMapping
    • @GetMapping
    • @PostMapping
    • @PutMapping
    • @DeleteMapping
    • @PatchMapping

함수 기반 설계

  • 함수형 프로그래밍
    • 자료 처리를 수학적 함수의 계산으로 취급
    • 상태와 가변 데이터를 멀리하는 프로그래밍 패러다임
  • 특징
    • 상태가 없음
    • 대입문이 없음
    • 부작용이 없는 순수 함수
    • 불변성
  • 함수형 엔드포인트
    • Spring Web의 엔드포인트를 함수형 스타일로 작성하는 방법 제공
    • WebMvc.fn
    • routing, request handling
    • 불변성 고려하여 설계
    • 기존 DispatcherServlet 위에서 동작
    • 애노테이션 스타일과 함께 사용 가능
    • HandlerFunction
      • 입력: ServerRequest
      • 출력: ServerResponse
      • 결과가 data
    • RouterFunction
      • 입력: ServerRequest
      • 출력: Optional<HandlerFunction>
      • 결과가 data + behavior(ex: url mapping)
@Configuration
public class APIPlaceRouter {

    @Bean
    public RouterFunction<ServerResponse> placeRouter() {
        return route().nest(path("/api/places"), builder -> builder
                        .GET("", req -> ServerResponse.ok().body(List.of("place1")))
                        .POST("", req -> ServerResponse.ok().body(true))
                        .GET("/{placeId}", req -> ServerResponse.ok().body("place" + req.pathVariable("placeId")))
                        .PUT("/{placeId}", req -> ServerResponse.ok().body(true))
                        .DELETE("/{placeId}", req -> ServerResponse.ok().body(true)))
                .build();
    }
}
// HandlerFuntion 만들어서 리팩토링
// APIPlaceHandler
@Component
public class APIPlaceHandler {

    public ServerResponse getPlaces(ServerRequest request) {
        return ok().body(List.of("place1"));
    }

    // TODO: URI 수정
    public ServerResponse createPlaces(ServerRequest request) {
        return created(URI.create("/api/places/1")).body(true);
    }

    public ServerResponse getPlace(ServerRequest request) {
        return ok().body("place" + request.pathVariable("placeId"));
    }

    public ServerResponse modifyPlace(ServerRequest request) {
        return ok().body(true);
    }

    public ServerResponse removePlaces(ServerRequest request) {
        return ok().body(true);
    }
}

// APIPlaceRouter
@Configuration
public class APIPlaceRouter {
  
  	// APIPlaceHandler가 주입됨
    @Bean
    public RouterFunction<ServerResponse> placeRouter(APIPlaceHandler apiPlaceHandler) {
        return route().nest(path("/api/places"), builder -> builder
                        .GET("", apiPlaceHandler::getPlaces)
                        .POST("", apiPlaceHandler::createPlaces)
                        .GET("/{placeId}", apiPlaceHandler::getPlace)
                        .PUT("/{placeId}", apiPlaceHandler::modifyPlace)
                        .DELETE("/{placeId}", apiPlaceHandler::removePlaces))
                .build();
    }
}

요청, 응답 설계

  • 핸들러 메소드
    • Spring Web에서 요청을 받아 응답을 반환하는 메서드
    • 매핑 정보, 요청, 응답값을 가짐
  • @RequestMapping 속성
    • name: 뷰 템플릿에서 식별할 때 쓰는 이름
    • value, path: URI
    • method: HTTP 메서드
    • params: 파라미터 검사
    • headers: 헤더 검사
    • consumes: 헤더의 Content-Type 검사
    • produces: 헤더의 Accept 검사
@RequestMapping(
	name = "GetPlaces",
  value = "/places",
  path = "/places",
  method = RequestMethod.GET,
  params = "test=true",
  headers = "header-auth=authInfo",
  consumes = MediaType.APPLICATION_JSON_VALUE,
  produces = MediaType.APPLICATION_JSON_VALUE  
)
public List<String> getPlaces() {
  ...
}
  • @RequestMapping shortcuts
    • @GetMapping
    • @PostMapping
    • @PutMapping
    • @DeleteMapping
    • @PatchMapping
  • 핸들러 메소드가 받을 수 있는 요청
    • @RequestParam, @PathVariable
      • @RequestParam 없이 사용해도 같은 동작
      • 있으면 required=true 기본 옵션, 없으면 required=false로 적용됨
    • @ModelAttribute, @SessionAttribute, Model, ModelMap
    • @RequestHeader, @CookieValue
    • ServletRequest, Servletresponse, HttpSession
    • WebRequest, NativeWebRequest
    • Principal, Locale, TimeZone, InputStream, OutputStream, Reader, Writer
  • 핸들러 메소드가 보낼 수 있는 응답
    • @ResponseBody
    • HttpEntity<B>, ResponseEntity<B>
    • String, View
    • ModelAndView
    • @ModelAttribute, Map, Model
    • HttpHeaders
    • void