您的位置:首页 > Web前端 > JavaScript

[Servlet&JSP] 封装器的使用

2015-12-15 20:19 495 查看
过滤器可以在执行Servlet的service()方法前后,进行前置和后置处理。但是有些信息无法更改,例如请求参数。使用请求封装器及相应封装器,将容器产生的请求与相应对象加以封装,可以针对某个请求信息或响应进行加工处理。

请求封装器

HttpServletRequestWrapper实现了HttpServletRequest接口,以下范例通过继承HttpServletRequestWrapper实现了一个请求封装器,可以请请求参数中的角括号替换为替代字符。

import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class CharacterRequestWrapper extends HttpServletRequestWrapper{
private Map<String, String> escapeMap;

public CharacterRequestWrapper(HttpServletRequest request,
Map<String, String> escapeMap) {
super(request); //封装传入的请求对象
this.escapeMap = escapeMap;
}

@Override
public String getParameter(String name) { //重写getParameter()方法
return doEscape(this.getRequest().getParameter(name));
}

private String doEscape(String parameter) {
if (parameter == null) {
return null;
}
String result = parameter;
Iterator<String> it = escapeMap.keySet().iterator();
while(it.hasNext()) {
String origin = it.next();
String escape = escapeMap.get(origin);
result = result.replaceAll(origin, escape);
}

return result;
}
}


可以使用这个请求封装器搭配过滤器,以进行字符过滤的服务。例如:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class CharacterFilter implements Filter {
private Map<String, String> escapeMap;

@Override
public void init(FilterConfig filterConfig) throws ServletException {
BufferedReader reader = null;
try {
String escapeListFile = filterConfig.getInitParameter("ESCAPE_LIST");
reader = new BufferedReader(new InputStreamReader(
filterConfig.getServletContext().getResourceAsStream(escapeListFile)));

String input = null;
escapeMap = new HashMap<String, String>();
while ((input = reader.readLine()) != null) {
String[] token = input.split("\t");
escapeMap.put(token[0], token[1]);
}
} catch (IOException ex) {
Logger.getLogger(CharacterFilter.class.getName())
.log(Level.SEVERE, null, ex);
} finally {
try {
reader.close();
} catch (IOException ex) {
Logger.getLogger(CharacterFilter.class.getName())
.log(Level.SEVERE, null, ex);
}
}
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//将原请求对象封装到CharacterRequestWrapper中
HttpServletRequest requestWrapper =
new CharacterRequestWrapper((HttpServletRequest)request, escapeMap);
//将CharacterRequestWrapper对象当做请求参数传入doFilter()
chain.doFilter(requestWrapper, response);
}

@Override
public void destroy() {
// TODO Auto-generated method stub
}
}


响应封装器

如果想要对响应的内容进行压缩处理等,可以在响应封装器部分继承HttpServletResponseWrapper类来对HttpServletResponse对象进行封装。

如要对浏览器进行输出响应,必须通过getWriter()取得PrintWriter,或是通过getOutputStream()取得ServletOutputStream。所以针对压缩输出的请求,主要就是继承HttpServletResponseWrapper之后,通过重写这两个方法来达成的。

在这里压缩功能将采用GZIP格式,这是浏览器可以接受的压缩格式,可以使用GZIPOutputStream类来实现。由于getWriter()的PrintWriter在创建时也是必须要用到ServletOutputStream,所以这里首先扩展ServletOutputStream类,让它具有压缩功能。

GzipServletOutputStream.java:

package club.chuxing;

import java.io.IOException;
import java.util.zip.GZIPOutputStream;

import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;

public class GZipServletOutputStream extends ServletOutputStream{
private GZIPOutputStream gzipOutputStream;

public GZipServletOutputStream(ServletOutputStream servletOutputStream)
throws IOException {
this.gzipOutputStream = new GZIPOutputStream(servletOutputStream);
}

public void write(int b) throws IOException {
//输出时通过GZIPOutputSteam的write()压缩输出
gzipOutputStream.write(b);
}

public GZIPOutputStream getGzipOutputStream() {
return gzipOutputStream;
}

@Override
public boolean isReady() {
// TODO Auto-generated method stub
return false;
}

@Override
public void setWriteListener(WriteListener listener) {
// TODO Auto-generated method stub
}
}


CompressionResponseWrapper.java:

package club.chuxing;

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 gzServletOutputStream;
private PrintWriter printWriter;
public CompressionResponseWrapper(HttpServletResponse resp) {
super(resp);
}

@Override
public ServletOutputStream getOutputStream() throws IOException {
if (printWriter != null) {
throw new IllegalStateException();
}
if (gzServletOutputStream == null) {
gzServletOutputStream = new GZipServletOutputStream(
getResponse().getOutputStream());
}

return gzServletOutputStream;
}

@Override
public PrintWriter getWriter() throws IOException {
if (gzServletOutputStream != null) {
throw new IllegalStateException();
}
if (printWriter == null) {
gzServletOutputStream = new GZipServletOutputStream(
getResponse().getOutputStream());
OutputStreamWriter osw = new OutputStreamWriter(
gzServletOutputStream, getResponse().getCharacterEncoding());
printWriter = new PrintWriter(osw);
}

return printWriter;
}

@Override
public void setContentLength(int len) {

}

public GZIPOutputStream getGZIPOutputStream() {
if (this.gzServletOutputStream == null) {
return null;
}
return this.gzServletOutputStream.getGzipOutputStream();
}
}


CompressionFilter.java(压缩过滤器):

package club.chuxing;

import java.io.IOException;
import java.util.zip.GZIPOutputStream;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
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 {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;

String encodings = req.getHeader("accept-encoding");
if ((encodings != null) && encodings.indexOf("gzip") > -1) {
//建立响应封装
CompressionResponseWrapper responseWrapper =
new CompressionResponseWrapper(res);
//设置响应内容编码为gzip格式
responseWrapper.setHeader("content-encoding", "gzip");

chain.doFilter(request, responseWrapper);

GZIPOutputStream gzipOutputStream = responseWrapper.getGZIPOutputStream();
if (gzipOutputStream != null) {
//调用GZIPOutputStream的finish()方法完成压缩输出
gzipOutputStream.finish();
}
} else {
chain.doFilter(request, response);
}
}

@Override
public void destroy() {
// TODO Auto-generated method stub
}
}


最后,将过滤器设置在web.xml中,响应就会是压缩过后的内容。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: