如果你的主要工作就是开发或测试一个动态国际化Java Web项目,那么如下图所示的编码处理问题想必是“大宝天天见”咯。那么作为开发和测试人员,面对这样高频的事件,又需要怎样应对呢?本文将尝试从两个不同角度来分析在这样的技术背景下,我们需要注意哪些国际化知识点。
首先对于开发人员来说,需要注意的是:
一、HTML中的metacontent
确保每一个HTML头部都包含有正确的编码信息,通过metacontent字段进行设置。
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
二、在JSP中contentType的charset和pageEncoding
务必明示pageEncoding属性用来确定JSP编译器使用何种编码。
<%@ page language="java"contentType="text/html; charset=utf-8"pageEncoding="utf-8"%>
三、Tomcat的server.xml
处理完page content,接下来需要考虑的就是处理client发来的数据。大多数应用程序容器都会将码表写死,例如Apache Tomcat默认的就是ISO-8859-1,所以这里务必用UTF-8来配置connector来处理GET请求。
<Connector port="8080" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" compression="on" compressionMinSize="128" noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml,text/plain,text/css,text/ javascript,application/x-javascript,application/javascript" URIEncoding="UTF-8" />
这样一来,Tomcat将所有得到的参数按照UTF-8进行编码。因此,当用户将以下地址写入浏览器的地址栏时,曼城按照UTF-8编码将会encode成为曼城。
https://localhost:8443/ID/Users?action=search&name=曼城
但需要注意的是POST请求不会因此而改变。
四、Filter
千呼万唤始出来,终于轮到Filter登场了!除了修改上述内容,作为一个开发人员,我们务必指定一个EncodingFilter来强制webapp用UTF-8来处理所有request+ response。示意代码如下:
public class EncodingFilter implements Filter { private String encoding = "utf-8"; public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { //设置request编码 request.setCharacterEncoding(encoding); //设置response编码 response.setContentType("text/html;charset=" + encoding); response.setCharacterEncoding(encoding); filterChain.doFilter(request, response); } public void init(FilterConfig filterConfig) throws ServletException { String encodingParam = filterConfig.getInitParameter("encoding"); if (encodingParam != null) { encoding = encodingParam; } } public void destroy() { } }除此之外,我们还需要把filter添加到web.xml文件中,这样就能在每一个request发生之前,filter都会被执行。
<filter> <filter-name>EncodingFilter</filter-name> <filter-class> com.g11n.filters.EncodingFilter </filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>EncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>五、JDBC connection
一旦需要使用DB,就得配置JDBC链接。进入到context.xml中,添加如下内容。
<Resource name="jdbc/AppDB" auth="Container" type="javax.sql.DataSource" maxActive="20"maxIdle="10" maxWait="10000" username="g11n" password="***" driverClassName="com.mysql.jdbc.Driver"url="jdbc:mysql://localhost:3306/ ID_development?useEncoding=true&characterEncoding=UTF-8" />而关于数据库方面,也还有一些国际化关注点,但已经超越了本文的范围,本文不多累述。
换个角度,再来说说测试人员吧。我猜细心的测试人员一定已经准备好了一堆用例来进行验证,“凭尔几路来,我只一路去!”。必须承认,这样传统的黑盒业务覆盖测试方法肯定是行之有效的,但不得不说,效率却相当的低。如果在测试时间被压缩到很紧的情况下,传统的方式就不再行的通啦!可是一旦面对这样的在情况,测试人员要怎么做呢?
有人说,加班完成呗!呃~~~这位兄台,您慢走,我就不送了!……但送走这位仁兄后,活儿还在那里,只增不减啊!怎么破?这里提供一种我的解法,供大家参考吧。
1、 首先确保你能读到产品代码。(如否,请回归传统黑盒业务覆盖)
2、 针对本文提到的五点,分别针对其实现代码进行验证,必要时添加单元测试用例。
友情提示!针对代码的验证也可以分为手动、自动两种。一旦使用了自动脚本,请勿用其抢月饼,否则后果自负!
3、 无需部署真实测试环境,仅对上述五点代码进行验证。任何一点不满足要求,立刻报bug就是了。
4、 完成对上述五点的测试后,相信项目中不会再有编码问题出现了。如果此刻时间还有富余,那么就可以对layout,format之类的检查酌情而定了。