老生常谈--关于J2EE开发中的字符编码

来源:互联网 发布:棋牌游戏网站源码 编辑:程序博客网 时间:2024/05/29 14:52

这几天发现团队中的几个新成员对于开发中的编码理解的不是很好,特意写这篇文章,帮助大家理解。


首先,我们明确我们的目标在我们的工程中全部使用UTF-8编码。

其次,我们需要了解开发中解除到的编码包括文件内容编码、请求参数编码、返回内容编码。


文件内容编码

首先我们讨论文件内容编码。jsp页面是我们MVC模式中的View,是展现到前台的页面,所以这个页面必须要支持多字节字符串(日常主要是中文),我们必须为其设置编码格式。

我们先看一个简单的jsp示例文件:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>中文页面</title></head><body><h1>您好,这个页面支持中文。</h1></body></html>

注意:

  1. 每个JSP文件的pageEncoding是基础,只有你设置了这个,tomcat在请求过来时将JSP文件转换为java文件(servlet源文件)的时候才会将其转换为非乱码格式,否则如果你将pageEncoding设置为US-ASCII,文件中的中文都会是乱码了;
  2. JSP头部的contentType和html部分的meta中的Content-Type其实是一回事,都是设置最后展现的时候告诉浏览器这个页面的字符集,如果这里指定的字符集浏览器中没有安装,正常情况下浏览器会提示去安装,和具体显示不太搭界。
  3. contentType中的charset还有个作用就是设置我们的请求响应的编码,也就是说,如果我们提交请求的时候使用的编码格式不正确,那么最后输出的结果可能也不正确,具体在servlet中我们可以通过pageContext.getResponse().getCharacterEncoding()得到这些值;

所以按照以上理论,正常情况下我们只需要设置pageEncoding就可以了,但为了支持有些用户使用的英文系统,为了提示使用者去下载中文支持,需要添加contentType。


请求参数编码

struts中使用

首先我们看一下struts2中如何使用字符编码。我们建立一个简单的struts2工程,写一个DummyAction:

package com.freesoft.action;import com.opensymphony.xwork2.ActionSupport;public class DummyAction extends ActionSupport {/** *  */private static final long serialVersionUID = -9106994256206918756L;private String username;private String password;private Integer age;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String execute() throws Exception {System.out.println("username is " + username);System.out.println("password is " + password);System.out.println("age is " + age);return SUCCESS;}}

我们的请求页面是:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><%@ taglib prefix="s" uri="/struts-tags" %><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>中文网页</title></head><body><h1>中文网页测试</h1><s:form action="dummy.action"><s:textfield name="username" label="username"></s:textfield><s:textfield name="password" label="password"></s:textfield><s:textfield name="age" label="age"></s:textfield><s:submit value="submit"></s:submit></s:form></body></html>

结果页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><%@ taglib prefix="s" uri="/struts-tags" %><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body><s:label value="%{username}"></s:label></body></html>

我们在请求中输入中文的名字,发现可以正确处理中文。那么我们再去深入,当你在你的struts.xml配置文件的package外面加上:

<constant name="struts.i18n.encoding" value="US-ASCII"></constant>
的时候,再去使用中文名,就会出现乱码,说明是i18n这个interceptor中的encoding属性设定了字符编码格式。我们去源码中也可以很清楚的看到默认的编码格式设置的是在org.apache.struts2.dispatcher.Dispatcher文件中使用注解方式注入。文件default.properties中就设置了这个值:

### This can be used to set your default locale and encoding scheme# struts.locale=en_USstruts.i18n.encoding=UTF-8

所以我们可以自己去覆盖这个值。


Servlet方式

好了,struts方式搞定了之后能够保证我们的工作不出问题,下面我们随便讲讲servlet工作的流程:

servlet默认情况下是不会处理字符编码的,所以在request和response中都要你自己设置,我们看一下源代码(原来在tomcat/webapp下面的,从tomcat 7.0.20就转移到tomcat自己的源码中了,所以还需要下载一个tomcat源代码),这个类:org.apache.catalina.filters.SetCharacterEncodingFilter。



让我们再看看Tomcat给的建议,保证你在所有地方都是用UTF-8:

  1. 在server.xml的Connector中设置URIEncoding="UTF-8",类似于这种:
    <Connector port="8090" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"enableLookups="false" redirectPort="8443" acceptCount="100"debug="0" connectionTimeout="20000"disableUploadTimeout="true"URIEncoding="UTF-8"/>

  2. 使用一个filter来使得编码转换为UTF-8,可以使用Tomcat提供的这个;
  3. 在jsp中设置contentType使用UTF-8;
  4. 使response的输出都使用UTF-8,也就是使用:
    response.setContentType("text/html; charset=UTF-8")
    或者
    response.setCharacterEncoding("UTF-8")
  5. 你使用的任何会产生内容的库(例如Velocity, Freemarker,等等)中的编码设置都设置为UTF-8。
  6. 在所有可能读取参数的情况之前加载你的编码转换Filter;




原创粉丝点击