解决 web 字符编码乱码问题-----charSet 和PageEncoding的区别--request编码问题


 pageEncoding是jsp文件本身的编码
  contentType的charset是指服务器发送给客户端时的内容编码

http请求 如post:将内容封装在请求的request里,由于是外国人开发的,用的是iso-8859-1编码格式,后台获得中文数据就会出现乱码

request.setCharacterEncoding("UTF-8");就是将request编码格式换成UTF-8(后台还是出现了乱码),所以我用

String description = new String(request.getParameter("description").getBytes("iso-8859-1"), "UTF-8");

解决的问题,但是一个项目很多时候要处理这个问题,所以可以用filter解决这个问题

public class RequestFilter implements Filter {


private static Log log = LogFactory.getLog(RequestFilter.class);


private String LOGIN_URL; // 登录
private String[] IGNORE_URLS; // 忽略的URL


protected String encoding = null;//默认POST编码
protected String encoding_wlc = null;//weblogic下的GET编码
protected boolean ignore = true;


protected String selectEncoding(ServletRequest request) {
return (this.encoding);
}


protected String selectEncoding_wlc(ServletRequest request) {
return (this.encoding_wlc);
}


public void init(FilterConfig config) throws ServletException {


this.LOGIN_URL = config.getInitParameter("loginUrl");


String ignoreUrl = config.getInitParameter("ignoreUrl");


if (ignoreUrl != null && !"".equals(ignoreUrl)) {
this.IGNORE_URLS = ignoreUrl.split(";");
}


log.info("过滤器启动了...");


this.encoding = config.getInitParameter("encoding");
this.encoding_wlc = config.getInitParameter("encoding_wlc");
log.info("编码过滤初始化, 默认POST请求编码: " + this.encoding
+ ", WebLogic下GET请求编码: " + this.encoding_wlc);
}


public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {


HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;


String encod = selectEncoding(request);
String encod_wlc = selectEncoding_wlc(request);
if (request.getContentType() == null) {
request.setCharacterEncoding(encod_wlc);
response.setContentType("application/x-www-form-urlencoded; charset=" + encod_wlc);
response.setCharacterEncoding(encod_wlc);
} else {
request.setCharacterEncoding(encod);
}
encod = null;
encod_wlc = null;


/*String uri = httpRequest.getServletPath();


UserSession userSession = (UserSession) httpRequest.getSession().getAttribute("userSession");
if (userSession != null && !uri.startsWith("/system.do")) {
userSession.setLastAccessedTime(DateUtils.getTimeInMillis());
}
// 忽略的URL
if (this.IGNORE_URLS != null) {
for (int i = 0; i < this.IGNORE_URLS.length; i++) {
if (uri.startsWith(IGNORE_URLS[i])) {
chain.doFilter(request, response);
return;
}
}
}


if (userSession == null) {
String url = httpRequest.getContextPath()+ this.LOGIN_URL;
if(uri.equals("/admin") || uri.equals("/supervisor")){
url=httpRequest.getContextPath()+"/superLogin.jsp";
}else{
if(!"/index.jsp".equals(uri)){
url = url +"&errMsg=already";
}
}
httpResponse.sendRedirect(url);
return;
}*/
   
chain.doFilter(request, response);

return;
}


public void destroy() {
this.encoding = null;
this.encoding_wlc = null;


log.info("过滤器注销了");
}
}

<!-- 过滤器 -->
<filter>
<filter-name>RequestFilter</filter-name>
<filter-class>com.fu.oa.util.RequestFilter</filter-class>


<!-- 登录URL -->
<!-- <init-param>
<param-name>loginUrl</param-name>
<param-value>/system.do?method=login</param-value>
</init-param>-->


<!-- 需要忽略的文件夹和页面,用;隔开 -->
<!-- <init-param>
<param-name>ignoreUrl</param-name>
<param-value>/system.do;/common.do;/form.do;/formQuery.do;/webOffice;/onlineUser.do;/AS_SYSTEM;/form/view/;/ocx;/error.jsp;/superLogin.jsp;/FCExporter.jsp;/exportExcel.jsp;/singLogin</param-value>
</init-param>-->


<!-- POST编码 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>


<!-- weblogic GET编码 -->
<init-param>
<param-name>encoding_wlc</param-name>
<param-value>GBK</param-value>
</init-param>


</filter>
<filter-mapping>
<filter-name>RequestFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>RequestFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>RequestFilter</filter-name>
<url-pattern>/admin</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>RequestFilter</filter-name>
<url-pattern>/supervisor</url-pattern>
</filter-mapping>

<welcome-file-list>
<welcome-file>/sysManage/user/loginUI.jsp</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

web.xml

第一篇:

SP指令标签中<%@ page contentType="text/html;charset=GB2312"%>这句有什么用途?
关于JSP页面中的pageEncoding和contentType两种属性的区别:
  pageEncoding是jsp文件本身的编码
  contentType的charset是指服务器发送给客户端时的内容编码
  JSP要经过两次的“编码”,第一阶段会用pageEncoding,第二阶段会用utf-8至utf-8,第三阶段就是由Tomcat出来的网页, 用的是contentType。
  第一阶段是jsp编译成.java,它会根据pageEncoding的设定读取jsp,结果是由指定的编码方案翻译成统一的UTF-8 JAVA源码(即.java),如果pageEncoding设定错了,或没有设定,出来的就是中文乱码。
  第二阶段是由JAVAC的JAVA源码至java byteCode的编译,不论JSP编写时候用的是什么编码方案,经过这个阶段的结果全部是UTF-8的encoding的java源码。
  JAVAC用UTF-8的encoding读取java源码,编译成UTF-8 encoding的二进制码(即.class),这是JVM对常数字串在二进制码(java encoding)内表达的规范。
  第三阶段是Tomcat(或其的application container)载入和执行阶段二的来的JAVA二进制码,输出的结果,也就是在客户端见到的,这时隐藏在阶段一和阶段二的参数contentType就发挥了功效
  contentType的設定.
  pageEncoding 和contentType的预设都是 ISO8859-1. 而随便设定了其中一个, 另一个就跟着一样了(TOMCAT4.1.27是如此). 但这不是绝对的, 这要看各自JSPC的处理方式. 而pageEncoding不等于contentType, 更有利亚洲区的文字 CJKV系JSP网页的开发和展示, (例pageEncoding=GB2312 不等于 contentType=utf-8)。
  jsp文件不像.java,.java在被编译器读入的时候默认采用的是操作系统所设定的locale所对应的编码,比如中国大陆就是GBK,台湾就是BIG5或者MS950。而一般我们不管是在记事本还是在ue中写代码,如果没有经过特别转码的话,写出来的都是本地编码格式的内容。所以编译器采用的方法刚好可以让虚拟机得到正确的资料。
  但是jsp文件不是这样,它没有这个默认转码过程,但是指定了pageEncoding就可以实现正确转码了。
  举个例子:
<%@ page contentType="text/html;charset=utf-8" %>
  大都会打印出乱码,因为输入的“你好”是gbk的,但是服务器是否正确抓到“你好”不得而知。
  但是如果更改为
<%@ page contentType="text/html;charset=utf-8" pageEncoding="GBK"%>
  这样就服务器一定会是正确抓到“你好”了。
 
Java中将数据由UTF8转换成GB2312格式
关键字: java字符编码
UTF8转换成GB2312 当我们在基于HTTP协议的JSP或Servlet的应用中获取数据或发送请求时,JVM会把输送的数据编码成UTF8格式。如果我们直接从HTTP流中 提取中文数据,提取的结果为“????”(可能更多问号),为转换成我们能够理解的中文字符,我们需要把UTF8转换成GB2312,借助ISO- 8859-1标准编码能够轻易的实现,下面的代码实现了这一功能:

byte [] b;
String utf8_value;
utf8_value = request.getParameter("NAME");//从HTTP流中取"NAME"的UTF8数据
b = utf8_value.getBytes("8859_1"); //中间用ISO-8859-1过渡
String name = new String(b, "GB2312"); //转换成GB2312字符

这是我做的一个项目程序的一段:
      byte[] b;
    String gbk_value;
    gbk_value=request.getParameter("address");//从HTTP流中取"name"的GBK数据(由于web.xml中过滤器设置默认编码为GBK,所以外网从UTF-8变为GBK)
    b=gbk_value.getBytes("GBK");//中间用GBK过渡,从GBK转换成GBK数组
    String address=new String(b,"utf-8");//转换成utf-8字符
    myform.setAddress(address);

在知道流长度的情况下将输入流转换成字节数组 Java中的输入流抽象类InputStream有int read(byte[] b, int off, int len)方法,参数中byte[] b是用来存放从InputStream中读取的数据,int off指定数组b的偏移地址,也就是数组b的起始下标,int len指定需要读取的长度,方法返回实际读取的字节数。

刚学Java 的朋友可能要说:先定义一个与流长度等长的字节数组,调用read方法,指定起始下标为0,指定读取长度与数组长度等长,不是一下子可以读出来了吗?说的 没错,笔者曾经也试着这样读取数据,但后来发现在读取网络数据时很不安全,我们想想在网络上获取数据可能并没那么流畅,数据流的传送可能会断断续续,所以 并不能保证一次就能读取全部数据,特别是在读取大容量数据时更是如此,所以我们必须在读取数据时检测实际读到的长度,如果没有读完已知长度的数据就应该再 次读取,以此循环检测,直到实际读取的长度累加与已知的长度相等,下面的代码实现了这一功能:

ServletInputStream inStream = request.getInputStream(); //取HTTP请求流
int size = request.getContentLength(); //取HTTP请求流长度
byte[] buffer = new byte[size]; //用于缓存每次读取的数据
byte[] in_b = new byte[size]; //用于存放结果的数组
int count = 0;
int rbyte = 0;
while (count < size) {
//循环读取
rbyte = inStream.read(buffer); //每次实际读取长度存于rbyte中
for(int i=0;i
在不知道流长度的情况下将输入流转换成字节数组 前面介绍了已知流长度的情况下的转换方法,那么当我们不知道流有多长时,也就是说不能确定转换后的字节数组有多大时,该怎么处理呢?笔者查看了JDK文档 之后发现ByteArrayOutputStream有一个byte[] toByteArray()方法,该方法会自动创建一个字节数组,然后返回。于是就巧妙的用ByteArrayOutputStream来作中间过渡实现 转换,其它处理跟上面所介绍已知长度的情况差不多。假设需要被转换的流已经放在inStream里了,我们可以用如下的代码实现这一功能:

ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
byte[] buff = new byte[100]; //buff用于存放循环读取的临时数据
int rc = 0;

while ((rc = inStream.read(buff, 0, 100)) > 0) {
swapStream.write(buff, 0, rc);
}
byte[] in_b = swapStream.toByteArray(); //in_b为转换之后的结果
JSP 中 pageEncoding charset 的区别
首先,说说JSP/Servlet中的几个编码的作用。
     在JSP/Servlet中主要有以下几个地方可以设置编 码,pageEncoding="UTF-8"、contentType="text/html;charset=UTF-8"、request.setCharacterEncoding("UTF-8")和 response.setCharacterEncoding("UTF-8"),其中前两个只能用于JSP中,而后两个可以用于JSP和Servlet 中。
1、pageEncoding="UTF-8"的作用是设置JSP编译成Servlet时使用的编码。
     众所周知,JSP在服务 器上是要先被编译成Servlet的。pageEncoding="UTF-8"的作用就是告诉JSP编译器在将JSP文件编译成Servlet时使用的 编码。通常,在JSP内部定义的字符串(直接在JSP中定义,而不是从浏览器提交的数据)出现乱码时,很多都是由于该参数设置错误引起的。例如,你的 JSP文件是以GBK为编码保存的,而在JSP中却指定pageEncoding="UTF-8",就会引起JSP内部定义的字符串为乱码。
     另外,该参数还有一个功能,就是在JSP中不指定contentType参数,也不使用response.setCharacterEncoding方法时,指定对服务器响应进行重新编码的编码。

2、contentType="text/html;charset=UTF-8"的作用是指定对服务器响应进行重新编码的编码。
    在不使用response.setCharacterEncoding方法时,用该参数指定对服务器响应进行重新编码的编码。
 
3、request.setCharacterEncoding("UTF-8")的作用是设置对客户端请求进行重新编码的编码。
      该方法用来指定对浏览器发送来的数据进行重新编码(或者称为解码)时,使用的编码。

4、response.setCharacterEncoding("UTF-8")的作用是指定对服务器响应进行重新编码的编码。
     服务器在将数据发送到浏览器前,对数据进行重新编码时,使用的就是该编码。

    其次,要说一说浏览器是怎么样对接收和发送的数据进行编码的
    response.setCharacterEncoding("UTF- 8")的作用是指定对服务器响应进行重新编码的编码。同时,浏览器也是根据这个参数来对其接收到的数据进行重新编码(或者称为解码)。所以在无论你在 JSP中设置response.setCharacterEncoding("UTF-8")或者 response.setCharacterEncoding("GBK"),浏览器均能正确显示中文(前提是你发送到浏览器的数据编码是正确的,比如正 确设置了pageEncoding参数等)。读者可以做个实验,在JSP中设置response.setCharacterEncoding("UTF- 8"),在IE中显示该页面时,在IE的菜单中选择"查看(V)"à"编码(D)"中可以查看到是" Unicode(UTF-8)",而在在JSP中设置response.setCharacterEncoding("GBK"),在IE中显示该页面 时,在IE的菜单中选择"查看(V)"à"编码(D)"中可以查看到是"简体中文(GB2312)"。
     浏览器在发送数据时,对URL和参数会 进行URL编码,对参数中的中文,浏览器也是使response.setCharacterEncoding参数来进行URL编码的。以百度和 GOOGLE为例,如果你在百度中搜索"汉字",百度会将其编码为"%BA%BA%D7%D6"。而在GOOGLE中搜索"汉字",GOOGLE会将其编 码为"%E6%B1%89%E5%AD%97",这是因为百度的response.setCharacterEncoding参数为GBK,而 GOOGLE的的response.setCharacterEncoding参数为UTF-8。
      浏览器在接收服务器数据和发送数据到服务器 时所使用的编码是相同的,默认情况下均为JSP页面的response.setCharacterEncoding参数(或者contentType和 pageEncoding参数),我们称其为浏览器编码。当然,在IE中可以修改浏览器编码(在IE的菜单中选择"查看(V)"à"编码(D)"中修 改),但通常情况下,修改该参数会使原本正确的页面中出现乱码。一个有趣的例子是,在IE中浏览GOOGLE的主页时,将浏览器编码修改为"简体中文 (GB2312)",此时,页面上的中文会变成乱码,不理它,在文本框中输入"汉字",提交,GOOGLE会将其编码为"%BA%BA%D7%D6",可 见,浏览器在对中文进行URL编码时,使用的就是浏览器编码。
     弄清了浏览器是在接收和发送数据时,是如何对数据进行编码的了,我们再来看看服务器是在接收和发送数据时,是如何对数据进行编码的。
     对于发送数据,服务器按照response.setCharacterEncoding—contentType—pageEncoding的优先顺序,对要发送的数据进行编码。
     对于接收数据,要分三种情况。一种是浏览器直接用URL提交的数据,另外两种是用表单的GET和POST方式提交的数据。
   因为各种WEB服务器对这三种方式的处理也不相同,所以我们以Tomcat5.0为例。
     无论使用那种方式提交,如果参数中包含中文,浏览器都会使用当前浏览器编码对其进行URL编码。
     对于表单中POST方式提交的数据,只要在接收数据的JSP中正确request.setCharacterEncoding参数,即将对客户端请求进行重 新编码的编码设置成浏览器编码,就可以保证得到的参数编码正确。有写读者可能会问,那如何得到浏览器编码呢?上面我们提过了,在默认请情况下,浏览器编码 就是你在响应该请求的JSP页面中response.setCharacterEncoding设置的值。所以对于POST表单提交的数据,在获得数据的 JSP页面中request.setCharacterEncoding要和生成提交该表单的JSP页面的 response.setCharacterEncoding设置成相同的值。
     对于URL提交的数据和表单中GET方式提交的数据,在接收数 据的JSP中设置request.setCharacterEncoding参数是不行的,因为在Tomcat5.0中,默认情况下使用ISO- 8859-1对URL提交的数据和表单中GET方式提交的数据进行重新编码(解码),而不使用该参数对URL提交的数据和表单中GET方式提交的数据进行 重新编码(解码)。要解决该问题,应该在Tomcat的配置文件的Connector标签中设置useBodyEncodingForURI或者 URIEncoding属性,其中useBodyEncodingForURI参数表示是否用request.setCharacterEncoding 参数对URL提交的数据和表单中GET方式提交的数据进行重新编码,在默认情况下,该参数为false(Tomcat4.0中该参数默认为 true);URIEncoding参数指定对所有GET方式请求(包括URL提交的数据和表单中GET方式提交的数据)进行统一的重新编码(解码)的编 码。URIEncoding和useBodyEncodingForURI区别是,URIEncoding是对所有GET方式的请求的数据进行统一的重新 编码(解码),而useBodyEncodingForURI则是根据响应该请求的页面的request.setCharacterEncoding参数 对数据进行的重新编码(解码),不同的页面可以有不同的重新编码(解码)的编码。所以对于URL提交的数据和表单中GET方式提交的数据,可以修改 URIEncoding参数为浏览器编码或者修改useBodyEncodingForURI为true,并且在获得数据的JSP页面中 request.setCharacterEncoding参数设置成浏览器编码。

下面总结下,以Tomcat5.0为WEB服务器时,如何防止中文乱码。
1、对于同一个应用,最好统一编码,推荐为UTF-8,当然GBK也可以。
2、正确设置JSP的pageEncoding参数
3、在所有的JSP/Servlet中设置contentType="text/html;charset=UTF-8"或response.setCharacterEncoding("UTF-8"),从而间接实现对浏览器编码的设置。
4、 对于请求,可以使用过滤器或者在每个JSP/Servlet中设置request.setCharacterEncoding("UTF-8")。同时, 要修改Tomcat的默认配置,推荐将useBodyEncodingForURI参数设置为true,也可以将URIEncoding参数设置为 UTF-8(有可能影响其他应用,所以不推荐)。


第二篇


pageEncoding
     
 在JSP标准的语法中,如果 pageEncoding属性存在,那么JSP页面的字符编码方式就由pageEncoding决定,否则就由contentType属性中的 charset决定,如果charset也不存在,JSP页面的字符编码方式就采用默认的ISO-8859-1。

 

 

 

ContentType 
     ContentType属性指定了MIME类型和JSP页面回应时的字符编码方式。MIME类型的默认值是“text/html”; 字符编码方式的默认值是“ISO-8859-1”. MIME类型和字符编码方式由分号隔开

pageEncoding的内容只是用于jsp输出时的编码,不会作为header发出去的。

pageEncoding   是通知web server jsp的编码。

关于JSP页面中的pageEncoding和contentType两种属性的区别: 

pageEncoding是jsp文件本身的编码 

contentType的charset是指服务器 发送给客户端时的内容编码 

JSP要经过两次的“编码”,第一阶段会用pageEncoding,第二阶段会用utf-8至utf-8,第三阶段就是由Tomcat出来的网页, 用的是contentType。 

第一阶段是jsp编译成.java,它会根据pageEncoding的设定读取jsp,结果是由指定的编码方案翻译成统一的UTF-8 JAVA源码(即.java),如果pageEncoding设定错了,或没有设定,出来的就是中文乱码。 

第二阶段是由JAVAC的JAVA源码至java byteCode的编译,不论JSP编写时候用的是什么编码方案,经过这个阶段的结果全部是UTF-8的encoding的java源码。 

JAVAC用UTF-8的encoding读取java源码,编译成UTF-8 encoding的二进制码(即.class),这是JVM对常数字串在二进制码(java encoding)内表达的规范。 

第三阶段是Tomcat(或其的application container)载入和执行阶段二的来的JAVA二进制码,输出的结果,也就是在客户端见到的,这时隐藏在阶段一和阶段二的参数contentType就发挥了功效 

contentType的設定. 

pageEncoding 和contentType的预设都是 ISO8859-1. 而随便设定了其中一个, 另一个就跟着一样了(TOMCAT4.1.27是如此). 但这不是绝对的, 这要看各自JSPC的处理方式. 而pageEncoding不等于contentType, 更有利亚洲区的文字 CJKV系JSP网页的开发和展示, (例pageEncoding=GB2312 不等于 contentType=utf-8)。 

jsp 文件不像.java,.java在被编译器读入的时候默认采用的是操作系统所设定的locale所对应的编码,比如中国大陆就是GBK,台湾就是BIG5 或者MS950。而一般我们不管是在记事本还是在ue中写代码,如果没有经过特别转码的话,写出来的都是本地编码格式的内容。所以编译器采用的方法刚好可 以让虚拟机得到正确的资料。 

但是jsp文件不是这样,它没有这个默认转码过程,但是指定了pageEncoding就可以实现正确转码了。 

举个例子: 


<%@ page contentType="text/html;charset=utf-8" %>


大都会打印出乱码,因为我输入的“你好吗”是gbk的,但是服务器 是否正确抓到“你好吗”不得而知。 

但是如果更改为 


<%@ page contentType="text/html;charset=utf-8" pageEncoding="GBK"%>


这样就服务器 一定会是正确抓到“你好吗”了。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值