HTTP 프로토콜
HTTP는 Hyper Text Transfer Protocol의 약자로, 인터넷 상에서 데이터를 주고 받기 위한 약속, 규칙이다. 웹에서는 클라이언트(브라우저)와 서버간에 데이터를 주고 받기 위한 방식으로 HTTP프로토콜을 사용한다. 이렇게 규칙을 정해두었기 때문에, 모든 프로그램이 이 규칙에 맞춰 개발함으로써 서로 정보를 교환할 수 있게 된다. HTTP로 보낼 수 있는 데이터는 HTML문서, 이미지, 동영상, 오디오, 텍스트 문서, JSON형식 등 여러종류가 있으며 브라우저에서 요청하면 서버는 요청에 대한 내용을 처리하여 브라우저에 다시 응답해준다.
HTTP 프로토콜의 특징
단순하고 읽기 쉽다. - 텍스트 기반의 프로토콜
상태를 유지하지 않는다. (stateless) - 클라이언트의 정보를 저장하지 않는다. (이를 보완하기 위해 쿠키와 세션을 이용)
확장 가능하다. - 커스텀 헤더(header) 추가 가능
HTTP 메시지
HTTP의 요청과 응답을 보낼 때 사용되는 메시지 형태
요청 메시지
GET /ch2/hello HTTP/1.1
Host: 111.22.33.44:8080
Connection: keep-alive
Cache-Control: max-age=0
Accept-Encoding: gzip, deflate, br
응답 메시지
HTTP/1.1 200 OK
Content-Length: 44
Content-Type: text/html
Date: Sat, 20 Oct 2021 19:03:38 GMT
<html>
<head></head>
<body>Hello</body>
</html>
클라이언트와 서버간 요청과 응답을 이해하기 위해서는 먼저 클라이언트(Client)와 서버(Server)를 이해해야 한다.
클라이언트란 요청을 보내는 쪽을 의미하며 일반적으로 웹 관점에서는 브라우저를 의미하며,
서버란 요청을 받는 쪽을 의미하며 일반적으로 데이터를 보내주는 원격지의 컴퓨터를 의미한다.
웹 애플리케이션 서버 (WAS)?
Web Server는 Web을 서비스해주며 WAS는 서버의 프로그램을 사용할 수 있도록 해주는 역할을 한다. 우리가 만든 프로그램을 클라이언트(브라우저)에서 원격호출 할 수 있는 이유가 WAS가 있기 때문이다.
WAS를 사용하는 이유
프로그램이 브라우저에 저장되어있을 경우 update에 문제가 생긴다. 해당 브라우저에서 업데이트 한 프로그램은 다른 브라우저에서는 업데이트가 적용되지 않기 때문이다. 하지만 서버에 프로그램이 설치되어있다면 서버 한 곳만 update하면 모든 브라우저에서 동일하게 프로그램을 사용할 수 있다. 즉, update에 용이하기 때문에 WAS를 사용한다.
Spring에서의 HTTP 요청과 응답
HttpServletRequest
브라우저에서 서버로 요청할 때 데이터를 담아서 요청할 수 있다. 이 때 톰캣(WAS)에서는 자동으로 HttpServletRequest 객체를 생성해주며 요청 정보를 객체에 저장해준다. 서버에서는 HttpServletRequest를 통해 브라우저에서 보낸 요청 데이터를 처리할 수 있게 된다.
예제를 통해 HttpServletRequest에 담긴 데이터를 콘솔에 찍어보자.
RequestInfo 클래스 생성
@Controller
public class RequestInfo {
@RequestMapping("/requestInfo")
public void main(HttpServletRequest request) {
// HttpServletRequest 객체를 받아온다.
// 요청 내용의 인코딩
System.out.println("request.getCharacterEncoding()="
+request.getCharacterEncoding());
// 요청 내용의 길이. 알수 없을 때는 -1
System.out.println("request.getContentLength()="
+request.getContentLength());
// 요청 내용의 타입. 알 수 없을 때는 null
System.out.println("request.getContentType()="
+request.getContentType());
// 요청 방법
System.out.println("request.getMethod()="+request.getMethod());
// 프로토콜의 종류와 버젼 HTTP/1.1
System.out.println("request.getProtocol()="+request.getProtocol());
// 프로토콜
System.out.println("request.getScheme()="+request.getScheme());
// 서버 이름 또는 ip주소
System.out.println("request.getServerName()="+request.getServerName());
// 서버 포트
System.out.println("request.getServerPort()="+request.getServerPort());
// 요청 URL
System.out.println("request.getRequestURL()="+request.getRequestURL());
// 요청 URI
System.out.println("request.getRequestURI()="+request.getRequestURI());
// context path
System.out.println("request.getContextPath()="
+request.getContextPath());
// servlet path
System.out.println("request.getServletPath()="
+request.getServletPath());
// 쿼리 스트링
System.out.println("request.getQueryString()="
+request.getQueryString());
// 로컬 이름
System.out.println("request.getLocalName()="+request.getLocalName());
// 로컬 포트
System.out.println("request.getLocalPort()="+request.getLocalPort());
// 원격 ip주소
System.out.println("request.getRemoteAddr()="+request.getRemoteAddr());
// 원격 호스트 또는 ip주소
System.out.println("request.getRemoteHost()="+request.getRemoteHost());
// 원격 포트
System.out.println("request.getRemotePort()="+request.getRemotePort());
}
}
브라우저에서 해당 URL로 요청
실행 결과
request.getCharacterEncoding()=null
request.getContentLength()=-1
request.getContentType()=null
request.getMethod()=GET
request.getProtocol()=HTTP/1.1
request.getScheme()=http
request.getServerName()=localhost
request.getServerPort()=8080
request.getRequestURL()=http://localhost:8080/ch2/requestInfo
request.getRequestURI()=/ch2/requestInfo
request.getContextPath()=/ch2
request.getServletPath()=/requestInfo
request.getQueryString()=null
request.getLocalName()=localhost
request.getLocalPort()=8080
request.getRemoteAddr()=0:0:0:0:0:0:0:1
request.getRemoteHost()=0:0:0:0:0:0:0:1
request.getRemotePort()=51831
HttpServletRequest 객체에 내장되어있는 메서드를 통해 원하는 요청 정보들을 얻을 수 있다.
HttpServletRequest의 메서드
쿼리스트링(Query String)
브라우저에서 서버로 요청할 때 데이터를 보내는 방법 중 하나로 URL뒤에 name=value 형식으로 데이터를 담아서 보낼 수 있다.
이 때 ? 뒤에 데이터를 담을 수 있으며 이 데이터 형식을 쿼리스트링이라고 한다.
?year=2021&month=12&day=31
이 데이터를 얻기 위해서는 HttpServletRequest 객체의 getParameter 메서드를 이용해서 얻어올 수 있다.
@Controller
public class RequestInfo {
@RequestMapping("/requestInfo")
public void main(HttpServletRequest request) {
String year = request.getParameter("year");
String year = request.getParameter("month");
String year = request.getParameter("day");
// 파라미터를 한번에 가져올 경우
Enumeration enum = request.getParameterNames();
Map paramMap = request.getParameterMap();
}
}
?year=2021&year=2020&year=2019
쿼리스트링의 name이 같은 경우
@Controller
public class RequestInfo {
@RequestMapping("/requestInfo")
public void main(HttpServletRequest request) {
String[] yearArr = request.getParameterValues("year");
}
}
HttpServletResponse
HttpServletResponse객체도 HttpServletRequest객체와 마찬가지로 톰캣(WAS)에서 자동으로 객체를 생성해준다. 서버에서 만든 응답 정보를 브라우저에 보낼 때 사용한다.
예제를 통해 쿼리스트링으로 받은 데이터를 브라우저에 출력해보자
ResponseEx 클래스 생성
@Controller
public class ResponseEx {
@RequestMapping("/responseEx")
public void main(HttpServletRequest request, HttpServletResponse response) throws Exception {
String name = request.getParameter("name");
String age = request.getParameter("age");
// response 객체를 통해 브라우저에 보낼 데이터 형식 설정
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
// html 형식으로 보내기위해 PrintWriter 객체 사용
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("</head>");
out.println("<body>");
out.println("이름은 : "+ name+" 나이는 : "+age);
out.println("</body>");
out.println("</html>");
}
}
브라우저에 해당 URL로 요청
실행 결과
'프로그래밍 > Spring' 카테고리의 다른 글
[Spring] Tomcat의 내부 구조, 설정 파일에 대해 알아보자 (0) | 2021.12.28 |
---|---|
[Spring] 클라이언트와 서버에 대해 알아보자 (0) | 2021.12.28 |
[Spring] 원격 프로그램 실행방법에 대해 알아보자 (0) | 2021.12.27 |
[Spring] Maven Lifecycle에 대해 알아보자 (0) | 2020.09.02 |
[Spring] Maven에 대해 알아보자 (0) | 2020.09.02 |