在进行web应用程序开发的过程中中文问题经常困扰着很多程序员因此在接下来的两个课程的学习中我将根据实践经验来谈一下web应用中的中文问题的解决方法让大家不再为此而头痛
我们就前那个登录验证的例子进行进阶处理中文乱码问题前面例子中只要用户名和密码都是才返回成功的页面为了处理中文我们判断只有用户名是张三才登陆成功
一程序进阶
既然是中文乱码处理页面的用户输入就是中文了相应的action的if处理也要变成: if (usernameequals(张三) &&userpassequals())
效果图
我们以结果为导向首先大家先看看要完成的效果图对接下来要做的事情有个清晰的认识
如图键入中文
显示结果如下图
为什么会到错误页面呢?我们明明都写正确了呀是的没有错误这是什么原因呢?
请看下图
我们打印才发现原来username的值传到action中成了乱码这主要由于客户端和服务器端采用了不同的字符集中文乱码我们没有处理
二解决办法
A直接转编码
我们新建一个包命名为util在包下新建一个类文件命名为EncodingUtil类的功能就是提供一个字符集转换的一个方法具体代码如下所示
package util;
public class Encoding {
public static String isToGB(String src) {
String strRet = null;
try {
strRet = new String(srcgetBytes(ISO__) GBK);
} catch (Exception e) {
eprintStackTrace();
}
return strRet;
}
}
小结这办法虽然能解决中文乱码但是每次还得调用是不是很不方便呢?如果忘记了调用这个方法那程序又乱码了维护起来很困难下面我们看另一种解决方案
B继承RequestProcessor类
RequestProcessor类处理ActionServlet接收到的所有请求根据它的处理方式可将每个请求分解为多个小任务分别由不同的方法执行这就允许针对请求的各个单独部分自定义处理
RequestProcessor类的部分方法如下
processPath() 获取客户端请求的路径URI
processMapping() 根据请求URI获取所需的映射信息
processRoles() 检查用户的角色是否允许他访问请求的资源
processActionForm() 新建一个Form Bean或从请求会话中检索Form Bean
processForward() 处理元素forward以匹配当前的请求路径
processValidate() 调用Form Bean的validate()方法
processPreprocess() 告诉请求处理器调用此方法后是否应继续处理请求
processLocale() 为请求选择一个语言环境
processActionCreate() 实例化当前ActionMapping指定的类的实例
processActionPerform() 将调用action的perform()或execute()方法
呵呵发没发现RequestProcess类的所有方法都有一个前缀proess接着往下看吧
RequestProcessor在action之前所以我们应着手RequestProcessor要开发自己的RequestProcessor类步骤如下
() 创建一个继承orgapachestrutsactionRequestProcessor的类在改类中显示定义一个无参方法体为空的构造器
() 重写所需的方法加入我们的功能
具体代码如下所示
package servlets;
import javaioUnsupportedEncodingException;
import javaxservlethttpHttpServletRequest;
import javaxservlethttpHttpServletResponse;
import orgapachestrutsactionRequestProcessor;
public class EncodingHandler extends RequestProcessor {
public boolean processPreprocess(HttpServletRequest servletRequest
HttpServletResponse serveltResponse) {
try {
servletRequestsetCharacterEncoding(GBK);
Systemoutprintln(请求被处理);
} catch (UnsupportedEncodingException ex) {
exprintStackTrace();
}
return true;
}
}
() 修改配置文件sturtsconfigxml在其中加入一个名为的元素用以指定我们定制的RequestProcessor类
<?xml version= encoding=UTF?>
<!DOCTYPE strutsconfig PUBLIC //Apache Software Foundation//DTD Struts Configuration //EN config__dtd>
<strutsconfig>
<formbeans>
<formbean name=loginActionForm type=formbeansLoginActionForm />
</formbeans>
<actionmappings>
<action
path=/login
name=loginActionForm
scope=request
type=actionsLoginAction>
<forward name=success path=/successjsp/>
<forward name=error path=/wrongjsp/>
</action>
</actionmappings>
<controller processorClass=servletsEncodingHandler />
</strutsconfig>
上面就是我们自己的定义的RequestProcessor类使用标签类定义
如图
小结这样做呢?问题是解决了每一个请求先经过这个方法并转换了字符集再交给action做处理这样我们不用在操心中文乱码但RequestProcessor是与struts耦合在一块儿如果不用struts框架我们又该如何处理中文问题呢?是否又更好的办法呢?那就接着跟我往下看吧
CFilter来解决中文问题
Filter是不是你脑子里闪现了这个词呢?下面就来看看如何用它来改写我们上一章节的例子吧!
() 首先在工程中新建一包命名为filter在下面新建一类文件命名为EncodingServlet并继承HttpServlet实现Filter接口注意并实现接口的方法
在Servlet中filter起着过滤器的作用当一个请求发送到服务器的时候需要把请求首先交给filter来处理然后交给action做处理EncodingServlet负责处理请求的字符集在此就起这么个功能具体代码请依照如下所示
package servlets;
import javaxservletFilter;
import javaxservletFilterChain;
import javaxservletFilterConfig;
import javaxservletServletException;
import javaxservletServletRequest;
import javaxservletServletResponse;
import javaxservlethttpHttpServlet;
public class EncodingServlet extends HttpServlet implements Filter {
private static final long serialVersionUID = L;
public void doFilter(ServletRequest servletRequest
ServletResponse serveltResponse FilterChain filterChain) {
try {
servletRequestsetCharacterEncoding(GBK);
filterChaindoFilter(servletRequest serveltResponse);
} catch (Exception ex) {
}
}
public void init(FilterConfig arg) throws ServletException {
}
}
() 修改webxml加入我们的filter
EncodingServlet
servletsEncodingServlet
EncodingServlet
/*
小结这个中文乱码处理用了fileter而且适用与任何场合比较实用
怎么样通过三个处理中文乱码的方案有和感想呀是不是程序很有意思呀那就跟着我继续看看struts别的东东吧……