处理request中的乱码问题

本文介绍了两种处理HTTP请求乱码问题的方法:1. 动态代理实现,通过在web.xml配置filter,然后创建动态代理类,重写getParameter等方法进行编码转换。2. 装饰模式实现,创建一个HttpServletRequest的装饰类,覆盖获取请求参数相关的方法,增加乱码解决的代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.动态代理实现

1>首先在web.xml中添加如下代码

<context-param>

       <param-name>encode</param-name>

       <param-value>utf-8</param-value>

    </context-param>

    <!-- filter配置 -->

    <filter>

       <filter-name>EncodingFilter</filter-name>

       <filter-class>cn.tedu.filter.EncodingFilter</filter-class>

    </filter>

    <filter-mapping>

       <filter-name>EncodingFilter</filter-name>

       <url-pattern>/*</url-pattern>

    </filter-mapping>

2>在写一个类EncodingFilter继承Filter,代码如下
public class EncodingFilter{

private String encode = null;

/**

* 初始化方法

 */

publicvoidinit(FilterConfig filterConfig) throws ServletException{

    //获取ServletContext对象

    ServletContext sc =filterConfig.getServletContext();

    //读取初始化参数中的编码集配置

    this.encode = sc.getInitParameter("encode");

}

/**

* 过滤方法

*/

publicvoid doFilter(final ServletRequest request, ServletResponse response,FilterChainchain) throws IOException,ServletException {

    //解决乱码

    //响应乱码

    response.setContentType("text/html;charset="+encode);

    //请求参数:创建动态代理

ServletRequest  proxyRequest=

(ServletRequest) Proxy.newProxyInstance(request.getClass().getClassLoader(),request.getClass().getInterfaces(), newInvocationHandler() {

          

       public Object invoke(Object proxy, Method method, Object[] args)

              throws Throwable {

           //如果是调用getParameter方法

           if("getParameter".equals(method.getName())){

              //获取请求参数

              String value =(String) method.invoke(request, args);

              //重新编码并返回

              return newString(value.getBytes("iso8859-1"),encode);

           //如果是调用getParameterValues方法

           }else if("getParameterValues".equals(method.getName())){

              //获取请求参数组成的数组

              String[] values= (String[]) method.invoke(request, args);

              //遍历数组

              for (int i = 0; i <values.length; i++) {

                  //对数组中每一个元素重新编码,并赋值给当前元素

                   values[i] = newString(values[i].getBytes("iso8859-1"),encode);

               }

              //返回编码后的数组

              return values;

           //如果是调用getParameterMap方法

           }else if("getParameterMap".equals(method.getName())){

              //获取请求参数组成的map

              Map<String,String[]>map = (Map<String, String[]>) method.invoke(request, args);

              //遍历map

              for (Map.Entry<String, String[]>entry : map.entrySet()) {

                  String[]value = entry.getValue();

                  for (int i = 0; i <value.length; i++) {

                     value[i] = newString(value[i].getBytes("iso8859-1"),encode);

                  }

                  //将编码后的value赋值给map

                  map.put(entry.getKey(),value);

              }

              return map;

           }else{

              //如果是其他方法,直接执行目标方法并返回

              return method.invoke(request, args);

           }

       }

    });

    //放行时,使用代理对象作为参数

    chain.doFilter(proxyRequest,response);

}


/**

 * 销毁方法

 */

publicvoid destroy() {

}

}

2.装饰模式实现乱码问题

写一个类EncodingFilter继承Filter,代码如下

public class EncodingFilter{

private String encode = null;

/**

* 初始化方法

 */

publicvoidinit(FilterConfig filterConfig) throws ServletException{

    //获取ServletContext对象

    ServletContext sc =filterConfig.getServletContext();

    //读取初始化参数中的编码集配置

    this.encode = sc.getInitParameter("encode");

}


/**

* 内部类ServletRequest的装饰类 改造了获取请求参数相关的方法 增加了乱码解决的代码

*/

//继承了HttpServletRequestWrapper,这个父类本身就是 HttpServletRequest的装饰器  在其中提供方法的默认的实现 不想改造的方法不用管 想改造的方法 覆盖父类方法即可

class MyServletRequest extendsHttpServletRequestWrapper{

    private ServletRequest request = null;

    privatebooleanhasNotEncode = true;

    //构造器 接受传入的request保存在类的内部

    public MyServletRequest(HttpServletRequest request) {

       super(request);

       this.request = request;

    }

    //覆盖和获取请求参数相关的方法

    @Override

    public Map<String,String[]> getParameterMap() {

       try {

           //获取请求参数组成的map

           Map<String,String[]>map = request.getParameterMap();

           if(hasNotEncode){//由于request对此map会缓存所以解决乱码的操作 只需要做一次 此处通过hasNotEncode来控制

              //遍历map

              for (Map.Entry<String, String[]>entry : map.entrySet()) {

                  //获取当前遍历到的值的数组

                  String[]values = entry.getValue();

                  //遍历值的数组

                  for (int i = 0; i <values.length; i++) {

                     //解决乱码 存回数组

                     values[i]= newString(values[i].getBytes("iso8859-1"),encode);

                  }

              }

              hasNotEncode = false;

           }

           //返回解决完乱码的map

           return map;

       } catch (Exception e) {

           e.printStackTrace();

           thrownewRuntimeException();

       }

    }

    @Override

    public String[] getParameterValues(String name) {

       return getParameterMap().get(name);

    }

    @Override

    public String getParameter(String name) {

       String[] values =getParameterValues(name);

       return values == null ? null : values[0];

    }

}

 

/**

 * 过滤方法

 */

publicvoid doFilter(final ServletRequest request, ServletResponse response,FilterChainchain) throws IOException,ServletException {

    //解决乱码

    //响应乱码

    response.setContentType("text/html;charset="+encode);

    //请求参数

    ServletRequest myRequest= newMyServletRequest((HttpServletRequest) request);

    //资源放行

    chain.doFilter(myRequest,response);

}

/**

 * 销毁方法

 */

publicvoid destroy() {

}




}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值