HTTP 요청 메시지를 개발자가 직접 파싱해서 사용해도 되지만, 매우 불편할 것이다.
서블릿은 개발자가 HTTP 요청 메시지를 편리하게 사용할 수 있도록 개발자 대신에 HTTP 요청 메시지를 파싱한다.
그리고 그 결과를 HttpServletRequest 객체에 담아서 제공한다
HttpServletRequest를 사용하면 다음과 같은 HTTP 요청 메시지를 편리하게 조회할 수 있다.
POST /save HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
username=lee&age=30
시작 라인 ( POST /save HTTP/1.1 )은
- HTTP 메소드
- URL
- 쿼리 스트링
- 스키마, 프로토콜
의 정보가 담겨있다.
헤더는 헤더 내용이,
바디는
- form 파라미터 형식을 조회할 수 있고
- message body 데이터를 직접 조회할 수 있다.
HttpServletRequest 객체는 추가로 여러 가지 부가기능도 함께 제공한다.
1) 임시 저장소 기능을 한다
: 해당 HTTP요청이 시작될 때부터 끝날 때까지 유지되는 임시 저장소 기능을 한다.
- 저장 : request.setAttribute(name, value);
- 조회 : request.getAttribute(name)
2) 세션 관리 기능을 한다
- request,getSession(create : true);
★★★ 중요 ★★★
HttpServletRequest, HttpServletRespinse를 사용할 때 가장 중요한 점은 이 객체들이 HTTP 요청 메시지, HTTP 응답 메시지를 편리하게 사용하도록 도와주는 객체라는 점이다. 따라서 이 기능에 대해서 깊이있는 이해를 하려면 HTTP 스펙이 제공하는 요청, 응답 메시지 자체를 이해해야 한다.
HttpServletRequest 기본 사용법
RequestHeaderServlet.java
package helloMVC.servlet.basic.request;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "requestHeaderServlet", urlPatterns = "/request-header")
public class RequestHeaderServlet extends HttpServlet {
// Ctrl + O
// protected 로 만들어야 한다. public 으로 만들면 안된다.
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
printStartLine(request);
printHeaders(request);
printHeaderUtils(request);
printEtc(request);
response.getWriter().write("ok");
}
//start line 정보
private void printStartLine(HttpServletRequest request) {
System.out.println("--- REQUEST-LINE - start ---");
System.out.println("request.getMethod() = " + request.getMethod()); //GET
System.out.println("request.getProtocol() = " + request.getProtocol()); //HTTP/1.1
System.out.println("request.getScheme() = " + request.getScheme()); //http
// http://localhost:8080/request-header
System.out.println("request.getRequestURL() = " + request.getRequestURL());
// /request-header
System.out.println("request.getRequestURI() = " + request.getRequestURI());
//username=hi
System.out.println("request.getQueryString() = " +
request.getQueryString());
System.out.println("request.isSecure() = " + request.isSecure()); //https 사용 유무
System.out.println("--- REQUEST-LINE - end ---");
System.out.println();
}
//Header 모든 정보
private void printHeaders(HttpServletRequest request) {
System.out.println("--- Headers - start ---");
/*
// 옛날 방식의 iterator 보는 방식
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
System.out.println(headerName + ": " + request.getHeader(headerName));
}
*/
// 요즘은 Arrow Function 사용해서 Iterator를 돌린다.
request.getHeaderNames().asIterator()
.forEachRemaining(headerName -> System.out.println(headerName + ":" + request.getHeader(headerName)));
System.out.println("--- Headers - end ---");
System.out.println();
}
//Header 편리한 조회
private void printHeaderUtils(HttpServletRequest request) {
System.out.println("--- Header 편의 조회 start ---");
System.out.println("[Host 편의 조회]");
System.out.println("request.getServerName() = " +
request.getServerName()); //Host 헤더
System.out.println("request.getServerPort() = " +
request.getServerPort()); //Host 헤더
System.out.println();
System.out.println("[Accept-Language 편의 조회]");
request.getLocales().asIterator()
.forEachRemaining(locale -> System.out.println("locale = " +
locale));
System.out.println("request.getLocale() = " + request.getLocale());
System.out.println();
System.out.println("[cookie 편의 조회]");
if (request.getCookies() != null) {
for (Cookie cookie : request.getCookies()) {
System.out.println(cookie.getName() + ": " + cookie.getValue());
}
}
System.out.println();
System.out.println("[Content 편의 조회]");
System.out.println("request.getContentType() = " +
request.getContentType());
System.out.println("request.getContentLength() = " +
request.getContentLength());
System.out.println("request.getCharacterEncoding() = " +
request.getCharacterEncoding());
System.out.println("--- Header 편의 조회 end ---");
System.out.println();
}
//기타 정보
private void printEtc(HttpServletRequest request) {
System.out.println("--- 기타 조회 start ---");
System.out.println("[Remote 정보]");
System.out.println("request.getRemoteHost() = " +
request.getRemoteHost()); //
System.out.println("request.getRemoteAddr() = " +
request.getRemoteAddr()); //
System.out.println("request.getRemotePort() = " +
request.getRemotePort()); //
System.out.println();
System.out.println("[Local 정보]");
System.out.println("request.getLocalName() = " +
request.getLocalName()); //
System.out.println("request.getLocalAddr() = " +
request.getLocalAddr()); //
System.out.println("request.getLocalPort() = " +
request.getLocalPort()); //
System.out.println("--- 기타 조회 end ---");
System.out.println();
}
}
위 서블릿을 만들고 Postman으로 HTTP 테스트를 할 수 있다.
로컬에서 테스트하면 IPv6 정보가 나오는데, IPv4 정보를 보고 싶으면 다음 옵션을 VM options에 넣어주면 된다.
-Djava.net.preferIPv4Stack=true
'스프링 > 스프링 웹' 카테고리의 다른 글
[Spring] HTTP 요청 데이터 - POST HTML Form (0) | 2023.05.17 |
---|---|
[Spring] HTTP 요청 데이터 종류 및 GET 쿼리 파라미터 (0) | 2023.05.17 |
[Spring] 서블릿(Servlet) 만들기 (0) | 2023.05.16 |
[Spring] 서블릿(Servlet) 프로젝트 환경 설정 (IntelliJ) (0) | 2023.05.16 |
[Spring] 자바 백엔드 웹 기술 역사(서블릿, JSP, MVC) (1) | 2023.05.16 |
댓글