您的位置:首页 > 编程语言 > Java开发

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

2014-11-13 21:23 495 查看
问题:

在处理用户提交的内容时,可能会有一些特殊字符,显示这些内容时可能导致界面混乱;

在用户评论中会有一些污言秽语,需要进行净化处理;

我不想修改原有的程序实现字符替换,这该如何实现?

解决方案:

可以用过滤器解决问题,程序需要用到包装类,包装类是一种装饰器模式:不改变原有的类,为其添加新的功能;

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<len;i++){
char c= str.charAt(i);
switch(c){
case ' ':sb.append(" ");break;
case '\n':sb.append("<br/>");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<String,String> map = new HashMap<String,String>();
@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<String> 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

主要代码:

<html>
<head>
<title>留言板</title>
</head>
<style>
div {
margin:5px;

}
div.left {
float :left;
width:30%;
}
div.right{
float:left;
width:30%;
}
</style>
<body>
<div class="left">
<form action="say.jsp?action=submit" method="post">
用户名:<input name ="username" type="text" /><br/>
主题:<input name ="topic" type="text" /><br/>
内容:<textarea name ="content" row="10" cols="40"></textarea><br/>

<input type = "submit"  value="提交" />
</form>
</div>
<div class="right" >
用户名:<input name ="username" type="text" / value="${leavelMassage.username }"><br/>
主题:<input name ="topic" type="text"  value="${leavelMassage.topic }" /><br/>
内容:<textarea name ="content" row="10" cols="40"  >${leavelMassage.content}</textarea><br/>
</div>
</body>
</html><%out.flush(); %>


------------------------------

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

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

<filter>
<filter-name>GuestbookFilter</filter-name>
<filter-class>Filter.GuestbookFilter</filter-class>
<init-param>
<param-name>word_file</param-name>
<param-value>/WEB-INF/word.txt</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>GuestbookFilter</filter-name>
<url-pattern>/say.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>


-----------------------

额外代码:

1.WebUtils.requestParam2Bean(reqWrapper,message);

public static void requestParam2Bean(HttpServletRequest request,
LeavelMessage message) {
Enumeration<String> 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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: