[작성일: 2024. 04. 11]
HttpServletRequest 역할
HTTP 요청 메시지를 개발자가 직접 파싱해서 사용하면 매우 불편해진다. 서블릿은 개발자가 HTTP 요청 메시지를 편리하게 사용할 수 있도록 개발자 대신에 HTTP 요청 메시지를 파싱하고, 그 결과를 HttpServletRequest 객체에 담아서 제공한다.
POST /save HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
username=kim&age=20
HttpServletRequest를 사용하면 HTTP 메시지를 편리하게 조회할 수 있다.
Start Line에는 HTTP 메소드, URL, 쿼리 스트링, 스키마, 프로토콜의 정보를 제공한다.
Header에서는 헤더를 조회할 수 있고 Host, Content-Type 등의 정보를 제공한다.
Body에서는 form 파라미터 형식을 조회, message body 데이터를 직접 조회할 수 있다.
HttpServletRequest 객체는 이 외에도 임시 저장소 기능, 세션 관리 기능 등 여러가지 부가 기능도 함께 제공한다.
HTTP 요청이 시작할 때부터 끝날 때까지 유지되는 임시 저장소 기능은,
- 저장: request.setAttribute(name, value)
- 조회: request.getAttribute(name)
등과 같이 사용할 수 있다.
세션 관리 기능은 request.getSession(create: true)와 같이 사용한다.
HttpServletRequest, HttpServletResponse 객체는 HTTP 요청 메시지, HTTP 응답 메시지를 편리하게 사용하도록 도와주는 객체이기 때문에 더 깊게 이해하기 위해서는 HTTP 스펙이 제공하는 요청/응답 메시지 자체를 이해해야 한다.
HttpServletRequest 기본 사용법
package hello.servlet.basic.request;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "requestHeaderServlet", urlPatterns = "/request-header")
public class RequestHeaderServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
printStartLine(request);
}
private static 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.isSecure()은 http면 false, https면 true로 출력된다.
// Header 모든 정보
private void printHeaders(HttpServletRequest request) {
System.out.println("--- Headers - start ---");
/*
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
System.out.println(headerName + ": " + request.getHeader(headerName));
}
*/
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 편의 조회]");
// Host 헤더
System.out.println("request.getServerName() = " + request.getServerName());
// Host 헤더
System.out.println("request.getServerPort() = " + request.getServerPort());
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();
}
로컬에서 테스트하면 IPv6 정보가 나오는데 IPv4 정보를 보고 싶으면 다음 옵션을 넣어주자.
-Djava.net.preferIPv4Stack=true
🐣 출처: 인프런 김영한님 강의
이 글은 인프런의 김영한님 스프링 강의를 보고 작성한 글입니다.
강의를 들으면서 정리한 글이므로 틀린 내용이나 오타가 있을 수 있습니다.