通过PrimeFaces输入组件检索的Unicode输入已损坏 [英] Unicode input retrieved via PrimeFaces input components become corrupted

查看:121
本文介绍了通过PrimeFaces输入组件检索的Unicode输入已损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我还在使用PrimeFaces v2.2.1时,我能够使用PrimeFaces输入组件(例如< p:inputText> )键入unicode输入< p:editor> ,并在托管bean方法中检索输入形式良好。

When I was still using PrimeFaces v2.2.1, I was able to type unicode input such as Chinese with a PrimeFaces input component such as <p:inputText> and <p:editor>, and retrieve the input in good shape in managed bean method.

但是,我升级到PrimeFaces v3.1.1后,所有这些字符变成Mojibake或问号。

However, after I upgraded to PrimeFaces v3.1.1, all those characters become Mojibake or question marks. Only Latin input comes fine, it are the Chinese, Arabic, Hebrew, Cyrillic, etc characters which become malformed.

这是如何引起的,我该如何解决? / p>

How is this caused and how can I solve it?

推荐答案

简介



通常,JSF / Facelets将设置请求参数当创建/恢复视图时,默认情况下已将字符编码设置为UTF-8。但是如果在创建/恢复视图之前已经请求了之前的任何请求参数,那么设置正确的字符编码太晚了。

Introduction

Normally, JSF/Facelets will set the request parameter character encoding to UTF-8 by default already when the view is created/restored. But if any request parameter is been requested before the view is been created/restored, then it's too late to set the proper character encoding. The request parameters will namely be parsed only once.

它在PrimeFaces 3中失败。从2.x升级后的x是由PrimeFaces的中的新的 isAjaxRequest()覆盖引起的参数:

That it failed in PrimeFaces 3.x after upgrading from 2.x is caused by the new isAjaxRequest() override in PrimeFaces' PrimePartialViewContext which checks a request parameter:

@Override
public boolean isAjaxRequest() {
    return getWrapped().isAjaxRequest()
            || FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().containsKey("javax.faces.partial.ajax");
}

默认情况下, isAjaxRequest c $ c>(Mojarra / MyFaces中的一个,因为上面的PrimeFaces代码通过 getWrapped()获得)检查请求头,如下所示,这不影响请求参数编码作为请求参数在获得请求头时不会被解析:

By default, the isAjaxRequest() (the one of Mojarra/MyFaces, as the above PrimeFaces code has obtained by getWrapped()) checks the request header as follows which does not affect the request parameter encoding as request parameters won't be parsed when a request header is obtained:

    if (ajaxRequest == null) {
        ajaxRequest = "partial/ajax".equals(ctx.
            getExternalContext().getRequestHeaderMap().get("Faces-Request"));
    }

但是 isAjaxRequest()可以在任何阶段侦听器或系统事件侦听器或一些应用程序工厂之前创建/恢复视图之前调用。因此,当您使用PrimeFaces 3.x时,请求参数将在正确的字符编码设置之前进行解析,因此使用服务器的默认编码,通常为ISO-8859-1。

However, the isAjaxRequest() may be called by any phase listener or system event listener or some application factory before the view is been created/restored. So, when you're using PrimeFaces 3.x, then the request parameters will be parsed before the proper character encoding is been set and hence use the server's default encoding which is usually ISO-8859-1. This will mess up everything.

有几种方法可以解决:


  1. 使用 servlet过滤器其中设置 ServletRequest# setCharacterEncoding() 使用UTF-8。通过设置响应编码 ServletResponse#setCharacterEncoding() 是没有必要的,因为它不会受到这个问题的影响。

  1. Use a servlet filter which sets ServletRequest#setCharacterEncoding() with UTF-8. Setting the response encoding by ServletResponse#setCharacterEncoding() is by the way unnecessary as it won't be affected by this issue.

@WebFilter("/*")
public class CharacterEncodingFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        chain.doFilter(request, response);
    }

    // ...
}

您只需要考虑 HttpServletRequest#setCharacterEncoding()只设置POST请求参数的编码,而不是GET请求参数。对于GET请求参数,您仍然需要在服务器级别对其进行配置。

You only need to take into account that HttpServletRequest#setCharacterEncoding() only sets the encoding for POST request parameters, not for GET request parameters. For GET request parameters you'd still need to configure it at server level.

如果您碰巧使用JSF实用程序库 OmniFaces 时,此类过滤器已在框中提供, CharacterEncodingFilter 。只需在 web.xml 中将其安装为第一个过滤条目:

If you happen to use JSF utility library OmniFaces, such a filter is already provided out the box, the CharacterEncodingFilter. Just install it as below in web.xml as first filter entry:

<filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.omnifaces.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>





  • 重新配置服务器以使用UTF- 8而不是ISO-8859-1作为默认编码。在Glassfish的情况下,这将是添加以下条目到 / WEB-INF / 中的< glassfish-web-app& glassfish-web.xml 文件:

    <parameter-encoding default-charset="UTF-8" />
    

    Tomcat不支持它。它在< Context> 条目中具有 URIEncoding 属性,但这仅适用于GET请求,不适用于POST请求

    Tomcat doesn't support it. It has the URIEncoding attribute in <Context> entry, but this applies to GET requests only, not to POST requests.

    向PrimeFaces报告错误。有没有真的任何合法的原因,通过检查请求参数而不是请求头,检查HTTP请求是一个ajax请求,就像你对标准JSF和例如jQuery? The PrimeFaces的 core.js JavaScript正在这样做。如果将它设置为 XMLHttpRequest 的请求标头,将会更好。

    Report it as a bug to PrimeFaces. Is there really any legitimate reason to check the HTTP request being an ajax request by checking a request parameter instead of a request header like as you would do for standard JSF and for example jQuery? The PrimeFaces' core.js JavaScript is doing that. It would be better if it has set it as a request header of XMLHttpRequest.

    这篇关于通过PrimeFaces输入组件检索的Unicode输入已损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆