Servlet 03: 클라이언트로 출력하기
비트캠프 서초본원 엄진영 강사님의 수업을 듣고 정리했습니다.
Servlet 03: 클라이언트로 출력하기
1. 클라이언트로 출력하기
- 출력 스트림을 꺼내기 전에 출력할 때 사용할 문자표(charset)를 지정하지 않으면 리턴 받은 출력 스트림은 기본 문자표 ISO-8859-1을 사용한다.
- 즉 자바의 유니코드 문자를 ISO-8859-1 문자표에 따라 변환하여 출력한다.
- 자바(Unicode2;UTF-16) ⇒ 출력문자(ASCII)
- 영어 유니코드 문자는 ISO-8859-1 문자표에 있기 때문에 제대로 변환된다.
- 한글이나 한자같은 유니코드 문자는 ISO-8859-1 문자표에 없기 때문에 없다는 의미에서 ‘?’가 출력된다.
@WebServlet("/ex03/s1") // http://localhost:8080/bitcamp-java-web/ex03/s1
public class Servlet01 extends GenericServlet {
private static final long serialVersionUID = 1L;
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
PrintWriter out = res.getWriter();
out.println("Hello!");
out.println("안녕하세요!");
out.println("こんにちは");
out.println("您好");
out.println("مع السلامة؛ إلى اللقاء!");
}
}

2. 한글 깨짐 현상 처리
- 출력 스트림을 꺼내기 전에 출력 스트림이 사용할 문자표(charset)를 지정하라.
- 반드시 출력 스트림을 얻기 전에 설정해야 한다.
- res.setContentType(“MIME Type;charset=문자표이름”);
- 한글이나 일본 문자, 중국 문자, 아랍 문자는
UTF-8문자표에 정의되어 있다.
- MIME Type : Multi-purpose Internet Mail Extension
- 콘텐트의 형식을 표현
- 콘텐트타입/상세타입
- 예) text/plain, text/css, text/html 등
- 웹 브라우저는 콘텐트를 출력할 때 서버가 알려준 MIME 타입을 보고 어떤 방식으로 출력할 지 결정한다.
- MIME 타입에 오류가 있으면, 원하는 결과가 출력되지 않고 다운로드 화면이 출력된다.
@WebServlet("/ex03/s2")
public class Servlet02 extends GenericServlet {
private static final long serialVersionUID = 1L;
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain;charset=UTF-8"); // UCS2(UTF-16) ==> UTF-8
PrintWriter out = res.getWriter();
out.println("Hello!");
out.println("안녕하세요!");
out.println("こんにちは");
out.println("您好");
out.println("مع السلامة؛ إلى اللقاء!");
}
}

3. HTML 출력하기
- HTML 출력할 때 MIME 타입에 HTML을 지정하지 않으면 웹 브라우저는 일반 텍스트로 간주하여 출력한다.
@WebServlet("/ex03/s3")
public class Servlet03 extends GenericServlet {
private static final long serialVersionUID = 1L;
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
res.setContentType("text/html;charset=UTF-8"); // UTF-16 ==> UTF-8
PrintWriter out = res.getWriter();
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head><title>servlet03</title></head>");
out.println("<body><h1>안녕하세요</h1></body>");
out.println("</html>");
}
}

4. 바이너리 데이터 출력하기
@WebServlet("/ex03/s4")
public class Servlet04 extends GenericServlet {
private static final long serialVersionUID = 1L;
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
// photo.jpeg 파일의 실제 경로 알아내기
// 1) 서블릿의 환경 정보를 다루는 객체를 먼저 얻는다.
ServletContext ctx = req.getServletContext();
// 2) ServletContext를 통해 웹 자원의 실제 경로를 알아낸다.
// => getRealPath(현재 웹 애플리케이션의 파일 경로) : 실제 전체 경로를 리턴한다.
String path = ctx.getRealPath("/photo.jpeg");
System.out.println(path);
FileInputStream in = new FileInputStream(path);
// 바이너리를 출력할 때 MIME 타입을 지정해야 웹 브라우저가 제대로 출력할 수 있다.
// => 웹 브라우저가 모르는 형식을 지정하면 웹 브라우저는 처리하지 못하기 때문에
// 그냥 다운로드 대화상자를 띄운다.
res.setContentType("image/jpeg");
BufferedOutputStream out = new BufferedOutputStream(res.getOutputStream());
int b;
while ((b = in.read()) != -1) {
out.write(b);
}
out.flush(); // 버퍼 데코레이터에 보관된 데이터를 클라이언트로 방출한다.
out.close();
in.close();
}
}
