原文:开发基于JBoss AS 7.2.0的Java EE程序 - 08.如何设置UTF-8
英文:JBoss AS 7.2.0 - Java EE application development - 08.How to configure UTF-8
概述
为了能够让我们的Java EE程序显示中文,英文,等多国文字,我们需要在很多地方设置UTF-8编码格式。缺一不可!
1. MySql数据库编码设置
请参见 CentOS 6.4安装MySql Server和Client,设置字符集为UTF-8,修改登陆密码
一文中的 链接
。
2. ServletRequest和ServletResponse编码设置
我们通过Servlet Filter将所有ServletRequest和ServletResponse的编码格式设置为UTF-8。
package com.ybxiang.forum.servlet.filter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.logging.Logger;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ybxiang.forum.jsfmbean.ParameterHelper;
/**
* http://bbs.csdn.net/topics/300037688
* @author yingbinx
*
*/
@javax.servlet.annotation.WebFilter("/*")
public class EncodingFilter implements Filter {
static final Logger logger = Logger.getLogger(EncodingFilter.class.getName());
//FilterConfig config;
public void doFilter(ServletRequest r1, ServletResponse r2, FilterChain chain)throws ServletException,IOException {
HttpServletRequest request = (HttpServletRequest)r1;
HttpServletResponse response = (HttpServletResponse)r2;
try {
request.setCharacterEncoding(ParameterHelper.ENCODING);
response.setCharacterEncoding(ParameterHelper.ENCODING);
} catch (UnsupportedEncodingException e) {
logger.severe(e.getMessage());
}
//WARNING: do NOT swallow any Exception!!! If container can not see any exception, it will not redirect client to related error page.
//You can catch Exceptions and print them, and you must throw them at last!
chain.doFilter(r1, r2);
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig arg0) throws ServletException {
//config = arg0;
}
}
其中ParameterHelper.ENCODING 的定义:
public class ParameterHelper{
static final Logger logger = Logger.getLogger(ParameterHelper.class.getName());
public static final String ENCODING = "UTF-8";
...
}
3. ServletResponse编码设置
如果我们的Servlet要想客户端(浏览器)写入一些字符,那么也要设置UTF-8。
当然我们在前面已经对所有的Servlet的请求和相应设置过UTF-8编码格式了,这里是否需要这么做,本人没有测试过。
@WebServlet("/UploadPortraitServlet")
public class UploadPortraitServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
....
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
...
}
...
}
4. web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>PARAMETER_ENCODING</param-name>
<param-value>UTF-8</param-value>
</context-param>
<!-- Production,Development,UnitTest,SystemTest,Extension -->
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
...
}
5. jboss-web.xml
如果所有地方都设置了UTF-8,唯独这里没有设置UTF-8,那么中文用户名进行JAAS登陆会失败。
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<security-domain>java:/jaas/ybxiang-forum-jaas-security-domain</security-domain>
<!-- encoding for login servlet 'j_security_check' -->
<valve>
<class-name>org.apache.catalina.authenticator.FormAuthenticator</class-name>
<param>
<param-name>characterEncoding</param-name>
<param-value>UTF-8</param-value>
</param>
</valve>
</jboss-web>
6. faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.1" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_1.xsd">
...
</faces-config>
7. JSF pages
(a) 常规页面
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
...
</html>
(b) 组件(component)页面
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
...
</ui:composition>
8. JSF MBean中解析URL中的UTF-8参数
比如,我们的访问
http://javaarm.com/faces/list.xhtml?mid=42&keywords=介绍
或者
http://javaarm.com/faces/list.xhtml?mid=42&keywords=%E4%BB%8B%E7%BB%8D
那么,我就需要在TopicGroupingPagerMBean.java中对“keywords”这个参数进行UTF-8解码!
@ManagedBean
@RequestScoped
public class TopicGroupingPagerMBean extends AbstractPagerMBean{
static final Logger logger = Logger.getLogger(TopicGroupingPagerMBean.class.getName());
...
//*****************************************[地址参数]*****************************************//
...
public final String getKeywords(){
String keywords = ParameterHelper.getString(ParameterHelper.URL_PARAMETER_NAME_KEYWORDS);
if(keywords==null || keywords.trim().length()==0){
return "";
}
try{
keywords = java.net.URLDecoder.decode(keywords, ParameterHelper.ENCODING);
}catch(Exception e){
Log.error(e);
}
return keywords;
}
...
}其中 ParameterHelper为:
public class ParameterHelper{
public static final String ENCODING = "UTF-8";
...
public static String getString(String parameterName) {
//logger.info("ParameterName:"+parameterName);
//Map mp = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
@SuppressWarnings("rawtypes")
Map mp = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
if (mp == null || mp.isEmpty()) {
//logger.info("parameters are null");
return null;
} else {
Object obj_by_paramId = mp.get(parameterName);
Object obj_by_formIdPlusParamId = mp.get(FORM_ID+":"+parameterName);
if(obj_by_paramId!=null){
return obj_by_paramId.toString();
}else if(obj_by_formIdPlusParamId!=null){
return obj_by_formIdPlusParamId.toString();
}else{
// logger.severe(parameterName+" has NO value!!!");
return null;
}
}
}
9. JBoss AS 7 的 standalone.xml UTF-8设置
(a) JAAS hashCharset
<subsystem xmlns="urn:jboss:domain:security:1.2">
<security-domains>
<security-domain name="ybxiang-forum-jaas-security-domain" cache-type="default">
<authentication>
<login-module code="Remoting" flag="optional">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
<login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
<module-option name="password-stacking" value="useFirstPass"/>
<module-option name="dsJndiName" value="java:jboss/datasources/ybxiangForumMySqlDataSource"/>
<module-option name="principalsQuery" value="SELECT hashedPassword FROM User WHERE username=? and activated=true and locked=false"/>
<module-option name="rolesQuery" value="SELECT DISTINCT r.name, 'Roles' FROM User u, User_UserGroup ug, UserGroup_JaasRole gr, JaasRole r WHERE u.id=ug.user_id AND ug.usergroup_id=gr.usergroup_id AND gr.jaasrole_id=r.id AND u.username=?"/>
<module-option name="hashAlgorithm" value="SHA-256"/>
<module-option name="hashEncoding" value="Base64"/>
<module-option name="hashCharset" value="UTF-8"/>
<module-option name="unauthenticatedIdentity" value="guest"/>
</login-module>
</authentication>
</security-domain>
...
...
...
Comments