response 기본 객체는 request 기본 객체와 반대의 기능을 수행한다. request 기본 객체가 웹 브라우저에 전송한 요청 정보를 담고 있다면 response 기본 객체는 웹 브라우저에 보내는 응답 정보를 담고 있다.
response 기본 객체가 응답 정보와 관련해서 제공하는 기능은 다음과 같다.
이외의 몇 가지 기능이 더 있으나, JSP 페이지에서는 거의 사용되지 않는다.
response 기본 객체는 응답 정보에 헤더를 추가하는 기능을 제공한다. response 기본 객체가 제공하는 헤더 관련 메서드는 아래 표와 같다. 아래 표에서 메서드의 리턴 타입은 모두 void이다.
메서드 | 설명 |
addDateHeader(String name, long date) | name 헤더에 date를 추가한다. date는 1970년 1월 1일 이후 흘러간 시간을 1/1000초 단위로 나타낸다. |
addHeader(String name, String value) | name 헤더에 value를 값으로 추가한다. |
addIntHeader(String name, int value) | name 헤더에 정수 값 value를 추가한다. |
setDateHeader(String name, long date) | name 헤더의 값을 date로 지정한다. date는 1970년 1월 1일 이후 흘러간 시간을 1/1000초 단위로 나타낸다. |
setHeader(String name, String value) | name 헤더의 값을 value로 지정한다. |
setIntHeader(String name, int value) | name 헤더의 값을 정수 값 value로 지정한다. |
containsHeader(String name) | 이름이 name인 헤더를 포함하고 있을 경우 true를, 그렇지 않을 경우 false를 리턴한다. |
위의 표에서 add로 시작하는 메서드는 기존의 헤더에 새로운 값을 추가할 때 사용되며, set로 시작하는 메서드는 헤더의 값을 새로 지정할 때 사용된다.
응답 헤더를 직접 설정해야 하는 경우가 많진 않은데, 그 중 하나는 다음에 살펴볼 캐시와 관련된 것이다.
JSP를 비롯한 웹 어플리케이션을 개발하다 보면 새로운 내용을 DB에 추가했는데도 웹 브라우저에 출력되는 내용이 바뀌지 않는 경우가 있다. 웹 브라우저가 변경된 내용을 출력하지 않은 이유 중 하나는 웹 브라우저가 서버가 생성한 결과를 출력하지 않고 캐시에 저장된 데이터를 출력하기 때문이다.
캐시(Cache)란?
웹 브라우저가 WAS에 a.jsp의 실행을 요청하고 잠시 뒤에 한 번 더 a.jsp의 실행을 요청했다고 하자. 첫 번째 요청과 두 번째 요청 사이에 a.jsp가 출력한 결과에 차이가 없다면 웹 브라우저는 불필요하게 동일한 응답 결과를 두 번 요청한 셈이 된다. 캐시는 이렇게 동일한 데이터를 중복해서 로딩하지 않도록 할 때 사용한다. 웹 브라우저는 첫 번째 요청 시 응답 결과를 로컬 PC의 임시 보관소인 캐시에 저장한다. 이후, 동일한 URI에 대한 요청이 있으면 WAS에 접근하지 않고 로컬 PC에 저장된 응답 결과를 사용한다. 캐시에 보관된 데이터를 사용하는 경우, WAS에 접근하지 않기 때문에 훨씬 빠르게 응답 결과를 웹 브라우저에 출력할 수 있게 된다. 따라서 변경이 발생하지 않는 JSP의 응답 결과나 이미지, 정적인 HTML 등은 캐시에 보관함으로써 웹 브라우저의 응답 속도를 향상시킬 수 있다.
내용이 자주 바뀌지 않는 사이트는 웹 브라우저 캐시를 사용해서 보다 빠른 응답을 제공할 수 있다. 하지만, 게시판처럼 내용이 자주 변경되는 사이트는 웹 브라우저 캐시가 적용되면 사용자는 변경된 내용을 확인할 수 없게 된다. 예를 들어, 게시글 목록이 캐시된 경우, 내가 방금 등록한 게시글이 목록 화면에 보이지 않을 수 있다.
HTTP는 특수한 응답 헤더를 통해서 웹 브라우저가 응답 결과를 캐시할 것인지에 대한 여부를 설정할 수 있다. 응답 헤더와 관련된 헤더는 다음고 같다.
응답 헤더 | 설명 |
Cache-Control | HTTP 1.1 버전에서 지원하는 헤더로서, 이 헤더의 값을 "no-cache"로 지정하면 웹 브라우저는 응답 결과를 캐시하지 않는다. "no cache"로 설정하더라도 응답 내용을 캐시 저장소에 보관할 수 잇다. 예를 들어, "no-cache"를 설정했더라도, 웹 브라우저에 따라 뒤로가기 버튼을 클릭하면 캐시 저장소에 보관된 응답 내용을 사용하기도 한다. 응답 결과가 캐시 저장소 자체에 보관되지 않도록 하려면, 이 헤더에 "no-store"를 추가한다. |
Pragma | HTTP 1.0 버전에서 지원하는 헤더로서, 이 헤더의 값을 "no-cache"로 지정하면 웹 브라우저는 응답 결과를 캐시에 저장하지 않는다. |
Expires | HTTP 1.0 버전에서 지원하는 헤더로서, 응답 결과의 만료일을 지정한다. 만료일을 현재 시간보다 이전으로 설정함으로써 캐시에 보관되지 않도록 할 수 있다. |
최근 웹 브라우저는 HTTP 1.1 버전을 지원하기 때문에 Cache-Control 응답 헤더 값을 "no-cache"로 지정하면 응답 결과를 웹 브라우저가 캐시에 보관하지 않도록 할 수 있다. 하지만, HTTP 1.0 버전만 지원하는 웹 브라우저가 존재할 수 있기 때문에 다음 코드와 같이 Cache-Control 응답 헤더와 Pragma 응답 헤더를 모두 설정해주는 것이 좋다.
<%
response.setHeader("Cache-Control", "no-cache");
response.addHeader("Cache-Control", "no-store");
response.setHeader("Pragma", "No-Cache");
response.setDateHeader("Expires", "1L");
위 코드에서 Expires 응답 헤더의 값으로 long 타입 숫자를 설정했다. 이 값은 1970년 1월 1일 이후를 기준으로 1/1000초 단위로 값을 입력한다. 웹 브라우저가 응답을 캐시하지 않도록 하고 싶다면 이 값을 현재 시간보다 이전 값으로 지정하면 된다. 위 설정에 1L을 값으로 주었는데, 이는 만료일을 1970년 1월 1일 0시 0분 0.001초로 설정하는 것이므로 HTTP 1.0을 지원하는 웹 브라우저는 응답 결과를 캐시하지 않는다.
response 기본 객체에서 많이 사용되는 기능 중 하나는 리다이렉트 기능이다. 리다이렉트는 웹 서버가 웹 브라우저에게 다른 페이지로 이동하라고 응답하는 기능이다. 예를 들어, 사용자가 로그인에 성공한 후 메인 페이지로 자동으로 이동하는 사이트가 많은데 이렇게 특정 페이지를 실행한 후 지정한 페이지로 이동하길 원할 때 리다이렉트 기능을 사용한다.
위의 그림에서 보듯 리다이렉트 기능은 웹 서버 측에서 웹 브라우저에게 어떤 페이지로 이동하라고 지정하는 것이다. 그래서 위의 그림과 같이 리다이렉트를 지시한 JSP 페이지가 있을 경우 웹 브라우저는 실질적으로 요청을 두 번 하게 된다.
response 기본 객체는 다음의 메서드를 사용해서 웹 브라우저가 리다이렉트하도록 지시할 수 있다.
response.sendRedirect() 메서드는 주로 다음과 같은 형태로 사용된다.
<%@ page import = "java.sql.*" %>
...
//JSP 페이지에서 필요한 코드를 실행한다.
...
response.sendRedirect("이동할 페이지");
예를 들어, 로그인 후, 첫 페이지로 이동하길 원할 경우 아래 예제와 같이 sendRedirect() 메서드를 사용하면 된다.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String id = request.getParameter("memberId");
if(id != null && id.equals("madvirus")){
response.sendRedirect("/jsp01_war_exploded/index.jsp");
}else{
%>
<html>
<head>
<title>로그인에 실패</title>
</head>
<body>
잘못된 아이디입니다.
</body>
</html>
<%
}
%>
웹 브라우저를 실행한 후 memberId 파라미터 값을 madv라고 입력해보자.
실행 결과는 다음과 같다.
반면에 memberId 파라미터 값을 "madvirus"로 입력한 경우 index.jsp가 화면에 출력된다.
위의 예제 코드는 같은 서버 주소에 위치한 페이지로 리다이렉트했는데, 다른 서버 주소에 위치한 페이지로 이동하도록 지정할 수도 있다. 예를 들면 다음과 같다.
response.sendRedirect("http://javacan.tistory.com/entry/Event-Sourcing-PT");
웹 서버에 전송할 파라미터 값은 알맞게 인코딩해야 한다. 즉, 알파벳과 숫자 그리고 몇몇 기호를 제외한 나머지 글자들을 URL에 포함시키려면 인코딩을 해주어야 한다. response.sendRedirect() 메서드를 사용하는 경우에도 마찬가지로 인코딩한 쿼리 문자열을 상용해야 한다.
이 기능을 제공해주는 클래스는 java.net.URLEncoding 클래스이다. URLEncoding.encode() 메서드를 사용하면 파라미터 값으로 사용될 문자열을 지정한 캐릭터 셋으로 인코딩할 수 있다. 예제 코드는 다음과 같다.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.net.URLEncoder" %>
<%
String value="자바";
String encodedValue = URLEncoder.encode(value, "utf-8");
response.sendRedirect("/jsp01_war_exploded/index.jsp?name="+encodedValue);
%>
참고