版权声明:本文为setlilei原创文章 转载请注明来源 https://blog.csdn.net/setlilei/article/details/88361667
Java Filter&解决GET乱码
一劳永逸 打开Tomcat server.xml文件 加入URIEncoding=“UTF-8”
<Connector URIEncoding="UTF-8" connectionTimeout="20000"
port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
filter作用解决全局乱码 对目标资源进行预前处理
函数 | 作用 | 生命周期 |
---|---|---|
init(FilterConfig) | filter对象初始化时执行(filter对象初始化方法 只执行一次) | |
doFilter(ServletRequest,ServletResponse,FilterChain) | filter过滤器核心方法(每次访问到要过滤的资源都会执行) | |
destory() | filter对象销毁时方法(filter对象销毁时方法 只执行一次) |
<!--在web.xml中配置filter-->
<filter>
<filter-name>test</filter-name>
<filter-class>com.java.Test</filter-class>
<init-param>
<param-name>url</param-name>
<param-value>www.baidu.com</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>test</filter-name>
//<url-pattern>/test</url-pattern>--过滤资源路径为 项目名/test的请求
//<url-pattern>*.abc</url-pattern>--过滤资源路径所有后缀为abc的请求
//<url-pattern>/a/b/c/*</url-pattern>--过滤资源路径前缀为 项目名/a/b/c的所有请求
//<url-pattern>/a/b/c/*.abc</url-pattern>--不可混用 此处错误示范
<url-pattern>/*</url-pattern>--一般用法 当前为过滤所有路径
//<servlet-name>abc</servlet-name>
<dispatcher>REQUEST</dispatcher>--默认值 直接访问某个资源才能执行该过滤器方法
直接访问执行一次 sendRedirect访问执行两次
//<dispatcher>FORWARD</dispatcher>-- 转发访问某个资源才能执行该过滤器方法
forward()方法执行后调用 后执行filter
//<dispatcher>INCLUDE</dispatcher>-- A资源包含B资源访问某个资源才能执行该过滤器方法
//<dispatcher>ERROR</dispatcher>-- 出错后 访问某个资源才能执行该过滤器方法
</filter-mapping>
public class Test implements Filter {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("Hello Filter");//执行servlet前执行
chain.doFilter(request, response);//代表放行 不放行无法执行下一步的servlet方法
System.out.println("Filter后处理");//执行完servlet后执行
}
@Override
public void init(FilterConfig filterConfig)//当前filter的配置对象
throws ServletException {
String name = filterConfig.getFilterName();//获取web.xml<filter-name>的文本节点
String test = filterConfig.getInitParameter("url");
ServletContext context = filterConfig.getServletContext();
//ServletContext context = this.getServletContext();--一般用这种方式获取
}
}
FilterChain(过滤器链)对象维护着该filter对象的索引 连接多个filter 控制运行和运行顺序
过滤器可以多个链接到一起过滤 所有filter都要放行才可访问目标资源
filter可以用权限控制 连接数据库获取值后判断权限大小决定是否放行
/*
* 使用filter解决乱码
* 使用装饰着设计模式
*/
public class EncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//转型为与协议相关对象
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
//对request包装增强
HttpServletRequest myrequest = new MyRequest(httpServletRequest);
chain.doFilter(myrequest, response);
}
@Override
public void destroy() {
}
}
//自定义request对象
class MyRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;
private boolean hasEncode;
public MyRequest(HttpServletRequest request) {
super(request);//super必须写
this.request = request;
}
//对需要增强方法 进行重写覆盖
@Override
public Map getParameterMap() {
//先获得请求方式
String method = request.getMethod();
if (method.equalsIgnoreCase("post")) {
//post请求
try {
//处理post乱码
request.setCharacterEncoding("utf-8");
return request.getParameterMap();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else if (method.equalsIgnoreCase("get")) {//tomcat8.5已经处理了get中文可以将get中的代码注释掉
//get请求
Map<String, String[]> parameterMap = request.getParameterMap();
if (!hasEncode) {//确保get手动编码逻辑只运行一次
for (String parameterName : parameterMap.keySet()) {
String[] values = parameterMap.get(parameterName);
if (values != null) {
for (int i = 0; i < values.length; i++) {
try {
//处理get乱码
values[i] = new String(values[i].getBytes("ISO-8859-1"), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}hasEncode = true;
}
return parameterMap;
}
return super.getParameterMap();
}
@Override
public String getParameter(String name) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
if (values == null) {
return null;
}
return values[0];//取回参数的第一个值
}
@Override
public String[] getParameterValues(String name) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
return values;
}
}