javaweb-使用过滤器实现文本净化和字符转义

问题:
在处理用户提交的内容时,可能会有一些特殊字符,显示这些内容时可能导致界面混乱;
在用户评论中会有一些污言秽语,需要进行净化处理;
我不想修改原有的程序实现字符替换,这该如何实现?

解决方案:
可以用过滤器解决问题,程序需要用到包装类,包装类是一种装饰器模式:不改变原有的类,为其添加新的功能;
servlet提供了4个包装类
ServletRequestWrapper
HttpServletRequestWrapper
HttpServletResponseWrapper
HttpServletResponseWrapper

我们可以通过重写request的方法getParameter() 获取请求内容,并实现字符转义
为了净化用户评论等信息,需要获取这些响应内容,由于响应内容是通过字符(PrintWriter) 或字节(ServletOutputStream)流对象传输到客户端的,而字符或者字节流对象
是通过reponse的getWriter 或者getOutputStream 方法获取的.
于是,我们可以重写这两个方法,并且使响应内容写入ByteArrayOutputStream中,再通过它的方法getByteArray 得到响应内容.具体方法见java代码;
//
程序使用文件WebRoot/WEB-INF/word.txt 保存替换文本内容:
--------------------------------------------------
我靠=我*
fuck=****
他妈的=他**
--------------------------------------------------

1.编写类 ByteArrayServletOutputStream

package Filter;

// 用这个类替换ServletOutputStream
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javax.servlet.ServletOutputStream;
public class ByteArrayServletOutputStream extends ServletOutputStream {
	ByteArrayOutputStream baos;
	public void write(int b) throws IOException {
		
		baos.write(b);
	}
	public ByteArrayServletOutputStream(ByteArrayOutputStream baos) {
		this.baos = baos;
	}
}

2.编写 MyRequestWrapper

package Filter;

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

public class MyRequestWrapper extends HttpServletRequestWrapper {
	public MyRequestWrapper(HttpServletRequest request) {
		super(request);
	}
	
	@Override
	public String getParameter(String name) {
		String value = super.getParameter(name);
		if(value!=null){
			return toHtml(value.trim());
		}else{
			return null;
		}
	}
	
	//转化特殊字符
	public String toHtml(String str){
		if(str==null){
			return null;
		}
		StringBuffer sb = new StringBuffer();
		int len = str.length();
		for(int i=0;i");break;
			case '\r':break;
			case '\'':sb.append("'");break;
			case '<':sb.append("<");break;
			case '>':sb.append(">");break;
			case '&':sb.append("&");break;
			case '"':sb.append(""");break;
			case '\\':sb.append("\");break;
			default: sb.append(c);break;
			}
		}
		return sb.toString();
	}
}

3.编写 MyResponseWrapper

package Filter;

import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;


public class MyResponseWrapper extends HttpServletResponseWrapper {
	private ByteArrayOutputStream baos;
	private ByteArrayServletOutputStream basos;
	private PrintWriter pw;
	public MyResponseWrapper(HttpServletResponse response) {
		super(response);
		baos = new ByteArrayOutputStream();
		basos = new ByteArrayServletOutputStream(baos);
		
		pw = new PrintWriter(baos);
	}
	public PrintWriter getWriter(){ return pw;}
	
	public ServletOutputStream getOutputStream(){ return basos; }
	
	public byte[] toByteArray(){ return baos.toByteArray(); }
}

4.编写过滤器 GuestbookFilter

package Filter;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

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;

import utils.WebUtils;
import domain.LeavelMessage;

public class GuestbookFilter implements Filter {

	private static final String WORD_FILE="word_file";
	HashMap map = new HashMap();
	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		String action = request.getParameter("action");
		if(action==null||action.equals("")){
			chain.doFilter(request, response);
			return ;
		}
		
		HttpServletRequest httpReq = (HttpServletRequest) request;
		HttpServletResponse httpRes = (HttpServletResponse) response;
		
		MyRequestWrapper reqWrapper = new MyRequestWrapper(httpReq);
		MyResponseWrapper resWrapper = new MyResponseWrapper(httpRes);
		
		//LeavelMessage 和 WebUtils 见下方额外代码
		LeavelMessage message =new LeavelMessage();
		WebUtils.requestParam2Bean(reqWrapper,message);
		message.setDate(new Date());
		reqWrapper.getSession().setAttribute("leavelMassage",message);
		
		chain.doFilter(reqWrapper, resWrapper);
		
		String content =new String(resWrapper.toByteArray());
		String result = replaceText(content);
		httpRes.setContentType("text/html;charset=utf-8");
		PrintWriter out = httpRes.getWriter();
		out.println(result);

	}

	private String replaceText(String content) {
		if(content==null)return null;
		StringBuffer sb = new StringBuffer(content);
		Set keys = map.keySet();
		Iterator it  = keys.iterator();
		while(it.hasNext()){
			String key = (String)it.next();
			int index = content.indexOf(key);
			if(index!=-1){
				sb.replace(index, index+key.length(), map.get(key));
			}
		}
		return sb.toString();
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		String configPath = filterConfig.getInitParameter(WORD_FILE);
		ServletContext sc = filterConfig.getServletContext();
		String filePath = sc.getRealPath(configPath);
		
		try {
			FileReader fr = new FileReader(filePath);
			BufferedReader bfr = new BufferedReader(fr);
			
			String line;
			while((line=bfr.readLine())!=null){
				String[] strTemp = line.split("=");
				map.put(strTemp[0], strTemp[1]);
			}
		} catch (Exception e) {
			throw new ServletException("读取过滤文件信息出错!");
		}
	}

}

5.测试页面 say.jsp
主要代码:


  
    留言板
  
  
  
  	
用户名:
主题:
内容:
用户名:
主题:
内容:
<%out.flush(); %>

------------------------------
注意:一定要在最后写上 <%out.flush(); %> ,否则方法toByteArray无法获得内容

6.在web.xml中配置过滤器


	GuestbookFilter
	Filter.GuestbookFilter
	
		word_file
		/WEB-INF/word.txt
	


	GuestbookFilter
	/say.jsp
	REQUEST
	FORWARD

-----------------------
额外代码:
1.WebUtils.requestParam2Bean(reqWrapper,message);

public static void requestParam2Bean(HttpServletRequest request,
			LeavelMessage message) {
		Enumeration e = request.getParameterNames();
		while (e.hasMoreElements()) {
			String name = e.nextElement();
			String value = request.getParameter(name);
			try {
				value = new String(value.getBytes("ISO-8859-1"),"UTF-8");
			} catch (UnsupportedEncodingException e1) {
			}
			if(name.equals("username")) message.setUsername(value);
			if(name.equals("topic")) message.setTopic(value);
			if(name.equals("content")) message.setContent(value);
		}
	}
2.LeavelMessage

package domain;
import java.util.Date;
//留言板对象
public class LeavelMessage {
    //用户名
    //留言时间 yyyy-MM-dd HH:mm:ss
    //用户ip xxx.xxx.xxx.xxx
    //主题
    //内容
    private String username;
    private Date date;
    private String IP;
    private String topic;
    private String content;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date = date;
    }
    public String getIP() {
        return IP;
    }
    public void setIP(String iP) {
        IP = iP;
    }
    public String getTopic() {
        return topic;
    }
    public void setTopic(String topic) {
        this.topic = topic;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
}



你可能感兴趣的:(学习日志)