0. 개요
- Servlet 사용법을 자세히 배우기 전에, 우선 기본적인 HTTP 지식에 대해 알아보자.
- 그다음에 Servlet이 HTTP request와 response를 어떻게 처리하는지에 대해 알아보자.
1. 웹 서비스의 HTTP 요청과 응답
a) GET 방식
- 데이터를 url 파라미터(= 쿼리 파라미터)로 전달하는 방식
- 검색, 필터, 페이징 등에서 자주 사용하는 방식이다.
https://devraphy.tistory.com?category=Back-end&id=123
- 위의 예시를 보면, 물음표를 기점으로 쿼리 파라미터를 작성한 부분이라는 것을 알 수 있다.
- category라는 이름의 파라미터에는 Back-end라는 값이 매핑된다.
- id라는 이름의 파라미터에는 123이라는 값이 매핑된다.
- 쿼리 파라미터로 전달되는 값은 모두 String 자료형이다.
b) POST 방식 - <Form> 태그 사용
- HTTP 메시지 바디에 쿼리 파라미터를 저장하여 전달하는 방식으로,
- server에게 전달하는 데이터가 url에 노출되면 안 되는 경우 사용하는 방식이다.
- 일반적으로 HTML의 <Form> 태그를 사용하여 데이터를 전달할 때, 이 방식으로 전달된다.
- 이 경우, HTTP 헤더에 content-type의 값이 application/x-www-form-urlencoded로 되어있다.
- 즉, <Form> 태그로부터 데이터가 전달되었다고 판단할 수 있다.
c) HTTP message body
- HTTP 메시지 바디에 데이터를 담아서 전달하는 방식
- 주로 HTTP API 또는 RESTful API에서 사용하는 방식이다.
- JSON, XML, Text 데이터 형식을 사용할 수 있으나, 주로 JSON 형식을 사용한다.
- POST, PUT, PATCH와 같은 HTTP 메서드를 사용한다.
- 여기까지 웹 서비스에서 사용되는 HTTP 요청과 응답 형태에 대해서 알아보았다.
- 이제부터는 위에서 설명한 3가지 방식을 Servlet이 어떻게 처리하는지 알아보자.
2. Servlet의 요청 데이터 조회
- Servlet은 HttpServletRequest를 사용하여 client의 Request 메시지를 객체로 만든다.
- 그렇다면 Service() 메서드 내부에서 request 객체가 가진 값을 어떻게 조회하는지 알아보자.
a) HttpServletRequest.getParameter() - 쿼리 파라미터 조회
@WebServlet(name = "helloServlet", urlPatterns = "매핑할 url주소")
public class HelloServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 단일 파라미터의 값 조회 ex) www.tistory.com?username=devraphy
String param = request.getParameter("username"); // "devraphy" 반환
// 2. 동일 파라미터의 복수 값 조회 ex) www.tistory.com?nickname=raphy&nickname=rapha
String[] params = request.getParameterValues("nickname"); // ["raphy", "rapha"] 반환
// 3. 전체 파라미터의 값 조회 ex) www.tistory.com?username=devraphy&nickname=raphy
// 모든 쿼리 파라미터의 값을 Enum 자료형으로 반환한다. 그러므로 iterator를 사용한다.
request.getParameterNames().asIterator()
.forEachRemaining(paramName -> System.out.println(paramName + ": "
+ request.getParameter(paramName)));
}
}
- GET 방식 또는 <Form> 태그로 전달된 request의 데이터를 조회하는 방법으로 getParameter()를 사용한다.
- <Form> 태그는 POST 메서드로 전달된 request 다.
- 그러므로 왜 다른 형식으로 보내진 reuqest 데이터를 동일한 메서드로 조회할 수 있는지 의문이 들 것이다.
- <Form> 태그를 사용하면 HTTP 메시지 바디에 쿼리 파라미터가 저장된다.
- 쿼리 파라미터라는 데이터의 형식이 GET 방식과 동일하기 때문에 같은 메서드를 사용하여 조회할 수 있다.
- 즉, getParameter()는 GET 방식과 <Form> 태그로 부터 넘어온 request만 조회할 수 있다.
b) HTTP message body 조회
@WebServlet(name = "helloServlet", urlPatterns = "url 매핑 주소")
public class HelloServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. request의 body 내용을 바이트코드로 얻어옴
ServletInputStream inputStream = request.getInputStream();
// 2. 받아온 바이트코드를 문자열로 변환, 엔코딩 형식 기입해야함
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
}
}
- 우선 HTTP message body의 데이터를 읽기 위해서는 inputStream을 사용해야 한다.
- HTTP message body의 내용은 바이트 코드로 작성되어 있기 때문이다.
- 받아온 바이트 코드를 문자열로 변환하는데, 이때 StreamUtils의 copyToString() 메서드를 사용한다.
- copyToString() 메서드에는 문자열로 변환할 대상과 변환 형식(= 엔코딩)을 매개변수로 받는다.
- 엔코딩 형식은 상수로 제공된다.
3. Servlet의 응답 반환
- Servlet에서 어떻게 response를 처리하는지에 대해서 알아보자.
a) Response - 일반 text를 반환
@WebServlet(name = "helloServlet", urlPatterns = "url 매핑 주소")
public class HelloServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1 header의 content-type 및 인코딩 형식 설정
resp.setHeader("Content-Type", "text/plain;charset=utf-8");
// 2. response 객체를 이용한 Text를 반환할 객체를 생성
PrintWriter writer = resp.getWriter();
// 3. client에게 text를 반환
writer.println("HTTP response 테스트");
}
}
- response message의 헤더를 text 형식으로 설정한다.
- 그다음 response객체를 이용하여 writer 객체를 생성한다.
- writer 객체를 이용하여 client에게 전달하고 싶은 text를 반환한다.
- client는 해당 text를 response로 전달받고, 브라우저에 출력한다.
b) Response - HTML 반환
@WebServlet(name = "helloServlet", urlPatterns = "매핑 url")
public class HelloServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. response 헤더 설정
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
// 2. response 객체를 이용한 writer 객체 생성
PrintWriter writer = response.getWriter();
// 3. HTML 반환
writer.println("<html>");
writer.println("<body>");
writer.println("<div> 안녕 </div>");
writer.println("</body>");
writer.println("</html>");
}
}
- HTML을 응답하는 것은 text를 응답하는 방법과 차이가 없다.
- 다만, HTML을 위의 예시처럼 일일이 작성하여 전달해야 한다는 불편함이 있다.
- 이처럼 view를 처리해야 한다는 것이 Servlet을 사용하는 데에 있어서 가장 불편한 점이다.
c) Response - JSON 반환
@Getter @Setter
public class HelloData { // JSON 반환에 사용할 데이터 형식
private String username;
private int age;
}
@WebServlet(name = "helloServlet", urlPatterns = "url 매핑 주소")
public class HelloServlet extends HttpServlet {
// 1. 반환 데이터를 JSON 형식으로 바꿔주는 역할
private ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 2. Response 헤더 설정
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
// 3. 반환 데이터 설정
HelloData helloData = new HelloData();
helloData.setUsername("Raphael");
helloData.setAge(20);
// 4. json형식으로 parsing
String result = objectMapper.writeValueAsString(helloData);
// 5. response 객체에 담아 client에게 전달
response.getWriter().write(result);
}
}
- 위의 예시 코드와 같이, JSON 반환 시 사용할 데이터 형식을 따로 클래스로 만들어 사용할 수 있다.
- 여기서 핵심이 되는 부분은 ObjectMapper이다.
- resposne body에 담기는 데이터는 String 형식이므로 이를 JSON 형식으로 바꿔줘야 한다.
- 이때 ObjectMapper의 writeValueAsString() 메서드를 사용하여 변환할 수 있다.
- JSON을 전달받은 client는 이를 브라우저에 다음과 같이 출력한다.
'Back-end > Spring MVC 개념' 카테고리의 다른 글
6. MVC 1의 등장 (0) | 2022.03.01 |
---|---|
5. JSP의 등장 (0) | 2022.02.28 |
3. Servlet - 기본 사용 방법 (0) | 2022.02.24 |
2. Servlet의 등장 (0) | 2022.02.23 |
1. Java 웹 기술의 역사 (0) | 2022.02.22 |
댓글