当前访客身份:游客 [ 登录  | 注册加入尚学堂]
启用新域名sxt.cn
新闻资讯

如何用过滤器过滤HTTP协议和非HTTP协议编码

helloworld 发表于 2年前  | 评论(0 )| 阅读次数(577 )|   1 人收藏此文章,   我要收藏

在编写web时,最苦恼的事情就是乱码了。

一直没怎么考虑过JSP第一句话中

的ContentType和pageEncoding具体是用做什么的,害自己做了过滤器也老是出现问题。

Google下:


contentType ------------指定的是JSP页最终 Browser(客户端)所见到的网页内容的编码.

pageEncoding ------------指定JSP编写时所用的编码




如果害怕忘了在每个jsp都加上这样的编码,或者由于不同环境所需的客户端所见编码的不同。加上过滤器来解决

1.HTTP协议下的过滤:

(1.login.jsp   )用来模拟输入数据登录

 
<%@ page language="java"  pageEncoding="GBK"%>
<!DOCTYPEhtml PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<metahttp-equiv="Content-Type">
<title>HTTP协议和URL编码</title>
</head>
<body>
<p>这里仅仅POST编码测试</p>
<formaction="main.jsp"method="post">
<label>测试HTTP协议</label>
<inputtype="text"name="infoPost"/>
<inputtype="submit"value="提交">
</form>
<hr>
<p>测试通过GET传送(url方式)</p>
<formaction="main.jsp"method="get">
<label>测试URL</label>
<inputtype="text"name="infoGet"/>
<inputtype="submit"value="提交">
</form>
</body>
</html>




(2.main.jsp  )用来模拟得到数据

<%@ page language="java"  pageEncoding="GBK"%>
<!DOCTYPEhtml PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<metahttp-equiv="Content-Type">
<title>获取页面传过来的值</title>
</head>
<body>
 获取通过HTTP协议传送过来的值
<%=request.getParameter("infoPost") %>
<hr>
获取通过URL传送过来的值
<%=request.getParameter("infoGet") %>
</body>
</html>





(3.web.xml)配置


<!-- 编码过滤器 -->
 <filter>
 <filter-name>EncodeFilter</filter-name>
 <filter-class>demo.filter.EncodeFilter</filter-class>
 <init-param>
 <param-name>encoding</param-name>
 <param-value>GBK</param-value>
 </init-param>
 </filter>
 <filter-mapping>
 <filter-name>EncodeFilter</filter-name>
 <url-pattern>/*</url-pattern>
 </filter-mapping>





(4.EncodeFilter.java)过滤器类
	
packagedemo.filter;
 
importjava.io.IOException;
 
importjavax.servlet.Filter;
importjavax.servlet.FilterChain;
importjavax.servlet.FilterConfig;
importjavax.servlet.ServletException;
importjavax.servlet.ServletRequest;
importjavax.servlet.ServletResponse;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
 
/** 字符编码 */
publicclassEncodeFilterimplementsFilter {
    protectedString encoding;
    protectedFilterConfig filterConfig;
 
    publicEncodeFilter() {
        this.encoding =null;
        this.filterConfig =null;
    }
 
    publicvoiddestroy() {
 
        filterConfig =null;
        encoding =null;
    }
 
    publicvoiddoFilter(ServletRequest request, ServletResponse response,
            FilterChain filterChain)throwsIOException, ServletException {
        /*
         * 处理通过HTTP协议提交的数据
         */
        HttpServletRequest hrequest = (HttpServletRequest) request;
        HttpServletResponse hresponse = (HttpServletResponse) response;
        // 这里省略前面两段,直接用request..setCharacterEncoding(encoding);效果是一样的,这里为了说明这个是通过HTTP
        // 协议提交
        System.out.println("编码格式"+ encoding);
        hrequest.setCharacterEncoding(encoding);
        filterChain.doFilter(request, response);
 
    }
 
    /*
     * 过滤器初始化
     */
    publicvoidinit(FilterConfig filterConfig)throwsServletException {
        this.filterConfig = filterConfig;
        encoding = filterConfig.getInitParameter("encoding");
 
    }
 
}






结果:

  

post 方式参数存放在请求数据包的消息体中。get方式参数存放在请求数据包的请求行的URI字段中,以?开始以param=value&& parame2=value2的形式附加在URI字段之后。而request.setCharacterEncoding(charset); 只对消息体中的数据起作用,对于URI字段中的参数不起作用。

可以继承扩展HttpServletRequestWrapper 增加过滤功能

添加一个MyEncodeFilter类

packagedemo.filter;
 
importjava.io.UnsupportedEncodingException;
 
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletRequestWrapper;
 
publicclassMyEncodeFilterextendsHttpServletRequestWrapper{
 
    privateString encoding="GBK";
    publicMyEncodeFilter(HttpServletRequest request) {
        super(request);
         
    }
    publicMyEncodeFilter(HttpServletRequest request,String encoding) {
        super(request);
        this.encoding=encoding;
         
    }
    //新增加一个转码方法
    publicString encodeName(String en){
         
        try{
            returnnewString(en.trim().getBytes("ISO-8859-1"),encoding);
        }catch(UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            returnen;
             
        }
         
    }
    //增强过滤的方法,就是将URI字段中的参数编码(重写)
 
    publicString getParameter(String name) {
        //直接调用父类的getParameter方法获取参数的值
        String value=super.getParameter(name);
        //如果不为空就将其转码
        value=value==null?null:encodeName(value);
        returnvalue;
         
    }
     
 
 
}






改变后的Filter:

packagedemo.filter;
 
importjava.io.IOException;
 
importjavax.servlet.Filter;
importjavax.servlet.FilterChain;
importjavax.servlet.FilterConfig;
importjavax.servlet.ServletException;
importjavax.servlet.ServletRequest;
importjavax.servlet.ServletResponse;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
 
/** 字符编码 */
publicclassEncodeFilter implementsFilter {
    protectedString encoding;
    protectedFilterConfig filterConfig;
 
    publicEncodeFilter() {
        this.encoding =null;
        this.filterConfig =null;
    }
 
    publicvoiddestroy() {
 
        filterConfig =null;
        encoding =null;
    }
 
    publicvoiddoFilter(ServletRequest request, ServletResponse response,
            FilterChain filterChain)throwsIOException, ServletException {
        /*
         * 处理通过HTTP协议提交的数据
         */
        HttpServletRequest hrequest = (HttpServletRequest) request;
        // 这里省略前面两段,直接用request..setCharacterEncoding(encoding);效果是一样的,这里为了说明这个是通过HTTP
        // 协议提交
        System.out.println("编码格式"+ encoding);
        hrequest.setCharacterEncoding(encoding);
        //新增加方法<只要通过url来头中肯定有get>
        if(hrequest.getMethod().equalsIgnoreCase("get")){
            hrequest=newMyEncodeFilter(hrequest,encoding);
             
        }
         //
        filterChain.doFilter(hrequest, response);
 
    }
 
    /*
     * 过滤器初始化
     */
    publicvoidinit(FilterConfig filterConfig)throwsServletException {
        this.filterConfig = filterConfig;
        encoding = filterConfig.getInitParameter("encoding");
 
    }
 
}






解决成功!
分享到:0
关注微信,跟着我们扩展技术视野。每天推送IT新技术文章,每周聚焦一门新技术。微信二维码如下:
微信公众账号:尚学堂(微信号:bjsxt-java)
声明:博客文章版权属于原创作者,受法律保护。如果侵犯了您的权利,请联系管理员,我们将及时删除!
(邮箱:webmaster#sxt.cn(#换为@))
北京总部地址:北京市海淀区西三旗桥东建材城西路85号神州科技园B座三层尚学堂 咨询电话:400-009-1906 010-56233821
Copyright 2007-2015 北京尚学堂科技有限公司 京ICP备13018289号-1 京公网安备11010802015183