ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Servlet - request & response
    Spring/MVC1-서블릿(Servlet) 2023. 6. 7. 07:39
    728x90

     서블릿 간단 개요

    https://hongs429-blog.tistory.com/39
     

    서블릿(Servlet)

    우리가 흔히 알고 있듯이 HTML에서 Form 데이터의 전송이 서버로 일어나게 되면, 다음의 과정이 필요하다 1. Form 데이터 전송(POST) 2. 웹 브라우저가 생성한 요청 HTTP 메세지 이렇게 전달이 되면, 서

    hongs429-blog.tistory.com

    Servlet이란
    client와 서버와의 소통에서, 비지니스 로직에 대한 처리 코드를 제외한 모든 부분을 도와주는 것으로, 
    Client으로 부터 들어온 요청에 대한 처리(HttpServletRequest 담당)와
    이를 응답(HttpServletResponse 담당)을 개발자로 하여금 수많은 편의기능을 제공해주는
    역할을 수행한다고 생각하면 된다.

     

     

     

     Spring Boot에서 Servlet 객체 등록하기

    기본적으로 스프링부트에서 서블릿 객체를 활용하려면

    Container 생성시에 Servlet을 자동으로 등록하는 작업을 해야한다.

    스프링부트에서는 이를 @ServletComponentScan 이라는 어노테이션을 지원한다.

    @ServletComponentScan		// 서블릿 자동 등록
    				// 스프링이 자동으로 서블릿을 찾아서 등록한다.
    @SpringBootApplication
    public class ServletApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(ServletApplication.class, args);
    	}
    }

    @SpringBootApplication 안에 @ComponentScan 이 있는 것과 비슷한 원리이다.

     

     

     

     

    그렇다면, 무엇을 참고하여 찾을까?

    바로 @WebServlet 어노테이션으로 Servlet 객체를 찾는데,

    해당 어노테이션의 2가지 파라미터의 기능은,

    name : 서블릿이름
    urlPatterns : url 매핑

    을 담당한다.

    // 싱글톤!
    @WebServlet(name = "helloServlet", urlPatterns = "/hello")  // url= /hello 가들어오면 실행되는 클래스
    public class HelloServlet extends HttpServlet {
    
        @Override                        
        protected void service(
        HttpServletRequest request,   	 // client에서 전달받은 request
        HttpServletResponse response  	//  client에게 내려주기 위한 response
        ) throws ServletException, IOException {...}

     

     

     

     

    ● HttpServletRequest 의 역할

    위의 다양한 내용들 중

    • HTTP 메소드
    • URL
    • queryString
    • 헤더에 대한 조회
    • 바디에서는,
      form data 조회
      message body 데이터 조회

    등을 확인할 수 있으며,

     

    임시저장소의 기능으로, request가 들어와서 response되어 사라지기 전까지(Life Cycle) 저장하고 조회하는 기능을 수행하기도한다.

    • 저장 : request.setAttribute(name, value)
    • 조회 : request.getAttribute(name)

     

    뿐만 아니라, 세션 관리 기능 까지 가지고 있다.

     

     

    ● HttpServletResponse 의 역할

    reponse 객체가 해주는 역할로는,

    • HTTP 응답코드 지정
    • 헤더 생성
    • 바디 생성

    등이 있으며, 편의기능으로는

    • Content-Type 지정
    • 쿠키
    • Redirect

    가 있다.

     

     

     

     

    우리는 이런 HttpServletRequest 객체와 HttpServletResponse 객체가

    어떠한 방식으로 HTTP의 데이터를 주고 받는지를 알 필요가 있다.

     

    HTTP 요청 데이터

    1. GET - Query String

    url/?name=value 형식

    이는 요청 바디가 없이, URL에 단순히 데이터를 포함해서 전달하는 방식이다.

    대개 검색, 필터, 페이징 기능에서 사용하는 방식이다.

     

    2. POST - HTML Form

    우리가 흔히 알고 있는 form 태그의 내용
    request header의 내용 중

    이는 사실 위의 쿼리스트링 방식을 단순히 요청 바디에 담아서 전달하는 것과 동일하다.

    대신 url에 직접적으로 정보가 노출이 되지 않기 때문에

    대개 회원가입, 주문 과 같이 데이터를 저장하거나 수정하는 일에 사용된다.

     

     <GET - Query String> , <POST - HTML Form> 방식 모두 기본적으로 파싱하는 과정이 비슷하기 때문에,
    request.getParameter(). request.getParameterValues()
     등의 메소드를 사용해서 값을 받아낸다.

     

     

    3. HTTP message body에 데이터를 직접 담아서 요청 ( API 방식)

    최근에는 해당 방식을 주로 json(javaScript Object Notation)의 형식을 채택하여 쓴다.

    이는 단순히 그냥 String 값이다.

    스프링부트는 기본적으로 Jackson 라이브러리가 이를 자바 객체로 파싱을 자동으로 해주지만,

    Servlet에서는 우리가 직접 파싱을 해주어야 한다. 이때 사용되는 것이 ObjectMapper 객체이다.

    @WebServlet(name = "requestBodyJsonServlet", urlPatterns = "/request-body-json")
    public class RequestBodyJsonServlet extends HttpServlet {
    
        // SpringBoot는 기본적으로 json을 자바언어로 파싱해주는 Jackson 라이브러리를 제공
        private ObjectMapper objectMapper = new ObjectMapper();
    
        @Override
        protected void service(
        	HttpServletRequest request,
        	HttpServletResponse response
        ) throws ServletException, IOException {
            ServletInputStream inputStream = request.getInputStream();
            String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
    
            System.out.println("messageBody = " + messageBody); // 단순 문자다
            HelloData helloData = objectMapper.readValue(messageBody, HelloData.class);
    
            System.out.println("helloData.username = " + helloData.getUsername());
            System.out.println("helloData.age = " + helloData.getAge());
        }
    }

     

     

     

     

     

    위의 HTTP 요청 데이터와 대응되게 HTTP 응답 데이터도 다음과 같이 데이터를 담아서 전달한다.

    HTTP 응답 데이터

    1. 단순 Text 응답

            PrintWriter writer = response.getWriter();
            writer.println(helloData);  // 객체를 보내면 toString 값이 나간다
            writer.println("안녕하세요");    // ContentLength : 3*5 + 2 (enter 포함)
            writer.print("안녕하세요");      // 15       utf-8 encoding - 한글3 영어1 공백2
            writer.print("ok");             // 2

    2. HTML 응답

    위에서 설명을 하진 않았지만, response 응답을 다르게 할 때는 response header에

    그에 맞는 Content-type이 필요하다. 또한 한글도 적용이 되려면 charset을 utf-8로 설정해주어야 한다.

    @WebServlet(name = "responseHtmlServlet", urlPatterns = "/response-html")
    public class ResponseHtmlServlet extends HttpServlet {
        @Override
        protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // content-type을 잡아줘야한다.
            // Content-Type: text/html;charset=utf-8
            response.setContentType("text/html");
            response.setCharacterEncoding("utf-8");
    
            PrintWriter writer = response.getWriter();
    
            writer.println("<html>");
            writer.println("<body>");
            writer.println("<div>안녕?</div>");
            writer.println("</body>");
            writer.println("</html>");
        }
     }

    소스보기 화면

     

    3. HTTP API - Message Body에 JSON 형식으로 응답하기

    여기에선 response header에

    Content-Type : application/json 을 해주어야 한다.

    또한, 기본적으로 요청헤더에서 ObjectMapper 객체를 통해 단순 문자열을 자바객체로 변환해준 것처럼,

    여기서는 자바객체를 단순 문자열로 바꿔주는 작업도 함께 하는 것이 일반적이다.

    @WebServlet(name = "responseJsonServlet", urlPatterns = "/response-json")
    public class ResponseJsonServlet extends HttpServlet {
    
        private ObjectMapper objectMapper = new ObjectMapper();
        
        @Override
        protected void service(
        HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
            // Content-type : application/json
    //        response.setHeader("Content-type", "application/json;charset=utf-8");
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
    
            HelloData helloData = new HelloData();
            helloData.setUsername("kim");
            helloData.setAge(30);
    
            // {"username":"kim", "age":20}
            // 이렇게 하려면 ObjectMapper 객체가 필요. SpringBoot에서는 Jackson이라는 라이브러리가 내장
            String result = objectMapper.writeValueAsString(helloData);
            response.getWriter().write(result);
        }
    }

     

    이상으로 Servlet을 통해

    client 와 서버가 어떻게 데이터를 주고 받는지에 대해서 알아봤다.

Designed by Tistory.