프로그래밍/java, spring

서블릿방식과 spring MVC 컨트롤러의 json처리 비교

브래드 킴 2022. 12. 26. 10:44
728x90

서블릿의 HttpServletRequest, HttpServletResponse을 사용하는 방식과 spring MVC 컨트롤러 어노테이션을 활용하는 방법을 비교하여, json을 각각 어떻게 처리하는지 비교해보겠다.

 

 

json을 post로 request들어온 것을 받아 처리하는 방식과, json을 get요청한 것을 response 주는 방식으로 비교해보도록 하겠다. Hello라는 클래스 객체에 name, age가 있고, getter, setter가 있다는 것을 가정하겠다.

 

참고로, 서블릿 방법은 온전한 서블릿방식이 아니라, 스프링의 도움도 살짝 받았다는 것을 참고하길 바란다. 서블릿은 InputStream을 어떻게 사용하는지, 그리고 Jackson라이브러리로 json에서 어떻게 자바의 객체로 변환시키는지 위주로 보면 될것 같다. 그리고 스프링은 이러한 절차를 어떻게 간소화 시키는지 위주로 보면 될것같다.

 

서블릿 Request방식

@WebServlet(name = "helloApiRequest", urlPatterns = "/hello-api-request")
public class HelloApiRequest extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        ServletInputStream inputStream = req.getInputStream();
        String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
        Hello hello = objectMapper.readValue(messageBody, Hello.class);
        System.out.println(hello.getName());
        System.out.println(hello.getAge());
        resp.getWriter().write("ok");
    }
}

1)서블릿이 만들어준 req객체와 resp객체를 주입받는다.

2)req객체 담겨있는 값을 서블릿의 getInputStream메서드를 통해 Stream형태로 꺼낸다

3)스프링의 copyToString메서드를 통해 stream을 utf-8의 문자형식으로 인코딩한다.

4)jackson라이브러리의 ObjecdtMapper를 사용하여 읽어드린다음, 해당 메시지를 Hello클래스에 매핑시켜 자바객체로 꺼낸다.

 

*참고 : 만약 위와같은 json형식의 post가 아니고, html form형식의 post라면 getParameterNames를 통해 꺼내 Iterator시켜 꺼내면 된다. 단순한 get요청의 쿼리스트링이라면 getParameter로 request에서 원하는 값을 꺼내면 된다.

 

스프링 MVC reqeust방식

@Controller
public class HelloController {
    @PostMapping("hello-api-request")
    @ResponseBody
    public String helloApi(@RequestBody Hello hello){
        System.out.println(hello.getName());
        System.out.println(hello.getAge());
        return "ok";
    }
}

1)Controller + ResponsBody 어노테이션을 사용해도 되고 RestController을 사용해도 된다. 이를 통해 http request, response 처리가 가능하다. 즉, http 프로토콜을 통해 들어온 요청을 처리하고, 응답을 줄 수 있게 되는데 이는 서블릿이 해주던 req, resp 주입을 간편하게 대체한다. 또한 객체변환의 과정도 스프링이 간편하게 대체해주므로 위와 같이 사용하면 된다.

 

*참고 : 만약 위와같은 json형식의 post가 아니고, html form형식의 post라면 동일하게 객체로 받아 처리하면 된다. 만일 단순한 get요청의 쿼리스트링이라면 @RequestParam(value="name", required=false) String name 이런식으로 RequestParam을 통해 request에서 원하는 값을 꺼내면 된다.

 

서블릿 response방식

@WebServlet(name = "helloApiResponse", urlPatterns = "/hello-api-response")
public class HelloApiResponse extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("application/json");
        resp.setCharacterEncoding("utf-8");

        Hello hello = new Hello();
        hello.setName("kim");
        hello.setAge(30);
        String result = objectMapper.writeValueAsString(hello);
        resp.getWriter().write(result);
    }
}

1)response에 ContentType과 캐릭터셋을 세팅해준다.

2)객체를 만들어, ObjectMapper를 통해 String타입으로 변환하여 return한다.

 

참고)json이 아니고 일반 text라면 타입만 text/plain로 바꿔주면 된다. 만일 html을 return하여 렌더링시키고 싶다면, text/html이다.

 

스프링 MVC response방식

@Controller
public class HelloController {
    @GetMapping("hello-api-response")
    @ResponseBody
    public Hello helloApi(){
        Hello hello = new Hello();
        hello.setName("kim");
        hello.setAge(30);
        return hello;
    }
}

객체를 만들어 return만 해주면 객체에서 json의 String타입으로 알아서 변환되어 간편히 return된다.

 

참고)json이 아니고 일반 text/plain으로 리턴하고 싶다면, 그냥 return타입을 String으로 하면 된다. 만일 html을 return하여 렌더링시키고 싶다면, Model을 객체를 주입받아, 화면을 return하여 화면에 model attribute를 전달하는 방식이 편리할 것 같다. 타임리프 등을 활용하면 될듯싶다.

728x90