서블릿

kimwoody·2022년 7월 5일
0

spring-mvc1

목록 보기
1/1

Hello 서블릿

예전에는 톰캣같은 WAS를 설치하고, 그 위에 서블릿 코드를 올려서 실행했다. 하지만 이 과정은 매우 번거롭다.
스프링 부트는 톰캣을 내장하고 있으므로, 톰캣 설치 없이 편리하게 서블릿 코드를 실행할 수 있다.

스프링 부트 서블릿 환경 구성

스프링 부트 실행 클래스 위에 @ServletComponentScan 어노테이션을 사용해서 Servlet을 빈으로 등록하고 사용할 수 있게 한다.

@ServletComponentScan //서블릿 자동 등록 @SpringBootApplication
public class ServletApplication {
      public static void main(String[] args) {
          SpringApplication.run(ServletApplication.class, args);
			}
}

단, 빈으로 등록해서 사용할 Servlet에는 @WebServlet 어노테이션을 붙여준다. name, urlPattern 속성을 이용해서 해당 서블릿에 이름과 URL을 매핑해준다.

@WebServlet(name = "helloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {

		@Override
		protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}

서블릿에 매핑된 URL로 HTTP 요청을 보내면 서블릿 컨테이너는 service 메소드를 실행한다.

HttpServletRequest

서블릿은 개발자가 HTTP 요청 메시지를 편리하게 사용할 수 있도록 개발자 대신에 HTTP 요청 메시지를 파싱한다. 그리고 그 결과를 HttpServletRequest 객체에 담아서 제공한다.

개발자는 HttpServletReqeust 를 사용하면 HTTP 요청 메시지에 담긴 정보들을 편리하게 조회하고 사용할 수 있다.

http://localhost:8080/request-header?username=hello

위의 URL로 HTTP 요청을 하면 아래와 같은 HTTP 요청 메시지가 Servlet으로 오게 된다.

GET /request-header?username=hello HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Cache-Control: max-age=0
Connection: keep-alive
Cookie: JSESSIONID=85CE3F8B7693D8DA7870CEAB850E7A33
Host: localhost:8080
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"

Servlet에서는 HttpServletRequest 객체를 사용해서 HTTP 요청 메시지 내부의 데이터를 사용할 수 있다.

참고링크 Java(TM) EE 8 Specification APIs

HTTP 요청 데이터

GET - 쿼리 파라미터

  • /url?username=hello&age=20
  • 메시지 바디 없이, URL의 쿼리 파라미터에 데이터를 포함해서 전달
  • 예) 검색, 필터, 페이징 등에서 많이 사용하는 방식

http://localhost:8080/request-param?username=hello&age=20

위의 URL로 실행

@WebServlet(name = "helloServlet", urlPatterns = "/request-param")
public class HelloServlet extends HttpServlet {

		@Override
		protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
				String username = request.getParameter("username");
				String age = request.getParameter("age");
		}
}

POST - HTML Form

  • Content-Type: application/x-www-form-urlencoded
  • 메시지 바디에 쿼리 파라미터 형식으로 전달 username=hello&age=20
  • 예) 회원가입, 상품 주문, HTML Form 사용

http://localhost:8080/request-param

위의 URL로 Form Data 전송

@WebServlet(name = "helloServlet", urlPatterns = "/request-param")
public class HelloServlet extends HttpServlet {

		@Override
		protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
				String username = request.getParameter("username");
				String age = request.getParameter("age");
		}
}

HTTP message body

  • HTTP API에 주로 사용
  • 데이터 형식은 주로 JSON 형식 사용
  • Content-Type: application/json

http://localhost:8080/request-body-json

위의 URL로 JSON 데이터 전송({"username": "hello", "age": 20})

JSON 데이터를 파싱할 수 있는 객체 생성

@Getter @Setter
public class HelloData {

		private String username;
		private int age;
}

Servlet에서 JSON 데이터를 객체로 파싱

@WebServlet(name = "requestBodyJsonServlet", urlPatterns = "/request-body-json")
public class RequestBodyJsonServlet extends HttpServlet {

    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());

        response.getWriter().write("OK");
    }
}

HttpServletResponse

HttpServletResponse 역할

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

HttpServletResponse 를 사용해서 클라이언트에 보내줄 응답 메시지, 응답 코드, 헤더, 바디 등을 설정할 수 있다.

Java(TM) EE 8 Specification APIs

HTTP 응답 데이터

HTML 응답

@WebServlet(name = "responseHtmlServlet", urlPatterns = "/response-html")
public class ResponseHtmlServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");

        PrintWriter writer = response.getWriter();
        writer.println("<html>");
        writer.println("<body>");
        writer.println("<div>");
        writer.println("안녕?");
        writer.println("</div>");
        writer.println("</body>");
        writer.println("</html>");
    }
}

HTTP 응답으로 HTML을 반환할 때는 Content-Type을 text/html 로 지정해야 한다.

API JSON 응답

@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.setContentType("application/json");
        response.setCharacterEncoding("utf-8");

        HelloData helloData = new HelloData();
        helloData.setUsername("cheoljin");
        helloData.setAge(9999);

        // {"username": "hello", "age": 20}
        String result = objectMapper.writeValueAsString(helloData);
        response.getWriter().write(result);
    }
}

HTTP 응답으로 JSON을 반환할 때는 Content-Type을 application/json 로 지정해야 한다. Jackson 라이브러리가 제공하는 objectMapper.writeValueAsString() 를 사용하면 객체를 JSON 문자로 변경할 수 있다.

추가

Servlet & Servlet Lifecycle

https://velog.io/@kimwoody/Servlet-Servlet-Lifecycle

0개의 댓글