스프링 프레임워크는
평범한 POJO(Plain Old Java Object)를
사용하면서도 많은 일을
가능하도록 지원한다.
또한 많은 디자인 패턴이 적용되어 배포되므로
프레임워크를 사용하는 것 자체가
디자인 패턴을 사용하는 것이다.
POJO란?
POJO란 말 그대로 평범한 옛날 자바 객체를 의미한다.
POJO를 좀 더 쉽게 이해하기 위해서
반대로 Not POJO에 대해 알아보자.
대표적인 Not POJO 클래스는 Servlet 클래스이다.
Servlet 클래스는 우리 마음대로 만들 수 없으며,
반드시 Servlet에서 요구하는 규칙에 맞게 클래스를 만들어야 실행할 수 있다.
다음은 Servlet 클래스 작성 규칙이다.
1. javax.servlet, javax.servlet.http 패키지를 import해야 한다.
2. public 클래스로 선언되어야 한다.
3. Servlet, GenericServlet, HttpServlet 중 하나를 상속해야 한다.
4. 기본 생성자(Default Constructor)가 있어야 한다.
5. 생명주기에 해당하는 메소드를 재정의(Override)해야 한다.
@RestController
public class UserController {
@ResponseBody
@PostMapping("/user")
public User create(@RequestBody User user){
return new User();
}
위 상황에서 HttpMessageConverters가 사용된다.
HttpMessageConverters에는 여러 종류가 있다.
그 중 우리가 어떤 요청을 받았는지
또는 어떤 응답을 보내야하는지에 따라 사용하는 HttpMessageConverters가 달라진다.
예를 들어 JSON 요청이고 JSON 본문이 들어올 경우엔
JSONMessageConverts가 사용되어 JSON 메세지를 User라는 객체로 변환시켜준다.
그리고 Return 시에도
Http는 문자로 통신을 하기 때문에
User 객체 자체를 Response로 내보낼 순 없다.
그래서 User와 같은 Composition Type을
JSONMessageConverts를 사용하여 객체 -> 문자로 변환시켜 응답한다.
Composition Type 이란 그 안에 여러가지 프로퍼티를 갖을 수 있는 것을 뜻한다.
Resource 요청과 관련해선 ResourceHttpRequestHandler가 처리한다.
기본 Resource Path 이외의 추가적인 Resource Path를 관리하기 위해선
WebMvcConfigurer의 addResourceHandlers로 커스터마이징한다.
package com.example.demo.config;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configurable
/*
@EnableWebMvc // SpringBoot가 제공하는 모든 MVC기능은 사라지고 WebMVC 기능을 여기서 설정해줘야한다.
그런데 너무나 귀찮은 부분이기 때문에 @EnableWebMvc 선언을 하지 않고
"implements WebMvcConfigurer"를 통해 필요한 Method를 Override한다.
*/
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/m/**")
.addResourceLocations("classpath:/m/")
.setCachePeriod(20);
}
}
AcceptHeader에 따라 응답이 달라진다.
ex) accept(MediaType.APPLICATION_JSON_UTF8)
AcceptHeader는
“브라우저가 어떤한 타입의 본문을 응답을 원한다”를 서버한테 알려준다.
ContentNegotiatingViewResolver는
어떤 요청이 들어오면
그 요청에 응답을 만들 수 있는 모든 View를 찾는다.
그리고 최종적으로
그 AcceptHeader랑 비교해서 해당 View를 Return한다.