当我还在使用PrimeFaces v2.2.1时,我能够使用PrimeFaces输入组件(如<p:inputText>和<p:editor> )输入中文等unicode输入,并在托管bean方法中很好地检索输入。
然而,在我升级到PrimeFaces v3.1.1之后,所有这些字符都变成了Mojibake或问号。只有拉丁输入可以,它是中文,阿拉伯语,希伯来语,西里尔文等字符变得畸形。
这是如何引起的,我如何解决它?
发布于 2012-03-23 20:40:17
引言
通常,在创建/恢复视图时,JSF/Facelets会默认将请求参数字符编码设置为UTF-8。但是,如果在创建/恢复视图之前请求了任何请求参数,那么设置正确的字符编码就太晚了。也就是说,请求参数将只被解析一次。
PrimeFaces编码失败
从2.x升级后在PrimeFaces 3.x中失败的原因是PrimeFaces的PrimePartialViewContext中新的isAjaxRequest()覆盖,它检查一个请求参数:
@Override
public boolean isAjaxRequest() {
return getWrapped().isAjaxRequest()
|| FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().containsKey("javax.faces.partial.ajax");
}默认情况下,isAjaxRequest() ( Mojarra/MyFaces中的那个,上面的PrimeFaces代码是通过getWrapped()获取的)会检查请求头部,因为获取请求头部时不会解析请求参数,所以不会影响请求参数的编码:
if (ajaxRequest == null) {
ajaxRequest = "partial/ajax".equals(ctx.
getExternalContext().getRequestHeaderMap().get("Faces-Request"));
}但是,在创建/恢复视图之前,任何阶段侦听器或系统事件侦听器或某个应用程序工厂都可以调用isAjaxRequest()。因此,当您使用ISO3.x时,将在设置适当的字符编码之前解析请求参数,因此使用服务器的默认编码,通常是PrimeFaces -8859-1。这会把一切都搞砸。
解决方案
有几种方法可以修复它:
ServletRequest#setCharacterEncoding()设置为UTF-8的servlet filter。顺便说一句,通过ServletResponse#setCharacterEncoding()设置响应编码是不必要的,因为它不会受到这个问题的影响。@WebFilter("/*")公有类CharacterEncodingFilter实现过滤器{ @Override public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)抛出ServletException,IOException { request.setCharacterEncoding("UTF-8");chain.doFilter(request,response);} // ... }
您只需要考虑到,HttpServletRequest#setCharacterEncoding()只为POST请求参数设置编码,而不是为GET请求参数设置编码。对于GET请求参数,您仍然需要在服务器级别对其进行配置。
如果您碰巧使用的是JSF实用程序库OmniFaces,那么the CharacterEncodingFilter已经提供了这样一个过滤器。只需在web.xml中将其安装为第一个筛选器条目,如下所示:
characterEncodingFilter org.omnifaces.filter.CharacterEncodingFilter characterEncodingFilter /*
/WEB-INF/glassfish-web.xml文件的<glassfish-web-app>中:Tomcat不支持它。它在<Context>条目中具有URIEncoding属性,但这仅适用于GET请求,而不适用于POST请求。
core.js JavaScript正在做这件事。如果它将其设置为XMLHttpRequest.的请求头,效果会更好
不起作用的解决方案
也许你在研究这个问题的时候,会在互联网上的某个地方偶然发现下面的“解决方案”。这些解决方案在这种特定情况下是行不通的。解释如下。
XML设置XML :这只告诉解析器在围绕它构建
表格接受字符集=“UTF-8”>
现代浏览器忽略了这一点。这仅在Microsoft Internet Explorer浏览器中有效。即便如此,它的做法也是错误的。千万不要用它。所有真正的real浏览器都将改为使用在响应的Content-Type头中指定的字符集属性。只要您不指定attribute.
accept-charset也会以正确的方式执行此操作:-Dfile.coding=UTF-8
这仅由Oracle(!)使用读取和解析Java源文件。
https://stackoverflow.com/questions/9634230
复制相似问题