10

我在 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. 我在这里做什么奇怪的事情吗?这似乎应该支持开箱即用,但我找不到任何其他有同样问题的人。
4

2 回答 2

10

我认为您在 JSF 中遇到了一个极端案例错误。查询字符串是 URL 编码的,ExternalContext#encodeRedirectURL()它使用由 获得的响应字符编码ExternalContext#getResponseCharacterEncoding()。但是,虽然 JSF 默认使用 UTF-8 作为响应字符编码,但仅在实际要渲染视图时才设置,而不是在响应重定向时设置,因此响应字符编码仍然返回平台默认ISO-8859-1的导致您的字符使用这种错误的编码进行 URL 编码。

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

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

注意,这仍然需要容器本身使用相同的字符编码来解码请求URL,所以你肯定需要URIEncoding="UTF-8"在Tomcat的配置中进行设置。这不会再弄乱字符了,因为它们现在将是真正的 UTF-8。

于 2012-06-12T12:20:13.433 回答
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";

}

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

于 2012-06-12T12:11:24.397 回答