基于Tomcat的JSP提交表单时乱码

参考文献:Servlet容器Filter的使用(Filter解决乱码问题实例)Java Servlet Filter提交表单时的中文乱码问题jsp乱码问题的解决

原因:

Tomcat下面总是会把GET/POST过来的reqest.parameters以ISO8859-1来解码,但中文系统下的浏览器的缺省方式是以UTF-8提交发送请求的,而UTF-8、GB2312和iso8859-1的编码方式不一样,故导致取到的表单数据为不能识别的乱码。

P.S. jsp页面的开始明确给出的页面的编码格式 :

<%@ page language="java" conntentType="text/html;charset=GB18030" pageEncoding="GB18030"%>

其中,GB18030代表的是汉字的编码的
charset是指服务器发送给客户端时的内容编码.
pageEncoding是指JSP文件本身的编码.如果改为'UTF-8'的话,那JSP源文件就不能写汉字了.所以我们在最初设置的JSP本身的编码和服务器发送给客户端的编码都是 GB18030,即中文编码.
注意,客户端发给服务器的内容不显式指定编码方式的话仍为ISO8859-1

P.P.S. 元信息

<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">

表明这个网页的编码是utf-8,需要注意的是这个是网页内容的编码,而不是文件本身的。


解决方法:

  • post表单
    • 接受参数时进行编码转换

String str = new  String(request.getParameter("something").getBytes("ISO-8859-1"),"utf-8");

这样的话,每一个参数都必须这样进行转码。很麻烦。但确实可以拿到汉字。

    • 在请求页面上开始处,执行请求的编码代码

request.setCharacterEncoding("UTF-8");

把提交内容的字符集设为UTF-8。

这样的话,接受此参数的页面就不必在转码了。直接使用String str = request.getParameter("something");即可得到汉字参数。但每页都需要执行这句话。

这个方法也就对post提交的有效果,对于get提交和上传文件时的enctype="multipart/form-data"是无效的。稍后下面单独对这个两个的乱码情况再进行说明。

    • 为了避免每页都要写request.setCharacterEncoding("UTF-8"), 可以实现Filter接口, 将逻辑处理放入doFilter()方法中
见附录.
  • get表单

Tomcat会以get的缺省编码方式iso8859-1对汉字进行编码,编码后追加到url,导致接受页面得到的参数为乱码.

    • 使用上例中的第一种方式,对接受到的字符进行解码,再转码。

    • Get走的是url提交,而在进入url之前已经进行了iso8859-1的编码处理。要想影响这个编码则需要在 server.xml的Connector节点增加
useBodyEncodingForURI="true" 

属性配置,即可控制tomcat对get方式的汉字编码方式,上面这个属性控制get提交也是用request.setCharacterEncoding("UTF-8")所设置的编码格式进行编码。所以自动编码为utf-8,接受页面正常接受就可以了。

P.S. 但我认为真正的编码过程是,tomcat又要根据

<Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" debug="0" connectionTimeout="20000" useBodyEncodingForURI="true" disableUploadTimeout="true" URIEncoding="UTF-8"/>

里面所设置的URIEncoding=”UTF-8”再进行一次编码,但是由于已经编码为utf-8,再编码也不会有变化了。如果是从url获取编码,接受页面则是根据URIEncoding=”UTF-8”来进行解码的。


附录:

MyFilter.java
package com.bjpowernode.drp.util.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;

/**
 * 采用Filter统一处理字符集.
 * @author Summer
 *
 */
public class CharsetEncodingFilter implements Filter {

	//定义成员变量.
	private String encoding;
	//销毁.
	@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("CharacterEncodingFilter--begin");
		//设置字符集.
		request.setCharacterEncoding(encoding);
		
		//拿到链条继续向下调用.
		 chain.doFilter(request, response);
		 //返回了.
		 //System.out.println("CharacterEncodingFilter--end");

	}
	
	/**
	 * 过滤器初始化时候调用.
	 * 我们在初始化的时候调用
	 * 从web.xml中读取配置文件 读取encoding数据.
	 */
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		this.encoding = filterConfig.getInitParameter("encoding");
		
	
	}

}
web.xml

<filter>
	<filter-name>CharsetEncodingFilter</filter-name>
	<filter-class>com.bjpowernode.drp.util.filter.CharsetEncodingFilter</filter-class>
	<init-param>
		<param-name>encoding</param-name>
		<param-value>GBK</param-value>
	</init-param>
</filter>
	
<!-- 对哪些起作用,对jsp还是servlet -->
<filter-mapping>
	<filter-name>CharsetEncodingFilter</filter-name>	
	<url-pattern>*.jsp</url-pattern>
	<servlet-name>*</servlet-name>	<!-- 在这里需要注意的是,在给servlet注册filter环,container首先处理的是url-patterns, -->                                                      <!-- 然后才处理servlet-names,所以如果要对filter的执行顺序有要求,那么在此需要注意。 -->
</filter-mapping>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值