JSF 中 GET 参数的 UTF-8 编码

问题描述 投票:0回答:2

我在 JSF 中有一个搜索表单,它是使用 RichFaces 4 自动完成组件以及以下 JSF 2 页面和 Java bean 实现的。我使用 Tomcat 6 和 7 来运行该应用程序。

...
<h:commandButton value="#{msg.search}" styleClass="search-btn" action="#{autoCompletBean.doSearch}" />
...

在 AutoCompleteBean 中

public String doSearch() {

   //some logic here
   return "/path/to/page/with/multiple_results?query=" + searchQuery + "&amp;faces-redirect=true";

}

只要“searchQuery”字符串中的所有内容都在 Latin-1 中,此方法就可以正常工作,如果在 Latin-1 之外,则此方法不起作用。

例如,搜索“bodø”将自动编码为“bod%F8”。然而,搜索“Kra Ðong”将不起作用,因为它无法编码“Д。

我现在尝试了几种不同的方法来解决这个问题,但都不起作用。

  • 我尝试使用 URLEncode 对我自己的 searchQuery 进行编码,但这只会导致双重编码,因为 % 被编码为 %25。
  • 我尝试使用 java.net.URI 来获取编码,但给出与 URLEncode 相同的结果。
  • 我尝试在连接器中使用 URIEncoding="UTF-8" 在 Tomcat 中打开 UTF-8,但这只会使问题变得更糟,因为非 ASCII 字符根本不起作用。

所以我的问题是:

  1. 我可以更改 JSF 2 编码 GET 参数的方式吗?
  2. 如果我无法更改 JSF 2 编码 GET 参数的方式,我可以关闭编码并手动执行吗?
  3. 我在这里做了什么奇怪的事吗?这似乎应该是开箱即用的支持,但我找不到任何其他人有同样的问题。
java redirect jsf-2 utf-8 character-encoding
2个回答
10
投票

我认为您遇到了 JSF 中的一个极端情况错误。查询字符串由

ExternalContext#encodeRedirectURL()
进行 URL 编码,它使用由
ExternalContext#getResponseCharacterEncoding()
获得的响应字符编码。然而,虽然 JSF 默认使用 UTF-8 作为响应字符编码,但这仅在实际渲染视图时设置,而不是在重定向响应时设置,因此响应字符编码仍然返回平台默认值
 ISO-8859-1
这会导致您的字符使用这种错误的编码进行 URL 编码。

我已将其报告为问题 2440。同时,您最好的选择是事先自己明确设置响应字符编码。

FacesContext.getCurrentInstance().getExternalContext().setResponseCharacterEncoding("UTF-8");

注意,这仍然要求容器本身使用相同的字符编码来解码请求URL,所以你当然需要在Tomcat的配置中设置

URIEncoding="UTF-8"
。这不会再弄乱字符,因为它们现在将是真正的 UTF-8。


0
投票

HTTP URL 和标头接受的唯一字符编码是 US-ASCII,您需要对这些字符进行 URL 编码才能将它们发送回应用程序。在 Java 中执行此操作的最简单方法是:

public String doSearch() {

   //some logic here
   String encodedSearchQuery = java.net.URLEncoder.encode( searchQuery, "UTF-8" );
   return "/path/to/page/with/multiple_results?query=" + encodedSearchQuery + "&amp;faces-redirect=true";

}

然后它应该适用于您使用的任何角色。

© www.soinside.com 2019 - 2024. All rights reserved.