SpringMVC - 02. 서블릿
서블릿
서블릿이란?
- java를 사용하여 웹페이지를 동적으로 생성하는 서버측 프로그램 혹은 그 사양
- 위키피디아 참고
HTTP 요청 데이터 전달 방법
HttpServletRequest
- 서블릿이 HTTP 요청 메세지를 파싱해주고 나온 그 결과를 담을 객체
- 해당 HTTP 요처잉 시작부터 끝날 때 까지 유지되는 임시 저장소 기능도 함
- 저장 : request.setAttribute(name, value)
- 조회 : request.getAttribute(name)
- 세션 광리 기능
- request.getSession(create: true)
01. GET - 쿼리 파라미터
- 메세지 바디 없이, URL의 쿼리 파라미터에 데이터를 직접 포함해서 전달
- 검색, 필터, 페이징 등에서 많이 사용
- ?를 시작으로 보낼 수 있음 (추가 파라미터는 &로 구분)
- ex) /url?username=hello&age=20
02. POST - HTML Form
- content-type: application/x-www-form-urlencoded
- 메세지 바디에 쿼리 파라미터 형식으로 전달
- 회원 가입, 상품 주문 등에서 사용
- 매번 HTML Form을 만들기 불편하므로 Postman을 사용하여 테스트
01, 02에서 넘어온 쿼리 파라미터 조회 방법
- 위 두 방법은 클라이언트 입장에서 방식의 차이가 있으나, 서버 입장에선 둘의 형식이 동일함
- 따라서 같은 방법으로 파라미터값을 조회할 수 있음
System.out.println("[전체 파라미터 조회] - start");
request.getParameterNames().asIterator()
.forEachRemaining(paramName -> System.out.println(paramName + "=" + request.getParameter(paramName)));
System.out.println("[전체 파라미터 조회] - end");
System.out.println();
System.out.println("[단일 파라미터 조회] - start");
String username = request.getParameter("username");
String age = request.getParameter("age");
System.out.println("username = " + username);
System.out.println("age = " + age);
System.out.println("[단일 파라미터 조회] - end");
System.out.println();
System.out.println("[이름이 같은 복수 파라미터 조회]");
String[] usernames = request.getParameterValues("username");
for (String name: usernames) {
System.out.println("name = " + name);
}
System.out.println();
03. HTTP message body에 데이터를 직접 담아서 요청
- HTTP API에서 주로 사용
- 주로 JSON을 데이터 형식으로 사용 (XML, TEXT도 가능)
- POST, PUT, PATCH 사용 가능
03-1. meesage body : Text
-
메세지 바디를 Text로 보냈을 때 이를 바로 읽어오는 방법
-
@Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // message body의 내용을 byte 코드로 바로 읽어움 ServletInputStream inputStream = request.getInputStream(); // 가져온 byte 코드를 문지로 변환함 String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8); System.out.println("messageBody = " + messageBody); response.getWriter().write("ok"); }
03-2. message body: JSON
-
가장 많이 사용되는 데이터 형식
-
보통 JSNO을 그대로 쓰지 않고 객체로 변환하여 사용 (getter, setter 생성)
-
// JSON을 java 객체로 변환할 때 사용하는 jackson 라이브러리 (Spring MVC에 기본 제공) private ObjectMapper om = 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); HelloData helloData = om.readValue(messageBody, HelloData.class); System.out.println("helloData.username = " + helloData.getUsername()); System.out.println("helloData.userage = " + helloData.getAge()); response.getWriter().write("ok"); }
HTTP 응답 데이터 처리 방법
HttpServletResponse
- HTTP 응답코드, 헤더, 바디 생성
- 편의 기능 : Content-type 지정, Cookie 생성, Redirect
- 기본 사용 코드
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// [status-line]
// 상태코드는 내부적으로 선언되어있는 상수를 그대로 쓰자
response.setStatus(HttpServletResponse.SC_OK);
// [response-headers]
response.setHeader("Content-Type", "text/plain;charset=utf-8");
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Prama", "no-cache");
response.setHeader("my-header", "hello");
// [Header 편의 메소드]
content(response);
cookie(response);
redirect(response);
// [Message Body]
PrintWriter writer = response.getWriter();
writer.println("ok");
}
private void content(HttpServletResponse response) {
// Content-Type: text/plain;charset=utf-8
// Content-Length: 2
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
// response.setContentLength(3); 생략시 자동 생성 => 보통 생략함
}
private void cookie(HttpServletResponse response) {
// Set-Cookie: myCookie=good; Max-Age=600;
Cookie cookie = new Cookie("myCookie", "good");
cookie.setMaxAge(600);
response.addCookie(cookie);
}
private void redirect(HttpServletResponse response) throws IOException {
// Status Code 302
// Location: /basic/hello-form.htmlz
response.sendRedirect("/basic/hello-form.html");
}
01. 단순 텍스트 응답
-
Request와 차이가 없음
// [Message Body] PrintWriter writer = response.getWriter(); writer.println("ok");
02. HTML 응답
- content-type : ‘text/html’
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 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>");
}
03. API JSON
- HTTP API에 사용
- content-type : ‘application/json’
private ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void service(HttpServletRequest requset, HttpServletResponse response) throws ServletException, IOException {
// Content-Type: application/json
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
HelloData helloData = new HelloData();
helloData.setUsername("kim");
helloData.setAge(20);
// {"username":"kim", "age":20}
String result = objectMapper.writeValueAsString(helloData);
response.getWriter().write(result);
}
댓글남기기