Day69 Java프로그래밍 기초(HTTP)
HTTP(Hyper Text Transport Protocol)
1. HTTP의 정의
- HTTP (HyperText Transfer Protocol)는 월드 와이드 웹에서 정보를 주고받을 수 있게 해주는 프로토콜로, 클라이언트와 서버 간에 요청과 응답을 주고받는 방식으로 동작함.
2. HTTP의 구조
- 요청(Request): 클라이언트가 서버로 보내는 메시지. 주요 구성 요소는 다음과 같음.
- 요청 라인: 메서드(GET, POST 등), 요청 URL, HTTP 버전 정보 포함.
- 헤더(Header): 요청에 대한 부가 정보를 담고 있으며, 콘텐츠 유형, 인코딩 방식 등 포함.
- 본문(Body): 요청의 데이터가 담긴 부분으로, POST 요청 등에서 사용됨.
- 응답(Response): 서버가 클라이언트에게 보내는 메시지. 주요 구성 요소는 다음과 같음.
- 상태 라인: HTTP 버전, 상태 코드(예: 200 OK), 상태 메시지 포함.
- 헤더(Header): 응답에 대한 부가 정보를 담고 있으며, 서버 정보, 콘텐츠 유형 등 포함.
- 본문(Body): 요청에 대한 실제 데이터가 담긴 부분. HTML, JSON 등 다양한 형태로 전달됨.
3. HTTP의 메서드
- HTTP의 메서드의 기능과 특징
HTTP 메서드 | 기능 | 특징 |
---|---|---|
GET | 서버에서 데이터를 조회 | URL의 쿼리 스트링에 데이터를 포함하여 전송, 서버에서 리소스를 가져와 표시 |
POST | 서버에 데이터를 전송하여 처리 (리소스 생성) | 요청 본문에 데이터를 포함하여 전송, 리소스를 생성하거나 서버 상태 변경 |
HEAD | 서버에서 응답 헤더만 확인 | GET과 동일하지만 본문은 반환하지 않음 |
PUT | 서버에 데이터를 업로드하거나 리소스를 갱신 | 리소스를 생성하거나 대체, 리소스가 존재하지 않으면 새로 생성함 |
DELETE | 서버에서 특정 리소스를 삭제 | 리소스를 삭제하지만 삭제가 보장되지는 않음 |
OPTIONS | 서버가 지원하는 메서드 목록을 확인 | 서버에서 사용할 수 있는 HTTP 메서드와 통신 옵션을 확인할 때 사용 |
TRACE | 요청 경로 추적 (디버깅 목적) | 서버가 받은 요청을 그대로 응답으로 반환, 주로 디버깅에 사용됨 |
CONNECT | 서버와 클라이언트 간에 터널링 설정 (주로 HTTPS) | 클라이언트와 서버 간의 SSL 터널링을 설정하여 보안 연결을 위한 터널을 생성 |
4. 헤더의 주요 종류와 기능
1) General 헤더
정의
- General 헤더는 HTTP 요청과 응답 모두에서 사용될 수 있는 헤더로, 전송되는 메시지에 대한 일반적인 메타데이터를 제공하는 역할을 한다. 이 헤더는 특정 요청이나 응답 본문과 관련된 것이 아니라, 클라이언트와 서버 간의 통신에 대한 정보를 포함한다.
General 헤더의 주요 특징
- 캐시 제어:
Cache-Control
헤더는 클라이언트와 서버 간에 전송된 데이터에 대해 캐시 정책을 정의하는 역할을 한다.no-cache
는 캐시된 데이터를 사용하지 않고 항상 서버에서 최신 데이터를 가져오도록 지시한다.
- 연결 관리:
Connection
헤더는 클라이언트와 서버 간의 연결 상태를 관리하는 데 사용된다.keep-alive
는 현재 연결을 유지하여 추가적인 요청을 처리할 수 있게 하며,close
는 요청 후 연결을 종료하라는 지시를 내린다.
- 메시지의 날짜와 시간 정보:
Date
헤더는 요청 또는 응답이 생성된 날짜와 시간을 나타낸다.- 서버와 클라이언트 간에 시간을 동기화하거나, 응답의 유효성을 확인하는 데 사용된다.
- 구형 HTTP와의 호환성:
Pragma
헤더는 주로 HTTP/1.0과의 호환성을 유지하기 위해 사용되며, 캐시 제어와 같은 정책을 정의한다.Pragma: no-cache
는 구형 브라우저가 캐시하지 않도록 지시한다.
General 헤더의 예제
헤더 | 기능 | 특징 |
---|---|---|
Date | 요청 또는 응답이 생성된 날짜와 시간을 나타냅니다. | 날짜와 시간을 RFC 1123 형식으로 표시하며, 서버와 클라이언트 간 시간 정보를 동기화하는 데 사용됩니다. |
Connection | 클라이언트와 서버 간의 연결 관리를 설정합니다. | keep-alive 를 사용하면 연결을 유지하여 여러 요청을 처리할 수 있으며, close 는 연결을 종료합니다. |
Cache-Control | 클라이언트 또는 서버에서 응답을 캐시할 수 있는지와 캐시 동작 방식을 제어합니다. | no-cache , no-store , max-age 등을 사용하여 캐싱을 제어하며, 서버 응답의 유효성을 조정할 수 있습니다. |
Pragma | HTTP/1.0과의 호환성을 위한 캐시 제어 용도로 사용됩니다. | 주로 no-cache 값을 사용하여 구형 HTTP/1.0 캐시 제어를 위해 사용되며, 최신 HTTP에서는 거의 사용되지 않습니다. |
2) Entity 헤더
정의
- Entity 헤더는 HTTP 응답 또는 요청에서 전송되는 실제 데이터(엔터티)에 대한 메타데이터를 제공하는 역할을 한다.
- 주로 본문(payload)에 대한 정보, 데이터의 길이, 형식, 인코딩 방법 등을 설명하는 데 사용된다.
- 이러한 정보를 통해 클라이언트는 서버가 전송하는 데이터에 대해 더 많은 정보를 얻을 수 있고, 이를 적절하게 처리할 수 있다.
Entity 헤더의 주요 특징
- 엔터티 본문에 대한 정보 제공:
- Entity 헤더는 전송되는 데이터(엔터티)에 대한 정보를 제공하는 역할을 한다.
- 데이터의 타입(MIME 타입), 길이, 인코딩 방식, 언어, 압축 방식 등을 정의한다.
- 콘텐츠의 형식과 처리 방식:
- Entity 헤더는 클라이언트가 응답 데이터를 어떻게 해석하고 처리해야 할지에 대한 지침을 제공한다.
- 텍스트 데이터인지, 이미지인지, 압축된 데이터인지 등을 알려준다.
- 요청 및 응답에서 모두 사용 가능:
- Entity 헤더는 요청과 응답 모두에 사용될 수 있다.
- 클라이언트가 서버에 요청을 보낼 때
Content-Type
을 통해 요청 본문의 데이터 형식을 알릴 수 있고, 서버는 응답할 때에도 동일한 방식으로 응답 데이터의 형식을 알린다.
- 데이터 무결성:
Content-MD5
와 같은 엔터티 헤더는 전송된 데이터의 무결성을 검증하는 데 사용할 수 있다.- 이 헤더는 데이터가 전송 중에 손상되지 않았는지를 확인하는 데 도움을 준다.
- 엔터티의 길이와 범위:
Content-Length
나Content-Range
와 같은 헤더는 전송되는 데이터의 크기와 범위를 정의하여, 클라이언트가 데이터를 어떻게 수신해야 하는지 알려준다.
Entity 헤더의 예제
헤더 | 기능 | 특징 |
---|---|---|
Content-Length | 전송되는 엔터티 본문의 바이트 크기를 나타냅니다. | 서버가 전송할 데이터의 크기를 명확하게 정의하여 클라이언트가 수신할 데이터를 준비할 수 있게 합니다. |
Content-Type | 전송되는 데이터의 MIME 타입을 지정합니다. | 응답의 데이터 형식을 클라이언트에게 알려주어, 클라이언트가 데이터를 올바르게 해석하고 처리할 수 있도록 합니다. |
Last-Modified | 리소스가 마지막으로 수정된 날짜와 시간을 나타냅니다. | 클라이언트는 이 값을 통해 캐시된 리소스가 최신 상태인지 확인할 수 있으며, 이를 기반으로 조건부 요청을 할 수 있습니다. |
Expires | 응답 데이터가 더 이상 유효하지 않게 되는 시간을 나타냅니다. | 이 시간이 지나면 클라이언트는 데이터를 더 이상 캐시에서 사용하지 않고, 서버에서 새로 데이터를 요청해야 합니다. |
Content-Encoding | 본문 데이터에 적용된 인코딩 방식을 지정합니다. | 주로 데이터를 압축하여 전송할 때 사용되며, 클라이언트는 해당 인코딩 방식을 해제하여 원본 데이터를 복구합니다. |
3) Request 헤더
정의
- Request 헤더는 클라이언트가 서버에 요청을 보낼 때, 추가적인 정보를 제공하는 역할을 한다.
- 이 정보는 클라이언트와 서버 간의 통신을 더 효과적으로 처리하기 위해 사용된다.
- 클라이언트의 브라우저 정보, 요청에 대한 인증 정보, 언어 설정 등과 같은 정보가 포함된다.
- 서버는 클라이언트의 요구 사항을 이해하고, 적절하게 응답할 수 있다.
Request 헤더의 주요 특징
- 클라이언트 정보 제공:
- Request 헤더는 클라이언트의 정보를 서버에 제공하는 역할을 한다.
User-Agent
헤더는 클라이언트의 브라우저나 운영 체제 정보를 서버에 전달한다.
- 콘텐츠 협상:
- 클라이언트가 서버로부터 원하는 데이터 형식이나 언어를 지정할 수 있다.
Accept
헤더는 클라이언트가 받을 수 있는 콘텐츠의 MIME 타입을 정의하며,Accept-Language
는 선호하는 언어를 나타낸다.
- 인증 및 보안:
- Request 헤더는 서버에 인증 정보를 제공하여 클라이언트를 식별하거나, 서버와의 안전한 통신을 위한 토큰을 포함할 수 있다.
Authorization
헤더는 클라이언트가 서버에 액세스하기 위한 자격 증명을 전달한다.
- 캐시 제어:
- 클라이언트가 서버에서 캐시된 데이터를 사용할지 여부를 지정할 수 있다.
If-Modified-Since
헤더는 클라이언트가 마지막으로 받은 리소스가 수정되었는지 확인하고, 수정된 경우에만 새 데이터를 받도록 한다.
- 호스트와 리소스 식별:
- Request 헤더는 요청된 리소스를 더 구체적으로 식별하는 데 도움을 준다.
Host
헤더는 클라이언트가 요청하는 서버의 도메인 이름을 지정하며,Referer
헤더는 클라이언트가 요청을 보낸 이전 페이지의 URL을 전달한다.
Request 헤더의 예제
헤더 | 기능 | 특징 |
---|---|---|
Accept | 클라이언트가 서버로부터 받을 수 있는 콘텐츠의 MIME 타입을 지정합니다. | 여러 MIME 타입을 지정할 수 있으며, q 파라미터를 사용해 우선순위를 설정할 수 있습니다. |
Host | 클라이언트가 요청하는 서버의 호스트 이름과 포트를 명시합니다. | 가상 호스팅을 사용하는 서버에서 여러 도메인을 처리하기 위해 필수적으로 사용됩니다. |
Referer | 현재 요청을 발생시킨 이전 웹 페이지의 URL을 서버에 전달합니다. | 보안 및 개인정보 보호를 위해 일부 정보는 생략될 수 있습니다. |
User-Agent | 클라이언트의 브라우저, 운영체제 등의 정보를 서버에 제공합니다. | 서버는 이 정보를 통해 클라이언트 환경에 맞춘 응답을 제공할 수 있습니다. |
Authorization | 서버에 인증 정보를 전달하여 클라이언트를 식별하거나 권한을 부여받습니다. | Basic , Bearer 등의 인증 방식을 사용하며, 민감한 정보를 포함하므로 HTTPS와 함께 사용합니다. |
Accept-Encoding | 클라이언트가 서버로부터 받을 수 있는 데이터의 인코딩 방식을 지정합니다. | gzip , deflate 와 같은 압축 방식이 일반적으로 사용됩니다. |
Accept-Language | 클라이언트가 선호하는 언어를 서버에 전달합니다. | 여러 언어를 지정할 수 있으며, 우선순위를 q 파라미터로 설정할 수 있습니다. |
4) Response 헤더
정의
- Response 헤더는 서버가 클라이언트에 응답을 보낼 때 추가적인 정보를 제공하는 역할을 한다.
- 서버가 전송하는 데이터의 특성, 클라이언트와 서버 간의 연결 방식, 상태 코드 및 캐시 제어와 같은 다양한 요소를 포함한다.
- 이를 통해 클라이언트는 응답을 적절하게 해석하고 처리할 수 있다.
Response 헤더의 주요 특징
- 서버 정보 제공:
- Response 헤더는 서버의 정보를 클라이언트에 제공하는 역할을 한다.
- 예를 들어,
Server
헤더는 응답을 제공하는 서버의 소프트웨어 정보를 전달한다.
- 콘텐츠 메타데이터 제공:
- 서버가 전송하는 콘텐츠의 형식과 길이 등의 메타데이터를 제공한다.
- 예를 들어,
Content-Type
헤더는 전송된 데이터의 MIME 타입을 지정하며,Content-Length
헤더는 전송된 데이터의 크기를 지정한다.
- 캐시 제어:
- 서버는
Cache-Control
과 같은 헤더를 통해 클라이언트가 응답 데이터를 캐시할 수 있는지 여부를 결정할 수 있다. - 이를 통해 서버는 클라이언트가 캐시된 데이터를 사용할 수 있게 하거나, 새 데이터를 받아야 할지 결정한다.
- 서버는
- 리다이렉션 관리:
- Response 헤더는 클라이언트를 다른 URL로 리다이렉션할 수 있다.
- 예를 들어,
Location
헤더는 서버가 클라이언트에게 새 URL로 이동하도록 지시할 때 사용된다.
- 상태 정보 전달:
- 서버는
Retry-After
와 같은 헤더를 사용하여, 클라이언트가 요청을 다시 시도해야 하는 시간을 전달할 수 있다. - 이 헤더는 서버가 일시적으로 서비스할 수 없을 때 유용하다.
- 서버는
- 보안 관련 정보 제공:
- Response 헤더는 클라이언트에게 보안 관련 정보를 제공할 수 있다.
- 예를 들어,
Strict-Transport-Security
헤더는 클라이언트에게 HTTPS 연결만 허용하도록 지시한다.
Response 헤더의 예제
헤더 | 기능 | 특징 |
---|---|---|
Content-Type | 서버가 클라이언트에게 전송하는 콘텐츠의 MIME 타입을 명시합니다. | 데이터의 형식을 명시하며, 클라이언트는 이를 통해 응답을 어떻게 처리할지 결정합니다. |
Content-Length | 서버가 클라이언트에게 전송하는 데이터의 크기(바이트 단위)를 명시합니다. | 응답의 정확한 크기를 제공하여 클라이언트가 데이터 전송을 처리할 수 있게 도와줍니다. |
Set-Cookie | 서버가 클라이언트에게 쿠키를 설정할 때 사용됩니다. | 쿠키는 클라이언트의 브라우저에 저장되며, 이후 요청 시 자동으로 서버에 전송됩니다. |
Location | 클라이언트를 다른 URL로 리다이렉션할 때 사용됩니다. | 3xx 상태 코드와 함께 사용되며, 클라이언트를 지정된 URL로 이동시킵니다. |
Cache-Control | 클라이언트나 프록시 서버가 응답 데이터를 캐시할 수 있는지 여부를 제어합니다. | no-cache , no-store , max-age 등의 값으로 캐싱 동작을 제어할 수 있습니다. |
Expires | 응답이 더 이상 유효하지 않은 날짜와 시간을 명시합니다. | 이 헤더는 캐싱된 응답의 유효 기간을 명시하는 데 사용됩니다. |
WWW-Authenticate | 클라이언트에게 인증이 필요할 때 인증 방식을 제안합니다. | 주로 401 Unauthorized 응답과 함께 사용되며, 클라이언트는 인증 정보를 포함하여 다시 요청합니다. |
Retry-After | 서버가 현재 처리할 수 없을 때 다시 요청할 수 있는 시간을 명시합니다. | 주로 503(Service Unavailable) 응답과 함께 사용되며, 클라이언트가 다시 요청하기 전에 대기해야 할 시간을 지정합니다. |
GET요청과 POST요청
1. GET요청
- 웹 브라우저에 URL을 입력한 후 엔터를 치면 GET 요청을 보낸다.
- 웹 페이지에서 링크를 클릭하면(자바스크립트 처리하지 않은 상태) GET 요청을 보낸다.
- 웹 페이지의 폼(method=’GET’ 일 때)에서 전송 버튼을 클릭하면 GET 요청을 보낸다.
2. POST요청
- 웹 페이지의 폼(method=’POST’ 일 때)에서 전송 버튼을 클릭하면 POST 요청을 보낸다.
3. 클라이언트가 보낸 값 꺼내기
- 서블릿에서 데이터를 읽을 때, ServletRequest.getParameter(“파라미터명”)을 통해 읽는다.
인코딩 설정
- POST요청으로 보낸 데이터는 ISO-8859-1의 인코딩 방식을 사용한다.
- 한글의 데이터를 POST요청으로 받을 때는 req.setCharacterEncoding(“UTF-8”)을 설정한다.
4. GET요청과 POST요청 비교
파일 업로드
1. multipart/form-data 형식
- GET 요청이나 일반 POST 요청을 한 경우에는 파일이 이름만 넘어오고 파일 데이터는 넘어오지 않는다.
- GET 요청 시에는 String query에 파일이름만 넘어온다.
- POST 요청의 기본 데이터 전송 형식은 “application/x-www-form-urlencoded”으로 파일이름만 넘어온다.
- 데이터를 받기 위해서는 멀티파트 형식의 POST요청이 필요하다.
2. Sevlet 기본 라이브러리로 파일 업로드
데이터 형식 설정
- multipart/form-data으로 데이터를 받기 전 multipart/form-data에 대한 설정을 해야한다.
- xml에서
<multipart-config>
방법과 어노테이션@MultipartConfig
의 방식이 있다.
1
2
3
4
5
6
7
<servlet>
<servlet-name>ex04.Servlet05</servlet-name>
<servlet-class>com.eomcs.web.ex04.Servlet05</servlet-class>
<multipart-config>
<max-file-size>10000000</max-file-size>
</multipart-config>
</servlet>
1
@MultipartConfig(maxFileSize = 1024 * 1024 * 10)
데이터 읽어오기
- 일반 폼 데이터를 꺼낼 때는
getParameter("name")
로값을 꺼낸다. - 바이너리 데이터는
getPart("name")
을 통해 Part객체를 인스턴스 후Part.write("저장경로")
로 저장한다.
1
2
3
4
5
6
7
8
9
10
// req에 대한 인코딩 설정(form-data은 UTF설정을 해야한다.)
req.setCharacterEncoding("UTF-8");
HttpServletRequest httpReq = (HttpServletRequest) req;
// 문자열 데이터 추출
httpReq.getParameter("age")
// 바이너리 데이터 추출
Part photoPart = httpReq.getPart("photo");
photoPart.write("/uploadDir"+filename);
3. Apache 라이브러리 활용
- Apache 라이브러리는 FileItem 객체를 분석하여 파일과 form 데이터를 구분할 수 있다.
DiskFileItemFactory
- 각 파트 데이터를 분석하여 파라미터 이름과 값을 추출한다.
- 파일인 경우 임시 폴더에 저장한다.
- FileItem객체를 생성하여 해당 정보들을 리턴한다.
ServletFileUpload
- 클라이언트가 보낸 multipart 형식의 HTTP요청 프로토콜을 분석한다.
- DiskFileItemFactory을 통해 FilItem을 담는다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
ServletFileUpload multipartDataHandler = new ServletFileUpload(fileItemFactory);
List<FileItem> parts = multipartDataHandler.parseRequest((HttpServletRequest) req);
for (FileItem part : parts) {
if (part.isFormField()) {
// 파트의 데이터가 일반 데이터라면
paramMap.put(part.getFieldName(), // 클라이언트가 보낸 파라미터 이름
part.getString("UTF-8") // 파라미터의 값. 값 꺼낼 때 인코딩을 지정해야 한다.
);
} else {
// 파트의 데이터가 파일이라면
// => upload/ 디렉토리에 파일을 저장한다.
// 업로드 파일을 저장할 때 사용할 파일명을 준비한다.(중복방지)
String filename = UUID.randomUUID().toString();
// 전체 파일 경로를 준비한다.
File file = new File(this.uploadDir + "/" + filename);
// 임시 폴더에 저장된 파일을 지정된 파일 경로로 옮긴다.
part.write(file);
paramMap.put(part.getFieldName(), // 클라이언트가 보낸 파라미터 이름
filename // 파일 이름
);
}
}
참고자료
1. 절대경로와 상대경로
2. Payload
- HTTP에서의 Payload는 클라이언트와 서버 간의 HTTP 요청 또는 응답에서 전달되는 실제 데이터를 의미한다.
- 요청이나 응답의 본문(body)에 포함된 데이터이며, 헤더나 상태 정보와는 다르다.
- Payload는 주로 클라이언트가 서버로 정보를 전송할 때(POST 요청 등) 또는 서버가 클라이언트로 응답할 때 사용된다.
주요 특징
- HTTP 요청(Request)에서의 Payload:
- 클라이언트가 서버로 데이터를 전송할 때, 그 데이터가
Payload
에 포함된다. - 주로
POST
,PUT
,PATCH
같은 요청 메서드에서 사용되며, 요청 본문(body)에 실려서 서버로 전달된다. - 예를 들어, 사용자가 폼을 제출하거나 파일을 업로드할 때 전송되는 정보가 Payload에 해당한다.
- 요청 헤더에는 Content-Type, Content-Length와 같은 정보가 포함되어 데이터의 형식과 크기를 설명한다.
- 클라이언트가 서버로 데이터를 전송할 때, 그 데이터가
- HTTP 응답(Response)에서의 Payload:
- 서버가 클라이언트로 데이터를 반환할 때 응답 본문에 포함되는 데이터가
Payload
이다. - 주로
GET
요청의 응답에서 웹 페이지의 HTML, JSON 데이터, 이미지 등 다양한 형태의 데이터를 반환할 수 있다. - Content-Type과 Content-Length가 헤더에 명시되어 데이터 형식과 크기를 설명한다.
- 서버가 클라이언트로 데이터를 반환할 때 응답 본문에 포함되는 데이터가
Payload vs. Body
- Body는 HTTP 요청 또는 응답의 본문 전체를 가리키는 개념임.
- Payload는 Body에 담긴 실제 의미 있는 데이터를 가리킴. 본문이 있지만 Payload가 없는 경우도 존재할 수 있는데, 예를 들어
HEAD
요청은 응답 본문이 없지만 헤더 정보는 포함됨.
Payload의 역할
- 데이터 전송: 클라이언트가 서버로, 또는 서버가 클라이언트로 필요한 데이터를 전달하는 용도로 사용된다.
- API 통신: JSON, XML과 같은 포맷을 사용하여 REST API와의 통신에서 중요한 역할을 한다. 클라이언트가 서버로 정보를 전달하거나, 서버가 클라이언트로 데이터를 응답할 때 사용된다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.