加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

javaWeb 使用 filter 处理全站乱码问题

发布时间:2020-12-15 08:00:02 所属栏目:Java 来源:网络整理
导读:springboot 实例?https://blog.csdn.net/m0_38075425/article/details/81164930 https://www.cnblogs.com/Westfalen/p/6170312.html ? 1. web.xml文件中的配置 filter filter-nameCharacterEncodingFilter/filter-name filter-classde.bvb.web.filter.Charac

springboot 实例?https://blog.csdn.net/m0_38075425/article/details/81164930

https://www.cnblogs.com/Westfalen/p/6170312.html

?

1. web.xml文件中的配置

    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>de.bvb.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>characterEncoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping> 

2.CharacterEncodingFilter.java代码

package de.bvb.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;
import javax.servlet.http.HttpServletResponse;

/**
 * 
 * <p><b>Function:     处理全站乱码问题
 * </b></p>Class Name: CharacterEncodingFilter<br/>
 * Date:2016-12-13下午3:31:40<br/>author:Administrator<br/>since: JDK 1.6<br/>
 */
public class CharacterEncodingFilter implements Filter {
    private String charset = "UTF-8"; //默认编码设置为 UTF-8

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        String charset = filterConfig.getInitParameter("characterEncoding");
        if (charset != null && !charset.equals("")) {
            this.charset = charset;
        }
    }

    @Override
    public void doFilter(ServletRequest req,ServletResponse resp,FilterChain chain) throws IOException,ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        request.setCharacterEncoding(charset); //只能处理post方式的请求乱码
        response.setCharacterEncoding(charset);
        response.setContentType("text/html;charset=" + charset);

        chain.doFilter(new CharacterEncodingHttpServletRequest(request),response);
    }

    /**
     * 
     * <p><b>Function:     使用包装设计模式处理get方式的请求乱码
     * </b></p>Class Name: CharacterEncodingHttpServletRequest<br/>
     * Date:2016-12-13下午3:45:29<br/>author:Administrator<br/>since: JDK 1.6<br/>
     */
    class CharacterEncodingHttpServletRequest extends HttpServletRequestWrapper {
        private HttpServletRequest request;

        public CharacterEncodingHttpServletRequest(HttpServletRequest request) {
            super(request);
            this.request = request;
        }

        @Override
        public String getParameter(String name) {
            String value = request.getParameter(name);
            if (!"get".equalsIgnoreCase(request.getMethod())) { //如果是非get方法,直接返回
                return value;
            }
            if (value == null) {
                return null;
            }
            try {
                return value = new String(value.getBytes("iso8859-1"),request.getCharacterEncoding());
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }

    }

    @Override
    public void destroy() {
    }

}

?2.2 也可以通过动态代理技术处理 (-----------------------------有问题)

package de.bvb.web.filter;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

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;
import javax.servlet.http.HttpServletResponse;

/**
 * 
 * <p><b>Function:     通过动态代理技术处理全站乱码问题
 * </b></p>Class Name: CharacterEncodingFilter<br/>
 * Date:2016-12-13下午3:31:40<br/>author:Administrator<br/>since: JDK 1.6<br/>
 */
public class CharacterEncodingFilter implements Filter {
    private String charset = "UTF-8"; //默认编码设置为 UTF-8

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        String charset = filterConfig.getInitParameter("characterEncoding");
        if (charset != null && !charset.equals("")) {
            this.charset = charset;
        }
    }

    @Override
    public void doFilter(ServletRequest req,ServletException {
        final HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        request.setCharacterEncoding(charset); //只能处理post方式的请求乱码
        response.setCharacterEncoding(charset);
        response.setContentType("text/html;charset=" + charset);
        chain.doFilter((ServletRequest) Proxy.newProxyInstance(CharacterEncodingFilter.class.getClassLoader(),HttpServletRequest.class.getInterfaces(),new InvocationHandler() {

                    @Override
                    public Object invoke(Object proxy,Method method,Object[] args) throws Throwable {
                        //改写 getParameter() 方法在get请求时候的功能
                        if ("get".equalsIgnoreCase(request.getMethod()) && "getParameter".equals(method.getName())) {
                            String value = (String) method.invoke(request,args);
                            if (value == null) {
                                return null;
                            }
                            return new String(value.getBytes("iso8859-1"),request.getCharacterEncoding());
                        }
                        return method.invoke(request,args);
                    }
                }),response);
    }

    @Override
    public void destroy() {
    }

}

?

? _________________________________________________________________
?
filter过滤器简单实例
https://blog.csdn.net/tikaber/article/details/78778884

package com.test.filter; import java.io.IOException; 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 javax.servlet.http.HttpSession; public class FirstFilter implements Filter{ //FilterConfig可用于访问Filter的配置信息 private FilterConfig config; @Override public void destroy() { this.config = null; } @Override public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException { //获取ServletContext对象,用于记录日志 ServletContext context = this.config.getServletContext(); long before = System.currentTimeMillis(); HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; HttpSession session = req.getSession();; String url = req.getRequestURI(); String queryString = req.getQueryString(); String fullPath = url + queryString; if (fullPath.equals(session.getAttribute("fullPath"))) { long middleTime = System.currentTimeMillis(); if (middleTime - (Long.parseLong(session.getAttribute("before").toString()))<5000) { System.out.println("重复提交"); } } session.setAttribute("before",before); session.setAttribute("fullPath",fullPath); // System.out.println("before invoke firstFilter‘s chain.doFilter() .."); chain.doFilter(req,resp); // System.out.println("after invoke firstFilter‘s chain.doFilter() .."); long after = System.currentTimeMillis(); long sumLoad = after - before; System.out.println("1.请求被定位到" + fullPath + "所花的时间为: " + sumLoad); } @Override public void init(FilterConfig config) throws ServletException { this.config = config; System.out.println("firstFilter init()..."); } private HttpServletRequest request; public boolean getParameter() { //如果是以post方式提交数据的,就直接返回获取到的值 if(this.request.getMethod().equalsIgnoreCase("post")) { return true; }else { return false; } } }

?

?
?
__________________________________________________________________

一、过滤器Filter

1.filter的简介

filter是对客户端访问资源的过滤,符合条件放行,不符合条件不放行,并且可以对目??? 标资源访问前后进行逻辑处理

2.快速入门

步骤:

1)编写一个过滤器的类实现Filter接口

2)实现接口中尚未实现的方法(着重实现doFilter方法)

3)在web.xml中进行配置(主要是配置要对哪些资源进行过滤)

public class QuickFilter1? implements Filter{

?? ?@Override
?? ?//Filter对象销毁的时候执行destory方法? 项目关闭时 (服务器关闭)
?? ?public void destroy() {
?? ??? ?System.out.println("destroy...");?? ??? ?
?? ?}

?? ?@Override
?? ?//doFilter是Filter的核心过滤的方法
?? ??? ?/*
?? ??? ? * request: 内部封装是客户端http请求的内容
?? ??? ? * response: 代表是响应
?? ??? ? * FilterChain: 过滤器链对象
?? ??? ? *?
?? ??? ? */
?? ?public void doFilter(ServletRequest arg0,ServletResponse arg1,FilterChain arg2)
?? ??? ??? ?throws IOException,ServletException {
?? ??? ?// 对客户端的请求 和 响应 做出? 过滤 和 拦截 处理操做
?? ??? ?System.out.println("filter1 running....");
?? ??? ?//放行请求??? 处理完? 将请求 和响应 放到 dofilter里 然后 继续下一层操做
?? ??? ?arg2.doFilter(arg0,arg1);
?? ?}

?? ?@Override
?? ?//Filter对象创建的时候执行init方法???? ---init方法 只在filter 创建的时候?? 执行一次
?? ?public void init(FilterConfig arg0) throws ServletException {
?? ??? ?// T1、获得web.xml中filter 的名称<filter-name>QuickFilter1</filter-name>
?? ??? ? System.out.println("filter的名称:"+arg0.getFilterName());
?? ??? ?//2、获得当前filter的初始化参数??? ps: 初始化参数是在 filter里面 设置的? 获取的是这里面的value?
?? ??? ? System.out.println(arg0.getInitParameter("aaa"));
?? ??? ? //3?? 获得所有的初始化参数的名称??? 和 请求响应的 类似? 不常用
?? ??? ? // Enumeration<String> parameterNames = arg0.getInitParameterNames();
?? ??? ?
?? ??? ? //4、获得servletContext?? 所有 servletContext 先创建? 后创建的 是 filter
?? ??? ?arg0.getServletContext();
?? ??? ?System.out.println("init.......");
?? ?}

}

? <filter>
??? <filter-name>filter1</filter-name>
??? <filter-class>com.imooc.web.filter.QuickFilter1</filter-class>
??? <init-param>
????? <param-name>aaa</param-name>
????? <param-value>woaini</param-value>
??? </init-param>
? </filter>
? <filter-mapping>
??? <filter-name>filter1</filter-name>
??? <url-pattern>/*</url-pattern>
??? <dispatcher>REQUEST</dispatcher>
? </filter-mapping>

?

3.Filter的API详解

(1)filter生命周期及其与生命周期相关的方法

Filter接口有三个方法,并且这个三个都是与Filter的生命相关的方法

init(Filterconfig):代表filter对象初始化方法 filter对象创建时执行 ?init方法 只在filter 创建的时候?? 执行一次

?

doFilter(ServletRequest,ServletResponse,FilterCha):代表filter执行过滤的核心方法,如果某资源在已经被配置到这个filter进行过滤的话,那么每次访问这个资源都会执行doFilter方法 ?--可以多次访问 ?多次执行

* FilterChain: 过滤器链对象?? :接受客户端 的 请求和响应? 然后向下一个 filter对象? 传递值 直到????????????????????????????????? 传递到 dopost/doGet 方法中? 然后再返回

?*?? 问题1: 那么多filter对象? 先执行的是哪一个?? domain怎么传递filter对象?

?*???? Tomcat 会根据<filter-mapping>映射 在 web.xml中配置的先后顺序 来依次执行filter对象?

?*???? 注意是<filter-mapping>的 先后顺序 不是 <filter>的先后顺序

?

destory():代表是filter销毁方法 当filter对象销毁时执行该方法

??

Filter对象的生命周期:

1 Filter何时创建:服务器启动时就创建该filter对象 ??(因为 filter的作用是过滤请求和响应 ?所以会在服务器启动时 就开始创建)

2? Filter何时销毁:服务器关闭时filter销毁 ?

3? 每次访问(请求)的目标路径 ?只要配置的该目标资源经过filter过滤,dofilter就执行一次

?? Filter的AP详解

1)init(FilterConfig)

其中参数config代表 该Filter对象的配置信息的对象,内部封装是该filter的配置信息。

?

?

?@Override
?? ?//Filter对象创建的时候执行init方法???? ---init方法 只在filter 创建的时候?? 执行一次
?? ?public void init(FilterConfig arg0) throws ServletException {
?? ??? ?// T1、获得web.xml中filter 的名称<filter-name>QuickFilter1</filter-name>
?? ??? ? System.out.println("filter的名称:"+arg0.getFilterName());
?? ??? ?//2、获得当前filter的初始化参数??? ps: 初始化参数是在 filter里面 设置的? 获取的是这里面的value?
?? ??? ? System.out.println(arg0.getInitParameter("aaa"));
?? ??? ? //3?? 获得所有的初始化参数的名称??? 和 请求响应的 类似? 不常用
?? ??? ? // Enumeration<String> parameterNames = arg0.getInitParameterNames();
?? ??? ?
?? ??? ? //4、获得servletContext?? 所有 servletContext 先创建? 后创建的 是 filter
?? ??? ?arg0.getServletContext();
?? ??? ?System.out.println("init.......");
?? ?}

?

?

?

2)destory()方法

filter对象销毁时执行

3)doFilter方法

doFilter(ServletRequest,FilterChain)

其中的参数:

ServletRequest/ServletResponse:每次在执行doFilter方法时 web容器负责创建一个request和一个response对象作为doFilter的参数传递进来。该request个该response就是在访问目标资源的service方法时的request和response。

FilterChain:过滤器链对象,通过该对象的doFilter方法可以放行该请求

?

?

?

?

4.Filter的配置

?

url-pattern配置时

1)完全匹配? /sertvle1

2)目录匹配? /aaa/bbb/* ----最多的

/user/*:访问前台的资源进入此过滤器

/admin/*:访问后台的资源时执行此过滤器

3)扩展名匹配? *.abc? *.jsp?? 所有以 .abc? .jsp? 结尾的

?

注意:url-pattern可以使用servlet-name替代,也可以混用 ?但是servlet-name?????????????? 一次只能配一个 ???太麻烦 ?不提倡

?

?

dispatcher:访问的方式(了解)

REQUEST:默认值,代表直接访问某个资源时执行filter

FORWARD:转发时才执行filter

INCLUDE: 包含资源时执行filter

ERROR:发生错误时 进行跳转是执行filter

?

?

???? 俩个 servlet 对象 ???访问方式默认的情况下

????????? 转发 ???filter对象 访问一次 ?(转发是请求一次)

????????? 重定向 ?filter对象 访问俩次 ?(重定向是请求两次)

????????? 转发时? ?

????????????? A—转发---B?? 访问一次 ?先访问B资源 在访问A资源 ?

????????? 下面的都差不多 ?不再次细说 ?可以自己敲一下?? ??

?

???

总结Filter的作用?

1)公共代码的提取

2)可以对request和response中的方法进行增强(装饰者模式/动态代理)

3)进行权限控制

????????????? 通过filter 对请求 ?进行分析 ?可以决定对访问者 是否放行 ?是否允许其访问服务端的响应资源 (比如 ceo? 和 普通员工访问的资源是不一样的 权限大小 CEO能访问的东西 员工不一定 能访问)

4)乱码处理

?

?

?

?

?

?联想

Struts2 框架 就是通过filter 过滤器 ?连接web工程的 ??它是使用的filter的接口

而 spring 框架 ?则是通过 listener 监听器 连接的项目工程

?

?

? ? ?? 应用 处理乱码?


public class EncondingFilter implements Filter {

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

?? ?
?? ?public void doFilter(ServletRequest request,ServletException {
?? ??? ?
?? ??? ?//通过filter 统一完成 乱码问题
?? ??? ?request.setCharacterEncoding("UTF-8");
?? ??? ?//在传递request之前对request的getParameter方法进行增强
?? ??? ?//增强方法的三种模式???? 动态代理? 继承?? 装饰者模式
?? ?
?? ??? ?/*
?? ??? ? * 装饰者模式(包装)
?? ??? ? *?
?? ??? ? * 1、增强类与被增强的类要实现统一接口
?? ??? ? * 2、在增强类中传入被增强的类
?? ??? ? * 3、需要增强的方法重写 不需要增强的方法调用被增强对象的
?? ??? ? *?
?? ??? ? */
?? ??? ?
??? //被增强的对象???? --- get方法 的 乱码解决
?? ?HttpServletRequest req = (HttpServletRequest) request;
?? ?//增强对象
?? ?EnhanceRequest enhanceRequest = new EnhanceRequest(req);
?? ??? ?chain.doFilter(request,response);
?? ?}

?? ?public void init(FilterConfig fConfig) throws ServletException {
?? ??? ?// TODO Auto-generated method stub
?? ?}
//HttpServletRequestWrapper? 方法? 本质 还是 request 方法? ?

??? /**
?? ? * Servlet? filter可以在调用一个servlet的服务方法后,拦载或加工HTTP请求。尽管这非常诱人,
?? ? * 但其实际使用却有所限制,因为你不能改变HttpServletRequest对象。
?? ? * 这时候装饰模式派上了用场。创建HttpServletRequest的装饰类,需要继承HttpServletRequestWrapper
?? ? * 并且覆盖(增强)你希望改变的方法。?
?? ? * @author lqf
?? ? *
?? ? */
class EnhanceRequest extends HttpServletRequestWrapper{
?? ?
?? ?private HttpServletRequest request;

?? ?public EnhanceRequest(HttpServletRequest request) {
?? ??? ?super(request);
?? ??? ?this.request = request;
?? ?}
?? ?//对getParaameter增强
?? ?@Override
?? ?public String getParameter(String name) {
?? ??? ?String parameter = request.getParameter(name);//乱码
?? ??? ?try {
?? ??? ??? ?parameter = new String(parameter.getBytes("iso8859-1"),"UTF-8");
?? ??? ?} catch (UnsupportedEncodingException e) {
?? ??? ??? ?e.printStackTrace();
?? ??? ?}
?? ??? ?return parameter;
?? ?}

?? ?
}

时间:2019-08-20 11:08:05 阅读(8)
最新文章 更多
1 linux国际象棋 棋盘脚本.md(含脚本注释,查看更直观) 2019-08-25
2 Linux中root 密码重置 2019-08-25
3 [触动精灵]触动精灵官方手册流水账2 2019-08-25
4 二分图判定 2019-08-25
5 过滤器和监听器 2019-08-25
6 基础回顾--素数筛,欧拉函数 2019-08-25
7 还原Master数据库后SQLSERVER的服务无法开启 2019-08-25
8 (一)利用MFC搭建图片显示的界面 2019-08-25
9 postman 请求参数中传token如何动态获取 2019-08-25
10 利用python求非线性方程 2019-08-25
最新资讯 更多
1 外媒曝乌克兰核电站雇员擅自偷电挖比特币 2019-08-25
2 AI拍照翻译软件大测评 2019-08-25
3 华为海思注册资本从6亿增加到20亿 2019-08-25
4 从被唱衰到真香,共享充电宝是怎么逆风翻盘的? 2019-08-25
5 二维码已成万亿级产业 中国占据二维码应用市场90%以上 2019-08-25
6 嫦娥四号、玉兔二号再次唤醒 进入第九月昼 2019-08-25
7 三星苹果遭美消费者集体诉讼:手机电磁辐射违规 2019-08-25
8 AMD CEO苏姿丰:显卡交火已经不是关注的重点 2019-08-25
9 克隆猫公司预计年入2000万 2019-08-25
10 ofo这一年的艰难自救 2019-08-25

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读