JavaWeb学习-Filter-5-Filter实现全局编码过滤器

这篇来做一个Filter在全局编码过滤器练习,这篇新建一个web项目来做练习。

 

web项目创建

先创建一个叫GlobalFilter的web动态项目,把前面文章出现过的login.jsp复制过来,改成如下代码。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="${pageContext.request.contextPath}/web/loginServlet" method="post">
		用户名:<input type="text" name="username" /><br/>
		<input type="submit" value="登录" /><br/>
	</form>
</body>
</html>

因为我们这里做全局编码的练习,到时候登录页面输入用户名,我们会采用中文字符输入。

 

Servlet创建

因为这里我们是模拟全局,实际中应该有许多servlet和许多前端页面,例如注册,登录,首页搜索等。我们就来创建一个servlet来模拟下就好。创建一个LoginServlet.java。 url-pattern是/web/loginServlet。

package com.anthony.web.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
	
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//request.setCharacterEncoding("UTF-8");
		String name = request.getParameter("username");
		System.out.println(name);
	}

	
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

以前,我们是通过这个红圈代码来设置编码,这样拿到中文的username就不会是乱码。

 

现实开发中有很多个servlet,如果都这样写这行代码来设置编码,这行代码就冗余,我们可以把这行代码放到Filter过滤器中去。

 

Filter类创建

创建一个MyFilter.java 实现Filter接口,代码如下。

package com.anthony.web.filter;

import java.io.IOException;
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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;


public class MyFilter implements Filter {

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

	
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// 转换对象
		HttpServletRequest req = (HttpServletRequest) request;
		// 设置编码
		req.setCharacterEncoding("UTF-8");
		// 放行
		chain.doFilter(request, response);
	}

	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

web.xml内容如下

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>GlobalFilter</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <filter>
  	<filter-name>MyFilter</filter-name>
  	<filter-class>com.anthony.web.filter.MyFilter</filter-class>
  </filter>
  
  <filter-mapping>
  	<filter-name>MyFilter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>com.anthony.web.servlet.LoginServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/web/loginServlet</url-pattern>
  </servlet-mapping>
  
</web-app>

部署测试

现在部署到tomcat然后测试以下,前台页面用户名输入框输入“张三”看看。

在Eclipse控制台可以看到“张三”打印出来不乱码,说明我们Filter中编码设置起效果了。

 

Get方式提交表单问题

在login.jsp中我们表单提交是post方法,如果改成get呢,会出问题。

重新部署,再来测试下

如果是get方式传过来,中文就很有可能显示乱码。这个问题怎么解决了,有两种方式解决,第一种不要写get,就是post表单提交。现在我们来看看第二种方式如何解决。在MyFilter类中写一个通用的方法,既能解决get也能解决post的编码问题。

 

装饰模式解决get和post编码问题

我们在MyFilter.java代码中添加一个MyRequest class,里面写我们的装饰器代码,只重写了getParameter(String text)方法。

package com.anthony.web.filter;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

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.HttpServletRequestWrapper;


public class MyFilter implements Filter {

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

	
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// 转换对象
		HttpServletRequest req = (HttpServletRequest) request;
		// 设置编码
		//req.setCharacterEncoding("UTF-8");
		// 放行
		req = new MyRequest(req);
		// req这个对象是包装之后的对象,把这个传到servlet中的request
		chain.doFilter(req, response);
	}

	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

/**
 *  继承HttpServlet的包装类,实现装饰模式,解决get和post乱码问题
 * 
 */
class MyRequest extends HttpServletRequestWrapper{
	
	HttpServletRequest request;
	
	public MyRequest(HttpServletRequest request) {
		super(request);
		this.request = request;
	}
	
	public String getParameter(String name) {
		name = request.getParameter(name); //乱码
		try {
			return new String(name.getBytes("iso-8859-1"), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}
	
}

部署到tomcat,login.jsp表单还是get提交,测试可以解决get和post乱码。

 

重写其他方法

在request对象中,还有其他方法,例如getParameters() 和getParameterMap(),这里我们把这两个方法都重写一下。

package com.anthony.web.filter;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;

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.HttpServletRequestWrapper;


public class MyFilter implements Filter {

	public void destroy() {
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// 转换对象
		HttpServletRequest req = (HttpServletRequest) request;
		// 放行
		req = new MyRequest(req);
		// req变成自己包装的对象,然后传递给servlet中,servlet中的request就是调用包装过的req
		chain.doFilter(req, response);
	}

	public void init(FilterConfig fConfig) throws ServletException {
	}

}

/**
 * 继承HttpServlet的包装类,实现装饰模式,解决get和post乱码问题
 * 
 */
class MyRequest extends HttpServletRequestWrapper {
	
	HttpServletRequest request;
	
	public MyRequest(HttpServletRequest request) {
		super(request);
		this.request = request;
	}
	
	/*@Override
	public String getParameter(String name) {
		name = request.getParameter(name); //乱码
		try {
			return new String(name.getBytes("iso-8859-1"), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}*/
	
	@Override
	public String getParameter(String name) {
		Map<String, String[]> map = getParameterMap();
		return map.get(name)[0];
	}
	
	@Override
	public String[] getParameterValues(String name) {
		Map<String, String[]> map = getParameterMap();
		return map.get(name);
	}
	
	public boolean flag = true;
	@Override
	public Map<String, String[]> getParameterMap() {

		Map<String, String[]> map = request.getParameterMap(); // 乱码
		if (flag) {

			for (Map.Entry<String, String[]> m : map.entrySet()) {
				String[] values = m.getValue();
				for (int i = 0; i < values.length; i++) {
					try {
						values[i] = new String(values[i].getBytes("iso-8859-1"), "UTF-8");
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
					}
				}
			}
			flag = false;
		}
		return map;
	}
}

由于最后三个方法,我们倒数第二个第三个都是调用倒数第一个,为了解决第一个调用乱码好了,第二个再次调用又变成乱码,所以这里在第三个方法添加了一个flag。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明
JavaWeb中,可以使用Filter实现用户自动过滤Filter是Servlet规范中的一种组件,它能够对请求和响应进行过滤和修改,可以用于实现各种功能,如用户自动过滤、字符编码转换、权限控制等。 下面是一个简单的用户自动过滤Filter的示例代码: ```java @WebFilter(filterName = "userFilter", urlPatterns = {"/*"}) public class UserFilter implements Filter { private List<String> blacklist = Arrays.asList("hack", "attack", "sql", "xss"); public void init(FilterConfig config) throws ServletException { // 初始化 } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; String uri = req.getRequestURI(); String method = req.getMethod(); if ("POST".equals(method) && uri.contains("user")) { String username = req.getParameter("username"); String password = req.getParameter("password"); if (checkBlacklist(username) || checkBlacklist(password)) { // 检测到黑名单,返回提示信息 response.getWriter().write("您的输入包含非法字符,已被系统拦截!"); return; } } chain.doFilter(request, response); } public void destroy() { // 销毁 } private boolean checkBlacklist(String input) { if (input == null || input.isEmpty()) { return false; } for (String str : blacklist) { if (input.contains(str)) { return true; } } return false; } } ``` 上述代码中,我们定义了一个名为UserFilterFilter,并将其配置为拦截所有请求(urlPatterns={"/*"})。在doFilter方法中,我们首先获取请求的URI和请求方法,如果是POST请求并且URI包含"user",则说明用户正在进行登录或注册操作,需要对用户名和密码进行校验。我们调用checkBlacklist方法来检查用户名和密码中是否包含黑名单中的关键词,如果包含,就直接返回提示信息,否则调用chain.doFilter方法将请求传递给下一个Filter或Servlet。checkBlacklist方法的实现与前面的示例相同,不再赘述。 需要注意的是,Filter必须在web.xml或使用注解@WebFilter进行注册和配置。在上述示例中,我们使用了注解@WebFilter来注册Filter,这需要在Web项目中使用Servlet 3.0或以上版本的容器才能生效。如果使用的是Servlet 2.5或以下版本的容器,就必须在web.xml中配置Filter,例如: ```xml <filter> <filter-name>userFilter</filter-name> <filter-class>com.example.UserFilter</filter-class> </filter> <filter-mapping> <filter-name>userFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ``` 这样,我们就完成了一个简单的用户自动过滤Filter实现。需要注意的是,这只是一个示例,实际应用中可能需要更加复杂和完善的校验机制,以确保系统的安全性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值