2024. 10. 11. 15:38ㆍWeb Development/스프링 MVC 1편
HttpServletRequest - 개요
1. HttpServletRequest 역할
HTTP 요청 메시지를 개발자가 직접 파싱해서 사용해도 되지만, 매우 불편할 것이다.
서블릿은 개발자가 HTTP 요청 메시지를 편리하게 사용할 수 있도록 개발자 대신에 HTTP 요청 메시지를 파싱한다. 그리고 그 결과를 'HttpServletRequest' 객체에 담아서 제공한다.
HttpServletRequest를 사용하면 다음과 같은 HTTP 요청 메시지를 편리하게 조회할 수 있다.
2. HTTP 요청 메시지
POST /save HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
username=kim&age=20
- START LINE
- HTTP 메소드
- URL
- 쿼리 스트링
- 스키마, 프로토콜
- 헤더
- 헤더 조회
(한줄 비움)
- 바디
- form 파라미터 형식 조회
- message body 데이터 직접 조회
HttpServletRequest 객체는 추가로 여러가지 부가기능도 함께 제공한다.
3. 임시 저장소 기능
- 해당 HTTP 요청이 시작부터 끝날 때까지 유지되는 임시 저장소 기능
- 저장 : request.setAttribute(name, value)
- 조회 : request.getAttribute(name)
4. 세션 관리 기능
- request.getSession(create:true)
⭐중요
: HttpServletRequest, HttpServletResponse를 사용할 때 가장 중요한 점은 이 객체들이 HTTP 요청 메시지, HTTP 응답 메시지를 편리하게 사용하도록 도와주는 객체라는 점이다. 따라서 이 기능에 대해서 깊이있는 이해를 하려면 HTTP 스펙이 제공하는 요청, 응답메시지 자체를 이해해야한다.
HttpServletRequest - 기본사용법
Main> java> basic 아래 request 패키지 생성, 그 아래에 RequestHeaderServlet.java 파일 생성
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 {
//urlpattern "/request-header" 호출 시 자동실행되는 service 메소드
printStartLine(request);
//printHeaders(request);
//printHeaderUtils(request);
//printEtc(request);
response.getWriter().write("ok");
}
}
1. start Line
//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();
}
결과 확인
2. Header 정보 확인
//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();
}
결과확인
3. Header 편리한 조회
//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();
}
결과확인
- Accept-Language
: 브라우저에서 언어 지원 순서를 설정,
request.getLocale() 메소드로 가장 우선순위의 언어를 가져올 수 있다.
* 이 때, request.getContentType 이 null 인 이유는 GET 방식 요청이기 때문
-> POSTMAN 을 활용하여 POST 방식으로 요청해보자.
결과 확인
4. 기타 정보 조회
//기타 정보
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();
}
결과확인
HTTP 요청 데이터 - 개요
HTTP 요청 메시지를 통해 클라이언트에서 서버로 데이터를 전달하는 방법을 알아보자.
주로 다음 세가지 방법을 사용한다.
1. GET - 쿼리 파라미터
- /url?username=suyeon&age=26
- 메시지 바디 없이, URL의 쿼리 파라미터에 데이터를 포함해서 전달
- 예) 검색, 필터, 페이징등에서 많이 사용하는 방식
2. POST - HTML Form
- content-type: application/x-www-form-urlencoded
- 메시지 바디에 쿼리 파라미터 형식으로 전달 username=suyeon&age=26
- 예) 회원 가입, 상품 주문, HTML Form 사용
3. HTTP message body 에 데이터를 직접 담아서 요청
- HTTP API에서 주로 사용, JSON, XML, TEXT
- 데이터 형식은 주로 JSON 사용
- POST, PUT, PATCH
HTTP 요청 데이터 - GET 쿼리 파라미터
다음 데이터를 클라이언트에서 서버로 전송해보자.
전달 데이터
- username=suyeon
- age=26
메시지 바디 없이, URL의 "쿼리 파라미터"를 사용해 데이터를 전달하자.
예) 검색, 필터, 페이징 등에서 많이 사용하는 방식
쿼리 파라미터는 URL에 다음과 같이 "?"를 시작으로 보낼 수 있다. 추가 파라미터는 "&"로 구분하면 된다.
- http://localhost:8080/request-param?username=suyeon&age=26
서버에서는 HttpServletRequest 가 제공하는 다음 메서드를 통해 쿼리 파라미터를 편리하게 조회할 수 있다.
쿼리 파라미터 조회 메서드
String username = request.getParameter("username"); //단일 파라미터 조회
Enumeration<String> parameterNames = request.getParameterNames(); //파라미터 이름을 모두 조회
Map<String, String[]> parameterMap = request.getParameterMap(); //파라미터를 Map으로 조회
String[] usernames = request.getParameterValues("username"); //개수 파라미터 조회
(실습)
RequestParamServlet.java 생성
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;
import java.util.Enumeration;
/**
* 1. 파라미터 전송 기능
* http://localhost:8080/request-param?username=suyeon&age=26
*
*/
@WebServlet(name="RequestParamServlet", urlPatterns = "/request-param")
public class RequestParamServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
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");
}
}
결과확인
+ 이름이 같은 복수 파라미터 조회
* username=hello&username=kim 과 같이 파라미터 이름은 하나인데, 값이 중복이면 어떻게 될까?
request.getParameter() 는 하나의 파라미터 이름에 대해서 단 하나의 값만 있을 때 사용해야 한다.
지금처럼 중복일 때는 request.getParameterValues() 를 사용해야 한다.
참고) 이렇게 중복일 때 request.getParameter() 를 사용하면 request.getParameterValues() 의 첫 번째 값을 반환한다.
System.out.println("[이름이 같은 복수 파라미터 조회]-START");
String[] usernames = request.getParameterValues("username");
for(String name : usernames) {
System.out.println("username = "+name);
}
System.out.println("[이름이 같은 복수 파라미터 조회]-END");
- http://localhost:8080/request-param?username=suyeon&age=26&username=suyeon2
결과확인
'Web Development > 스프링 MVC 1편' 카테고리의 다른 글
서블릿, JSP, MVC 패턴(2) (1) | 2024.10.20 |
---|---|
서블릿, JSP, MVC 패턴(1) (0) | 2024.10.14 |
서블릿(3) (1) | 2024.10.13 |
서블릿(1) (7) | 2024.10.10 |
웹 애플리케이션 이해 (0) | 2024.07.06 |