여행을 개발하다

[Java] Servlet, HttpServletRequest 인터페이스(Interface) 본문

BackEnd/Java

[Java] Servlet, HttpServletRequest 인터페이스(Interface)

yhtragramming 2021. 8. 27. 22:58

 

너무 습관적으로만 사용했던 HttpServletRequest 인터페이스에 대해 공부해보았다.

 

인터페이스명을 그대로 뜯어보면 Http + Servlet + Request인데, Http는 프로토콜, Request는 말 그대로 요청이다. Servlet은 익히 들어왔지만 이의 정확한 의미와 작동 원리는 무엇일까...

 

본격적으로 HttpServletRequest에 대해 이야기하기 전에 간단하게 정리를 해봤다.

 

1. Servlet

정확히 말하면 'Java Servlet'을 의미하는데, 자바를 사용하여 동적으로 웹 페이지를 만들어주는 서버 측 프로그램 혹은 사양을 의미한다. (참조 : 위키백과, 검색어 : 자바 서블릿)

 

일반적으로 불리는 웹 서버(Web Server)는 클라이언트의 요청에 정적인 페이지(Javascript, HTML, 이미지)만을 응답해 줄 수 있다. 그래서 웹 서버 자체만으로는 동적 페이지를 클라이언트에게 전달할 수 없으며, 이는 필히 다른 애플리케이션의 도움을 필요로 한다.

 

이 역할을 하는 애플리케이션이 '(Java) Servlet'이다.

Servlet Architecture (출처 : https://www.geeksforgeeks.org/servlet-architecture/ )

 

2. Servlet Container

그러나 Servlet 자체도 혼자서는 그 역할을 오롯이 해낼 수 없다.

 

클라이언트의 요청에 응답하기 위해서는 여러 개의 스레드를 생성해야 하며, 부가적으로는 서블릿(서비스) 메서드 요청, 파라미터 관리 등의 일을 해야 한다.

 

그래서 보통은 웹 서버와 Servlet 사이에 Servlet Container를 두어 클라이언트 요청에 대한 스레드 풀(Thread Pool)을 관리하게 된다. Servlet Container는 웹 서버의 요청이 있을 때마다 스레드를 생성하며, 요청에 맞는 Servlet 메서드를 호출하여 웹 서버로 다시 전달한다.

 

대표적으로 WAS(Web Application Server)로 알려진 Apache Tomcat이 있지만, 사실 WAS는 (Web Server + Servlet Container) 두 개가 합쳐진 좀 더 넓은 개념이다.

 

3. HttpServeletRequest Interface?

① 인터페이스의 기능

→ 서블릿 컨테이너는 웹 서버로부터 들어온 클라이언트의 요청을 넘겨받아, HttpServletRequest 인터페이스의 객체를 생성한다. 이 객체에 클라이언트의 요청사항들을 담아 서블릿 서비스 메서드에 전달하므로, 클라이언트의 요청에 관한 많은 정보를 내장시키고 있다.

 

Servlet Container는 요청에 관한 각종 정보를 HttpServletRequest 객체에 담아 Servlet Method에 보낸다

 

② 인터페이스의 내장 메서드

HttpServeletRequest 인터페이스는 내부적으로 ServletRequest 인터페이스를 상속받고 있다.

따라서, 아래의 내장 메서드들은 ServletRequest 혹은 HttpServeletRequest 인터페이스의 멤버이다.

 

아래의 예제는 메소드명, 리턴 자료형, 설명 순으로 line을 구분하였고, 예제에서 쓰인 request는 별도 선언한 HttpServeletRequest 인터페이스의 객체라고 가정한다.

 

(1) getServerPort()

return java.lang.Integer

→ 요청을 받은 곳(서버)의 포트 번호를 리턴한다.

request.getServerPort() // 8080

 

(2) getLocalAddr()

return java.lang.String

→ 요청을 받은 인터페이스(서버)의 IP 주소를 리턴한다.

request.getLocalAddr() // 127.0.0.1

 

(3) getMethod()

return java.lang.String

→ 요청이 이루어진 Http 메서드의 종류를 리턴한다(GET, POST, PUT)

 request.getMethod() // POST

 

(4) getHeaderNames()

return java.util.Enumeration<java.lang.String>

→ 요청에 담겨있는 헤더들의 이름들을 리턴한다.

Enumeration<String> headerNames = request.getHeaderNames();
   while(headerNames.hasMoreElements()){
   System.out.println("request.getHeaderNames()==>" + headerNames.nextElement());
}
//request.getHeaderNames()==>host
//request.getHeaderNames()==>connection
//request.getHeaderNames()==>sec-ch-ua
//request.getHeaderNames()==>accept
//request.getHeaderNames()==>x-requested-with
//request.getHeaderNames()==>sec-ch-ua-mobile
//request.getHeaderNames()==>user-agent
//request.getHeaderNames()==>sec-fetch-site
//request.getHeaderNames()==>sec-fetch-mode
//request.getHeaderNames()==>sec-fetch-dest
//request.getHeaderNames()==>referer
//request.getHeaderNames()==>accept-encoding
//request.getHeaderNames()==>accept-language
//request.getHeaderNames()==>cookie

 

(5) getPathInfo()

return java.lang.String

→ 요청이 들어온 URL에 추가되어 있는 부가적인 경로 정보를 리턴한다.

request.getPathInfo() // null

 

(6) getQueryString()

return java.lang.String

→ URL에 포함되어 있는 Query 정보를 String 형태로 이어 리턴한다. 우리가 일반적으로 넘기는 GET 방식의 파라미터들을 가져오는 메서드다.

request.getQueryString() // CODE_ID=&CODE_NM=&CODE_DC=&cntPerPage=10&curPage=1

 

(7) getRemoteUser()

return java.lang.String

→ 요청한 사용자의 로그인 정보를 리턴한다. 인증이 완료된 사용자라면 정보를 리턴하고, 그렇지 않다면 null을 리턴한다.

request.getRemoteUser() // null

 

(8) getRequestURL()

return java.lang.StringBuffer

→ 클라이언트가 요청한 URL을 재구성하여 리턴한다.

request.getRequestURL() // http://localhost:8080/comCode/comCodeListUp

 

(9) getRequestURI()

return java.lang.String

→ HTTP 요청에서 쿼리 문자열까지 이 요청의 URL 부분을 리턴한다.

request.getRequestURI() // /comCode/comCodeListUp

 

(10) getServletPath()

return java.lang.String

→ 서블릿을 호출하는 요청자의 URL을 리턴한다.

request.getServletPath() // /comCode/comCodeListUp

 

(11) getRemoteAddr()

return java.lang.String

→ 요청한 호스트 혹은 마지막으로 요청한 프록시의 IP 주소를 리턴한다.

request.getRemoteAddr() // 0:0:0:0:0:0:0:1

 

(12) getRemoteHost()

return java.lang.String

→ 요청한 호스트 혹은 마지막으로 요청한 프록시의 정규화된 이름을 리턴한다.

request.getRemoteHost() // 0:0:0:0:0:0:0:1

 

(13) getRemotePort()

return java.lang.Integer

→ 요청한 호스트 혹은 마지막으로 요청한 프록시의 포트 정보를 리턴한다.

request.getRemotePort() // 53009

 

(14) getParameter(Parameter Name)

return java.lang.String

→ 매개변수로 받은 파라미터의 value를 리턴한다.

request.getParameter("CODE_ID") // null

 

(15) request.getParameterMap()

return java.util.Map<java.lang.String,java.lang.String[]>

→ 파라미터들을 Map<String, String[]> 형태로 리턴한다.

Map<String, String[]> parameterMap = request.getParameterMap();
Iterator<String> itr = parameterMap.keySet().iterator();
String key = null;
String[] value = null;
while(itr.hasNext()){
   key = itr.next();
   value = parameterMap.get(key);  
   System.out.println("request.getParameterMap(), " + key + " : " + Arrays.toString(value));
}
// 결과
//request.getParameterMap(), CODE_ID : []
//request.getParameterMap(), CODE_NM : []
//request.getParameterMap(), CODE_DC : []
//request.getParameterMap(), cntPerPage : [10]
//request.getParameterMap(), curPage : [1]

 

 

4. 활용 방안

프로젝트를 하면서 가장 높은 빈도로 썼던 메서드는 request.getParameter("파라미터") 뿐이었던 것 같다.

이제는 HttpServletRequest 인터페이스의 기능을 공부했으니, 나름 고도화(?) 된 활용 방안을 생각해 보았다.

활용 방안의 경우는 프로그래머들의 니즈에 따라 다양하며 정해진 것이 아니기에..

 

아래는 작성자의 주관적인 생각임을 미리 독자 여러분들께 말씀드립니다.

 

① Log를 남기는데 활용

HttpServletRequest 인터페이스를 활용하면 클라이언트가 어떤 메뉴, 어느 시각에 접근했는지를 log로 남길 수 있다. 여기서의 log는 spring 자체의 log(Apache log4j)로 단순히 console 출력이 될 수도 있고, 개발자가 구성해놓은 DB Table에 하나의 record가 될 수도 있다. 대체로 로그인한 사용자 정보, 클라이언트의 ip 주소, 접근 메서드(request.getRequestURI) 정도를 별도의 log 테이블로 구성한다. 단, 개발 중인 애플리케이션의 특징, 고객사의 현업 요건 등을 고려하여 테이블의 구조와 개수는 개발자와 DBA가 협의해야 하겠지만 말이다.

HttpServletRequest 객체를 parameter로 log 기록하기

 

② 웹페이지의 메뉴 navigation

웬만한 프로그램의 메뉴 리스트도 대부분 DB에서 관리하고 있다. 메뉴 정보를 담고 있는 테이블은 상/하위(부모/자식) 메뉴의 계층형 구조이며, 각 메뉴가 프로그램에서 어떤 url로 관리되고 있는지도 저장된다. HttpServeletRequest 인터페이스의 getRequestURI() 메서드를 활용하면 클라이언트가 어떤 url로 요청했는지 쉽게 확인할 수 있고, 이를 파라미터로 받아 해당 메뉴의 상세정보(메뉴명, table 내에서 관리되고 있는 메뉴 ID)를 select 해 올 수 있다.

HttpServletRequest 객체를 parameter로 메뉴 조회 해오기

지금까지 Servlet, HttpServletRequest 인터페이스에 대해 알아보았다.

 

감사합니다.

'BackEnd > Java' 카테고리의 다른 글

[Java] TreeMap  (0) 2021.12.21
[Java] Iterator(반복자)  (1) 2021.09.02
[Java] Thread (스레드)  (0) 2021.08.15
[Java] Wrapper Class(래퍼 클래스)  (0) 2021.08.04
ArrayList  (0) 2019.05.15
Comments