728x90
반응형
필터를 통해 서블릿이 실행되기 전에 특정 액션을 하게 만들 수 있다고 했다.
그런데 서블릿이 실행되고 나서 특정 액션을 하게 만들려면 어떻게 해야 할까?
간단하게 생각해 보면 필터의 doFilter()메소드 안에 있는 chain.doFilter(request, response) 를 마치고 나서 작업하면 될 것 같다.
하지만, 서블릿에 넘겨주는 response 객체를 서블릿이 사용하게 되면, 필터를 거치지 않고 바로 클라이언트로 response 하게 된다.
따라서 doFilter를 통해 response를 넘길 때 새로운 응답 객체(HttpServletResponse를 구현한 객체)를 만들어 넘기는 방법을 써야 한다.
하지만, HttpServletResponse는 간단한 클래스가 아니므로, 썬에서 구현해 둔 다음 4가지를 이용하면 된다.
위 4가지 클래스를 상속한 후 필요한 메소드만 재정의 해서 사용하면 된다.
response를 할 때 내용을 압축해서 보내주는 예제를 통해서 Response Filter를 어떻게 사용하는지 확인해 볼 수 있다.
압축과 관련된 부분은 다루고자 하는 범위를 넘어서는 듯 하며, Response를 어떻게 변형하여 넘겨주는지를 확인해 보면 된다.
CompressionResponseWrapper wrappedResp = new CompressionResponseWrapper(response); 와 같이 HttpServletResponseWrapper를 확장한 클래스를 통해 만들어진 랩퍼 클래스로부터 변경된 response 객체를 리턴받아 사용한다.
response 객체는 super(response);와 같이 상위 클래스에서 알아서 처리하도록 하며, 나머지 압축 관련 부분만 처리해 준다.
그런데 서블릿이 실행되고 나서 특정 액션을 하게 만들려면 어떻게 해야 할까?
간단하게 생각해 보면 필터의 doFilter()메소드 안에 있는 chain.doFilter(request, response) 를 마치고 나서 작업하면 될 것 같다.
하지만, 서블릿에 넘겨주는 response 객체를 서블릿이 사용하게 되면, 필터를 거치지 않고 바로 클라이언트로 response 하게 된다.
따라서 doFilter를 통해 response를 넘길 때 새로운 응답 객체(HttpServletResponse를 구현한 객체)를 만들어 넘기는 방법을 써야 한다.
하지만, HttpServletResponse는 간단한 클래스가 아니므로, 썬에서 구현해 둔 다음 4가지를 이용하면 된다.
ServletRequestWrapper
HttpServletRequestWrapper
ServletResponseWrapper
HttpServletResponseWrapper
HttpServletRequestWrapper
ServletResponseWrapper
HttpServletResponseWrapper
위 4가지 클래스를 상속한 후 필요한 메소드만 재정의 해서 사용하면 된다.
response를 할 때 내용을 압축해서 보내주는 예제를 통해서 Response Filter를 어떻게 사용하는지 확인해 볼 수 있다.
package com.example.web;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CompressionFilter implements Filter {
private ServletContext ctx;
private FilterConfig cfg;
@Override
public void init(FilterConfig cfg) throws ServletException {
// TODO Auto-generated method stub
this.cfg = cfg;
ctx = cfg.getServletContext();
ctx.log(cfg.getFilterName() + " initialized.");
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain fc) throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String valid_encodings = request.getHeader("Accept-Encoding");
if(valid_encodings.indexOf("gzip") > -1) {
CompressionResponseWrapper wrappedResp
= new CompressionResponseWrapper(response);
wrappedResp.setHeader("Content-Encoding", "gzip");
ctx.log("before chain...");
fc.doFilter(request, wrappedResp);
GZIPOutputStream gzos = wrappedResp.getGZIPOutputStream();
gzos.finish();
ctx.log(cfg.getFilterName() + ": finished the request.");
} else {
ctx.log(cfg.getFilterName() + ": no encoding performed.");
}
}
@Override
public void destroy() {
// TODO Auto-generated method stub
cfg = null;
ctx = null;
}
}
import java.io.IOException;
import java.util.zip.GZIPOutputStream;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CompressionFilter implements Filter {
private ServletContext ctx;
private FilterConfig cfg;
@Override
public void init(FilterConfig cfg) throws ServletException {
// TODO Auto-generated method stub
this.cfg = cfg;
ctx = cfg.getServletContext();
ctx.log(cfg.getFilterName() + " initialized.");
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain fc) throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String valid_encodings = request.getHeader("Accept-Encoding");
if(valid_encodings.indexOf("gzip") > -1) {
CompressionResponseWrapper wrappedResp
= new CompressionResponseWrapper(response);
wrappedResp.setHeader("Content-Encoding", "gzip");
ctx.log("before chain...");
fc.doFilter(request, wrappedResp);
GZIPOutputStream gzos = wrappedResp.getGZIPOutputStream();
gzos.finish();
ctx.log(cfg.getFilterName() + ": finished the request.");
} else {
ctx.log(cfg.getFilterName() + ": no encoding performed.");
}
}
@Override
public void destroy() {
// TODO Auto-generated method stub
cfg = null;
ctx = null;
}
}
package com.example.web;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class CompressionResponseWrapper extends HttpServletResponseWrapper {
private GZIPServletOutputStream servletGzipOS = null;
private PrintWriter pw = null;
public CompressionResponseWrapper(HttpServletResponse response) {
super(response);
}
public void setContentLength(int len) {}
public GZIPOutputStream getGZIPOutputStream() {
return this.servletGzipOS.internalGzipOS;
}
private Object streamUsed = null;
public ServletOutputStream getOutputStream() throws IOException {
if((streamUsed != null) && (streamUsed != pw)) {
throw new IllegalStateException();
}
if(servletGzipOS == null) {
servletGzipOS = new GZIPServletOutputStream(getResponse().getOutputStream());
streamUsed = servletGzipOS;
}
return servletGzipOS;
}
public PrintWriter getWriter() throws IOException {
if((streamUsed != null) && (streamUsed != servletGzipOS)) {
throw new IllegalStateException();
}
if(pw == null) {
servletGzipOS = new GZIPServletOutputStream(getResponse().getOutputStream());
OutputStreamWriter osw = new OutputStreamWriter(servletGzipOS, getResponse().getCharacterEncoding());
pw = new PrintWriter(osw);
streamUsed = pw;
}
return pw;
}
}
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class CompressionResponseWrapper extends HttpServletResponseWrapper {
private GZIPServletOutputStream servletGzipOS = null;
private PrintWriter pw = null;
public CompressionResponseWrapper(HttpServletResponse response) {
super(response);
}
public void setContentLength(int len) {}
public GZIPOutputStream getGZIPOutputStream() {
return this.servletGzipOS.internalGzipOS;
}
private Object streamUsed = null;
public ServletOutputStream getOutputStream() throws IOException {
if((streamUsed != null) && (streamUsed != pw)) {
throw new IllegalStateException();
}
if(servletGzipOS == null) {
servletGzipOS = new GZIPServletOutputStream(getResponse().getOutputStream());
streamUsed = servletGzipOS;
}
return servletGzipOS;
}
public PrintWriter getWriter() throws IOException {
if((streamUsed != null) && (streamUsed != servletGzipOS)) {
throw new IllegalStateException();
}
if(pw == null) {
servletGzipOS = new GZIPServletOutputStream(getResponse().getOutputStream());
OutputStreamWriter osw = new OutputStreamWriter(servletGzipOS, getResponse().getCharacterEncoding());
pw = new PrintWriter(osw);
streamUsed = pw;
}
return pw;
}
}
package com.example.web;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletOutputStream;
public class GZIPServletOutputStream extends ServletOutputStream {
GZIPOutputStream internalGzipOS;
GZIPServletOutputStream(ServletOutputStream sos) throws IOException {
// TODO Auto-generated constructor stub
this.internalGzipOS = new GZIPOutputStream(sos);
}
@Override
public void write(int param) throws IOException {
// TODO Auto-generated method stub
internalGzipOS.write(param);
}
}
import java.io.IOException;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletOutputStream;
public class GZIPServletOutputStream extends ServletOutputStream {
GZIPOutputStream internalGzipOS;
GZIPServletOutputStream(ServletOutputStream sos) throws IOException {
// TODO Auto-generated constructor stub
this.internalGzipOS = new GZIPOutputStream(sos);
}
@Override
public void write(int param) throws IOException {
// TODO Auto-generated method stub
internalGzipOS.write(param);
}
}
압축과 관련된 부분은 다루고자 하는 범위를 넘어서는 듯 하며, Response를 어떻게 변형하여 넘겨주는지를 확인해 보면 된다.
CompressionResponseWrapper wrappedResp = new CompressionResponseWrapper(response); 와 같이 HttpServletResponseWrapper를 확장한 클래스를 통해 만들어진 랩퍼 클래스로부터 변경된 response 객체를 리턴받아 사용한다.
response 객체는 super(response);와 같이 상위 클래스에서 알아서 처리하도록 하며, 나머지 압축 관련 부분만 처리해 준다.
728x90
반응형
'Java > Servlet & JSP' 카테고리의 다른 글
필터 - REQUEST (1) | 2009.04.16 |
---|---|
웹 애플리케이션 보안 (4) | 2009.04.10 |
웹 애플리케이션 배포하기 (0) | 2009.04.07 |
부모 자식 태그간의 통신 (0) | 2009.03.26 |
클래식 커스텀 태그 (0) | 2009.03.26 |