Spring Wev MVC 강의 정리 (1)
15 Aug 2022패스트 캠퍼스 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
- @RequestParam, @PathVariable
- 핸들러 메소드가 보낼 수 있는 응답
- @ResponseBody
- HttpEntity<B>, ResponseEntity<B>
- String, View
- ModelAndView
- @ModelAttribute, Map, Model
- HttpHeaders
- void