1 引言
Web开发的页面出现了乱码,一直不愿写出来,因为网上的解决方案太多了。但本文的所说的页面乱码问题,则是与网上的大多数解决方案不一样,使用通常的方法解决不了。这些通常的解决方法包括:
- 在出现乱码的jsp页面源文件的头部写:
<% request.setCharacterEncoding("utf-8"); %>
; - 在出现乱码的jsp页面源文件中的
<head>
标签中写入:
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
于是,本博文的写作动力就有了。
2 乱码表现、原因分析及解决
2.1 乱码表现
本项目是基于Struts 2构建的,struts.xml中涉及到乱码的action为getBooks,内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="teststruts" extends="struts-default" namespace="/">
<action name="login" class="com.rob.teststruts.action.LoginAction">
<result name="error">/error.jsp</result>
<result name="success">/welcome.jsp</result>
</action>
<action name="getBooks" class="com.rob.teststruts.action.GetBooksAction">
<result name="login">/loginForm.jsp</result>
<result name="success">/showBook.jsp</result>
</action>
</package>
</struts>
展示页面showBook.jsp的内容如下:
<%@ page language="java" pageEncoding="UTF-8" errorPage="" %>
<%@ page import="java.util.*, com.opensymphony.xwork2.util.*" %>
<!DOCTYPE html>
<html>
<head>
<title>作者李刚的图书</title>
</head>
<body>
<table border="1" width="360">
<caption>作者李刚的图书</caption>
<%
// 获取封装输出信息的ValueStack对象
ValueStack vs = (ValueStack)request.getAttribute("struts.valueStack");
String[] books = (String[])vs.findValue("books");
for (String book: books) {
%>
<tr>
<td>书名:</td>
<td><%=book%></td>
</tr>
<%}%>
</table>
</body>
</html>
项目部署、启动Tomcat后,出现如下乱码:
2.2 原因分析
利用引言中介绍的两种方法无法解决该问题,乱码仍然出现。忽然想到,BookService.java源文件本身是UTF-8编码,在Windows cmd下编译时没指定编码方式,会默认GBK编码,但对该文件的编译缺没报错。若一个UTF-8编码的java源文件中的注释中包含汉字,则编译时会提示如下:
所以,对源文件BookService.java来说,其中只有字符串中有汉字,没提示报错。最大的原因在于该文件编译时没指定utf-8编码。BookService.java的内容如下:
package com.rob.teststruts.service;
public class BookService {
private String[] books = new String[] {
"疯狂Java讲义",
"疯狂Android讲义",
"轻量级Java EE 企业应用实战",
"疯狂Ajax讲义",
"疯狂XML讲义",
};
// business logic method
public String[] getLeeBooks(){
return books;
}
}
2.3 解决
对源文件BookService.java按如下方式编译,指定编码方式:
javac -encoding utf-8 -d classes src\com\rob\teststruts\service\BookService.java
用生成的BookService.class文件替换部署环境中的旧的BookService.class,重启Tomcat,访问网址,成功解决乱码,如下图:
3 总结
这是个共性问题,只要是基于Java Web开发的项目,只要utf-8编码的源文件编译时没指定utf-8编码方式,都会遇到这个乱码问题。该问题用通常的乱码解决方法行不通。这里愿意与大家交流,有问题请大家私信。
大家注意,只要源文件是utf-8编码格式的,最好在编译时也指定utf-8编码方式。
本文例子选自书籍《Struts 2.x 权威指南》1第29页。书中代码未包含import部分、package部分,对编译过程也没提到,大家在阅读时要注意自行补上。实际上,有一定基础的人,都可以毫无困难地复现书中例子。在此,感谢作者提供的例子,虽然该例子没考虑到编码问题,这不是作者的问题。
李刚. Struts 2.x 权威指南. 第3版. 北京: 电子工业出版社, 2012.10: 29. ↩︎