DispatcherServlet으로 전환

Sol's·2023년 5월 24일
0

서블릿 컨테이너(FrontController)를 직접 구현하면 URI 맵핑, 보안, 다국어, 바인딩 기능 을 개발자가 계속 처리해 주어야 합니다.
이것을 간편화 하기위해 스프링DispatcherServlet으로 전환해 보겠습니다.

DispatcherServlet으로 전환

이제 프론트컨트롤러 패턴을 직접 구현한게 아닌 Spring의 DispatcherServlet을 사용하고 있습니다.
DispatcherServlet이 작업을 위임할 applicationContext를 등록하여 사용한 것을 확인 할 수 있습니다.

public static void main(String[] args) {
        GenericWebApplicationContext applicationContext = new GenericWebApplicationContext(); // 스프링 컨테이너 생성
        applicationContext.registerBean(HelloController.class); // 메타정보를 넣어 Bean을 생성
        applicationContext.registerBean(SimpleHelloService.class);
        applicationContext.refresh(); // Bean을 만드는 명령어

        // 서블릿 펙토리 : 서블릿 컨테이너를 만드는 것을 쉽게 도와줍니다.
        ServletWebServerFactory serverFactory = new TomcatServletWebServerFactory();
        // serverFactory.getWebServer : 서블릿 컨테이너 생성하는 메소드입니다.
        // 따라서 webServer 가 서블릿 컨테이너 입니다.
        WebServer webServer = serverFactory.getWebServer(servletContext -> {
            servletContext.addServlet("dispatcherServlet",
                    new DispatcherServlet(applicationContext) // DispatcherServlet이 작업을 위임할 applicationContext를 등록
            ).addMapping("/*"); // 모든 요청을 다 받는다.
        });
        webServer.start();
    }

아직 중요한게 남아있습니다.
스프링 컨테이너가 갖고있는 오브젝트에게 위임을 요청해야하는데 어디로 요청해야하는지에 대한 요청정보가 없습니다.
즉, 서블릿 컨테이너 코드 대신 컨트롤러 클래스 안에 매핑정보를 넣어야 합니다.

어노테이션을 활용한 매핑정보 넣기

@RequestMapping
public class HelloController {

    // final은 처음 생성할때 꼭 필요하므로 생성자가 꼭! 있어야 합니다.
    private final HelloService helloService;

    public HelloController(HelloService helloService) {
        this.helloService = helloService;
    }

    @GetMapping("/hello")
    public String hello(String name){
        // 컨트롤러의 중요한 역할인 유저의 요청사항을 검증하기
        return helloService.sayHello(Objects.requireNonNull(name));
    }
}

우선 DispatcherServlet은 모든요청을 받고 그 후에 DispatcherServlet가URI를 확인하여 주입받은 applicationContextBean을 확인하고 일치하는 URI가 있는지 확인하고

servletContext.addServlet("dispatcherServlet",
                    new DispatcherServlet(applicationContext) // DispatcherServlet이 작업을 위임할 applicationContext를 등록
            ).addMapping("/*"); // 모든 요청을 다 받는다.

String 반환의 기본값

return타입이 String이라면 스프링은 기본적으로 dispatcherServlet은 view라는 html템플릿을 찾아 view를 리턴해라! 라고 인식합니다.
지금은 html 파일이 없기때문에 에러가 발생한 것입니다.

ResponseBody로 해결

@ResponseBody를 붙이면 웹응답의 Body에값에 그대로 들어가게 됩니다.
그렇기에 HttpMessageConverter가 내부적으로 Json으로 변환하여 전송합니다.

 @GetMapping("/hello")
    @ResponseBody
    public String hello(String name){
        // 컨트롤러의 중요한 역할인 유저의 요청사항을 검증하기
        return helloService.sayHello(Objects.requireNonNull(name));
    }

profile
배우고, 생각하고, 행동해라

0개의 댓글