Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码、做一些业务逻辑判断等。其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对请求或响应(Request、Response)统一设置编码,简化操作;同时还可进行逻辑判断,如用户是否已经登陆、有没有权限访问该页面等等工作。它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁。
一、Filter在页面编码的应用
private FilterConfig filterConfig;
private String defaultCharSet = "UTF-8";
String charSet =null;
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
charSet = filterConfig.getInitParameter("charSet");
if(charSet == null){
charSet = defaultCharSet;
}
//1.解决post提交 的乱码
request.setCharacterEncoding(charSet);
response.setCharacterEncoding(charSet);
response.setContentType("text/html;charset="+charSet);
chain.doFilter(new MyRequest(request), response);
}
class MyRequest extends HttpServletRequestWrapper{
private HttpServletRequest request;
public MyRequest(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) {
String value = this.request.getParameter(name);
if(value==null){
return null;
}
if(!this.request.getMethod().equalsIgnoreCase("get")){
return value;
}
try {
value = new String(value.getBytes("iso8859-1"),charSet);
return value;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
}
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
二、Filter在用户自动登录中的应用
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//1.检查用户是否登陆
User user = (User) request.getSession().getAttribute("user");
if(user!=null){
chain.doFilter(request, response);
return;
}
//2.检查用户是否带自动登陆的cookie过来
Cookie autoLoginCookie = null;
Cookie cookies[] = request.getCookies();
for(int i=0;cookies!=null&&i<cookies.length;i++){
if(cookies[i].getName().equals("autoLogin")){
autoLoginCookie = cookies[i];
}
}
if(autoLoginCookie==null){
chain.doFilter(request, response);
return;
}
//3.用户带自动登陆cookie来了,但是cookie值不正常
String value = autoLoginCookie.getValue();
if(value.split("\\:").length!=3){
chain.doFilter(request, response);
return;
}
//3.用户带自动登陆cookie来了,并且cookie正常,则程序帮用户完成自动登陆
String username = value.split("\\:")[0];
long expiresTime = Long.parseLong(value.split("\\:")[1]);
String md5value = value.split("\\:")[2];
//4.判断cookie的有效期是否过期
if(expiresTime>=System.currentTimeMillis()){
chain.doFilter(request, response);
return;
}
//5.得到服务器中相对应的MD5的值
UserDao dao = new UserDao();
user = dao.find(username);
String password = user.getPassword();
String server_md5value = md5(username + ":" + expiresTime + ":" + password);
//6.md5值不相等
if(!server_md5value.equals(md5value)){
chain.doFilter(request, response);
return;
}
request.getSession().setAttribute("user", user);
chain.doFilter(request, response);
}
三、Filter控制浏览器缓存js\css\jpg等文件中的应用
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//1.得到请求的是什么资源 css js jpg
String uri = request.getRequestURI();
if(uri.endsWith(".css")){
long expriesTime = Integer.parseInt(this.config.getInitParameter("css"))*1000;
response.setDateHeader("expires", System.currentTimeMillis()+expriesTime);
}else if(uri.endsWith(".js")){
long expriesTime = Integer.parseInt(this.config.getInitParameter("js"))*1000;
response.setDateHeader("expires", System.currentTimeMillis()+expriesTime);
}else if(uri.endsWith(".jpg")){
long expriesTime = Integer.parseInt(this.config.getInitParameter("jpg"))*1000;
response.setDateHeader("expires", System.currentTimeMillis()+expriesTime);
}
chain.doFilter(request, response);
}
四、Filter压缩文件的应用
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//getOuputStream MyServletOutputStream
//getWriter MyWriter
//创建response,捕获目标资源输出的数据
MyResponse myresponse = new MyResponse(response);
chain.doFilter(request, myresponse);
//得到目标资源输出
byte resouceData[] = myresponse.getBuffer();
System.out.println("原始大小:" + resouceData.length);
//压缩数据
byte gzipData[] = gzip(resouceData);
//输出压缩数据给浏览器
response.setHeader("Content-Encoding", "gzip");
response.setContentLength(gzipData.length);
response.getOutputStream().write(gzipData); //utf-8
}
public byte[] gzip(byte src[]) throws IOException{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
GZIPOutputStream gout = new GZIPOutputStream(bout);
gout.write(src);
gout.close();
return bout.toByteArray();
}
class MyResponse extends HttpServletResponseWrapper{
private HttpServletResponse response;
private ByteArrayOutputStream bout = new ByteArrayOutputStream();
private PrintWriter pw = null;
public MyResponse(HttpServletResponse response) {
super(response);
this.response = response;
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new MyServletOuputStream(bout);
}
@Override
public PrintWriter getWriter() throws IOException {
pw = new PrintWriter(new OutputStreamWriter(bout,this.response.getCharacterEncoding())); //printWriter.writer("中国");
return pw;
}
public byte[] getBuffer(){
if(pw!=null){
pw.close();
}
return bout.toByteArray();
}
}
class MyServletOuputStream extends ServletOutputStream{
private ByteArrayOutputStream bout; //FileOuputStream
public MyServletOuputStream(ByteArrayOutputStream bout){
this.bout = bout;
}
@Override
public void write(int b) throws IOException {
bout.write(b);
}
}
五、Filter过滤敏感词汇的应用
private List<String> banWords = new ArrayList(); //保存用于匹配所有禁用词的正则表达式
private List<String> auditWords = new ArrayList(); //审核词
private List<String> replaceWords = new ArrayList(); //替换词
public void init(FilterConfig filterConfig) throws ServletException {
try{
String path = WordsFilter.class.getClassLoader().getResource("cn/itcast/words").getPath();
File filepath = new File(path);
File files[] = filepath.listFiles();
for(File f : files){
if(!f.getName().endsWith(".txt")){
continue;
}
BufferedReader br = new BufferedReader(new FileReader(f));
String line = null;
while((line=br.readLine())!=null){
String values[] = line.trim().split("\\|");
if(values.length!=2){
continue;
}
String word = values[0];
String type = values[1];
if(type.trim().equals("1")){
banWords.add(word);
}else if(type.trim().equals("2")){
auditWords.add(word);
}else if(type.trim().equals("3")){
replaceWords.add(word);
}
}
}
System.out.println("haha");
}catch (Exception e) {
throw new RuntimeException(e);
}
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//1.检查用户的请求数据中是否包含禁用词,包含禁用词则直接跳转到消息显示页面
Enumeration e = request.getParameterNames();
while(e.hasMoreElements()){
String value = request.getParameter((String) e.nextElement()); //你生小孩子没屁眼
if(value==null){
continue;
}
for(String pattern : banWords){
Pattern p = Pattern.compile(pattern); //得到一个代表pattern的正则表达式对象
Matcher m = p.matcher(value); //得到与字符串相匹配的匹配器
if(m.find()){
request.setAttribute("message", "请文明用词!!!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return;
}
}
}
chain.doFilter(new MyRequest(request), response);
}
class MyRequest extends HttpServletRequestWrapper{
private HttpServletRequest request;
public MyRequest(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) {
String value = this.request.getParameter(name); //帮用户获取它所需的数据
//对数据进行检查,如果发现包含审核或替词,则分别高亮、替换后再把数据返回给用户
if(value==null){
return null;
}
//检查是否包含审核词
for(String pattern : auditWords){ //吃.{0,2}人
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(value);
while(m.find()){ //调用匹配器的方法检查value中是否包含审核数据
String data = m.group(); //返回value中与正则表达式匹配的数据
value = value.replaceAll(data, "<font color=‘red‘>"+data+"</font>");
}
}
//检查是否包含替换词
for(String pattern : replaceWords){ //吃.{0,2}人
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(value);
while(m.find()){ //调用匹配器的方法检查value中是否包含审核数据
String data = m.group(); //返回value中与正则表达式匹配的数据
value = value.replaceAll(data, "*******");
}
}
return value;
}
}