spring

HttpServletRequest

Beencle 2023. 3. 5. 15:29

HttpServeltRequest 역할

  • HTTP 요청 메세지를 개발자가 직접 파싱해서 사용해도 되지만, 매우 불편할 것이다. 서블릿을 개발자가 HTTP 요청 메세지를 편리하게 사요할 수 있도록 개발자 대신 HTTP 요청 메세지를 파싱한다. 그리고 그 결과를 HttpServletRequest객체에 담아서 제공한다.
  • HttpServletRequest를 사용하면 다음과 같은 HTTP 요청 메세지를 편리하게 조회할 수 있다.
POST /save HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
username=kim&age=20

정보)

START LINE

- HTTP 메소드

- URL

- 쿼리 스트링

- 스키마, 프로토콜

HEADER

- 해더 정보

BODY

- form 파라미터 형식 조회

- message body 데이터 조회

 

이 외에도 HttpServletRequest 객체는 여러가지 부가 기능도 제공한다.

1. 임시 저장소 기능

해당 HTTP요청이 시작부터 끝날때 까지 유지되는 임시 저장소 기능

- 저장 : request.setAttribute(name,value)

- 조회 : request.getAttribute(name)

2. 세션 관리 기능

- request.getSession(create:true)

 

* HttpServletRequest, HttpServletResponse를 사용할때 가장 중요한 점은 이 객체들이 HTTP 요청메세지, HTTP응답 메세지를 편리하게 사용하도록 도와주는 객체라는 점이다. 따라서 이 기능에 대해서 깊이있는 이해를 하려면 "HTTP 스펙이 제공하는 요청,응답 메세지 자체를 이해" 해야 한다.

 

먼저 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();

이처럼 HttpServletRequest를 사용해서 메소드, 프로토콜, 스키마, URL 등등을 꺼내서 보여줄수 있다.

--- REQUEST-LINE - start ---
request.getMethod() = GET
request.getProtocol() = HTTP/1.1
request.getScheme() = http
request.getRequestURL() = http://localhost:8080/request-header
request.getRequestURI() = /request-header
request.getQueryString() = null
request.isSecure() = false
--- REQUEST-LINE - end ---

이런 결과 값을 볼 수 있다.

이중에 header의 정보를 가져와 보는 모습을 보자

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에 header들을 모두 꺼내어 하나씩 콘솔에 보여주는 모습이다.

위의 코드를 요즘식으로 간결하게 표현하게 되면 아래와 같은 코드가 된다.

System.out.println("--- Headers - start ---");
request.getHeaderNames().asIterator()
	.forEachRemaining(headerName -> System.out.println(headerName+ request.getHeader(headerName)));
System.out.println("--- Headers - end ---");
System.out.println();

결과는 모두 같게 나온다.

hostlocalhost:8080
connectionkeep-alive
cache-controlmax-age=0
sec-ch-ua"Chromium";v="110", "Not A(Brand";v="24", "Google Chrome";v="110"
sec-ch-ua-mobile?0
sec-ch-ua-platform"Windows"
upgrade-insecure-requests1
user-agentMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36
accepttext/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
sec-fetch-sitenone
sec-fetch-modenavigate
sec-fetch-user?1
sec-fetch-destdocument
accept-encodinggzip, deflate, br
accept-languageko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
--- Headers - end ---

이제 header의 편의 기능을 조회해보자

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();

[결과]

더보기

--- Header 편의 조회 start ---
[Host 편의 조회]
request.getServerName() = localhost
request.getServerPort() = 8080

[Accept-Language 편의 조회]
locale = ko_KR
locale = ko
locale = en_US
locale = en
request.getLocale() = ko_KR

[cookie 편의 조회]

[Content 편의 조회]
request.getContentType() = null
request.getContentLength() = -1
request.getCharacterEncoding() = UTF-8
--- Header 편의 조회 end ---

위에 내용을 보게 되면 먼저 host의 이름과 포트 번호가 보이고 다음에 보이는 Accept-Language는 웹에서 이해하는 언어의 순서를 보여준다. 그 다음엔 쿠키정보인데 이것 또한 header에 담겨서 온다. 현재는 쿠키가 없기때문에 나오지 않는다.

이때 null인 이유는 get방식으로 받아왓는데 이때 우리는 아무런 값도 넘겨주지 않았기 때문에 null이 된다.

 

이제 기타 정보에 대해 알아보자. 별로 중요한 내용은 아니니 이런 기능도 잇다는것만 기억해두자.

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();

[결과]

더보기

--- 기타 조회 start ---
[Remote 정보]
request.getRemoteHost() = 0:0:0:0:0:0:0:1
request.getRemoteAddr() = 0:0:0:0:0:0:0:1
request.getRemotePort() = 52207

[Local 정보]
request.getLocalName() = 0:0:0:0:0:0:0:1
request.getLocalAddr() = 0:0:0:0:0:0:0:1
request.getLocalPort() = 8080
--- 기타 조회 end ---

지금까지 HttpServletRequest를 통해 HTTP메세지에 start-line, header 정보 조회 방법을 이해했다.