헤더의 종류는 전통적으로 4가지 카테고리로 구분된다.
1. General header : 요청 및 응답 모두 적용되지만 body 와는 관련 없는 헤더
2. Request header : fetch 될 리소스나 클라이언트 자체에 대한 상세 정보를 포함하는 헤더
3. Response header : 위치나 서버 자체와 같은 응답에 대한 부가적인 정보를 갖는 헤더
4. Entity header : 컨텐츠 길이나 엔티티 body 에 대한 상세 정보를 포함하는 헤더
출력 시 나오는 헤더는 요청헤더(Request header) 이다.
package com.ohgiraffers.section01.headers;
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;
@WebServlet("/headers")
public class RequestHeaderPrintServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Enumeration<String> headerNames = req.getHeaderNames();
while (headerNames.hasMoreElements()) {
System.out.println(headerNames.nextElement());
}
// accept : 요청을 보낼 때 서버에게 요청할 응답 타입 명시
System.out.println("accept : " + req.getHeader("accept"));
// text/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
// accept-encoding : 응답 시 원하는 인코딩 방식
System.out.println("accpet-encoding : " + req.getHeader("accpet-encoding"));
// null
// accept-language : 응답 시 원하는 언어
System.out.println("accept-language : " + req.getHeader("accept-language"));
// ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
// connection : HTTP 통신이 완료된 후에 네트워크 접속을 유지할지 결정(기본값 - keep-alive = 연결유지)
System.out.println("connection : " + req.getHeader("connection"));
// keep-alive
// host : 서버의 도메인 네임과 현재 Listening 중인 TCP 포트 지정
System.out.println("host : " + req.getHeader("host"));
// localhost:8080
// referer : 이 페이지 이전에 대한 주소
System.out.println("referer : " + req.getHeader("referer"));
// http://localhost:8080/
// sec-fetch-dest : 요청 대상
System.out.println("sec-fetch-dest : " + req.getHeader("sec-fetch-dest"));
// document
// sec-fetch-mode : 요청 모드
System.out.println("sec-fetch-mode : " + req.getHeader("sec-fetch-mode"));
// navigate
// sec-fetch-user : 사용자가 시작한 요청일 때만 보내짐
System.out.println("sec-fetch-user : " + req.getHeader("sec-fetch-user"));
// ?1
// cache-control : 캐시 설정
System.out.println("cache-control : " + req.getHeader("cache-control"));
// null
// user-agent : 현재 사용자가 어떤 클라이언트를 이용해 보낸 요청인지 명시
System.out.println("user-agent : " + req.getHeader("user-agent"));
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36
}
}
서블릿이 하는 역할은 크게 3가지 이다.
1. 요청 받기 - HTTP method get/post 등 요청에 따라
parameter 로 전달받은 데이터를 꺼내올 수 있다.
2. 비즈니스 로직 처리 - DB 접속과 CRUD 에 대한 로직 처리
3. 응답하기 - 문자열로 동적인 웹페이지를 만들어 내보낸다.
package com.ohgiraffers.section01.response;
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.io.PrintWriter;
@WebServlet("/response")
public class ResponseTestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 문자열을 이용해 사용자에게 내보낼 페이지를 작성한다.
StringBuilder responseBuilder = new StringBuilder();
responseBuilder.append("<!DOCTYPE html>\n")
.append("<html>\n")
.append("<head>\n")
.append("</head>\n")
.append("<body>\n")
.append("<h1>안녕 servlet response</h1>\n")
.append("</body>\n")
.append("</html>");
// 브라우저로 내보낼 데이터의 타입을 설정
// 기본적으로 content-type의 기본값은 null 이다.
System.out.println("default response type : " + resp.getContentType());
// text/plain 으로 설정하면 html 태그를 단순 문자열로 인식한다.
// resp.setContentType("text/html");
// 브라우저로 내보낼 데이터의 인코딩 방식을 설정
// 별도로 인코딩을 지정해 주지 않으면 기본 설정된 방식을 따른다.(UTF-8)
System.out.println("default response encoding : " + resp.getCharacterEncoding());
// response.setCharacterEncoding("UTF-8");
// 두 설정을 한 번에 할 수 있다.
resp.setContentType("text/html; charset=UTF-8");
// 서버가 클라이언트에게 보낼 출력용 클래스
// 이 객체를 사용해 클라이언트로 데이터를 전송할 수 있다.
// 사용자 브라우저에 응답하기 위해서는 HttpServletResponse 의
// getWriter() method 로 PrintWriter 인스턴스를 반환받는다.
PrintWriter out = resp.getWriter();
// 데이터를 출력한다.
out.print(responseBuilder);
// 버퍼 - 데이터를 임시로 저장하는 공간입니다.
// 버퍼에 잔류한 데이터를 강제로 밀어넣는다.
// 버퍼에 남아 있는 데이터를 강제로 클라이언트에게 전송
out.flush();
// 닫아준다.
out.close();
}
}
package com.ohgiraffers.section02.headers;
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.io.PrintWriter;
import java.util.Collection;
import java.util.Iterator;
@WebServlet("/headers")
public class ResponseHeaderPrintServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html; charset=UTF-8");
PrintWriter out = resp.getWriter();
long currentTime = System.currentTimeMillis();
// currentTimeMillis() 함수는 1970년 1월 1일 0시를 기준으로 현재까지 경과한 시간을 1000분의 1초(밀리초)로 반환한다.
out.print("<h1>" + currentTime + "</h1>");
out.close();
Collection<String> responseHeaders = resp.getHeaderNames();
Iterator<String> iter = responseHeaders.iterator();
while(iter.hasNext()) {
String headerName = iter.next();
System.out.println(headerName + " : " + resp.getHeader(headerName));
/*
Content-Type : text/html;charset=UTF-8
Content-Length : 22
Date : Thu, 17 Oct 2024 08:41:39 GMT
Keep-Alive : timeout=20
Connection : keep-alive
* */
}
}
}
package com.ohgiraffers.section03.status;
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("/status")
public class StatusCodeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 특정 상황에 에러를 만들어 보내준다.
// resp.sendError(404, "없는 페이지 입니다. 경로를 확인 해주세요."); // sendError(에러코드, 메시지)
// 404 : 클라이언트의 잘못된 요청으로 나타난 에러
resp.sendError(500, "서버 내부 오류입니다. 서버 오류는 개발자의 잘못이고, 개발자는 여러분입니다.");
// 500 : 서버 에러
}
}