java - 如何正确解码传递给 servlet 的 unicode 参数

标签 java unicode servlets

假设我有:

<a href="http://www.yahoo.com/" target="_yahoo" 
    title="Yahoo!&#8482;" onclick="return gateway(this);">Yahoo!</a>
<script type="text/javascript">
function gateway(lnk) {
    window.open(SERVLET +
        '?external_link=' + encodeURIComponent(lnk.href) +
        '&external_target=' + encodeURIComponent(lnk.target) +
        '&external_title=' + encodeURIComponent(lnk.title));
    return false;
}
</script>

我已经确认 external_title 被编码为 Yahoo!%E2%84%A2 并传递给 SERVLET。如果在 SERVLET 我这样做:

Writer writer = response.getWriter();
writer.write(request.getParameter("external_title"));

我在浏览器中看到了 Yahoo!â„¢。如果我手动将浏览器字符编码切换为 UTF-8,它会更改为 Yahoo!TM(这是我想要的)。

所以我认为我发送给浏览器的编码是错误的(它是 Content-type: text/html; charset=ISO-8859-1)。我将 SERVLET 更改为:

response.setContentType("text/html; charset=utf-8");
Writer writer = response.getWriter();
writer.write(request.getParameter("external_title"));

现在浏览器字符编码是 UTF-8,但它输出 Yahoo!? 我根本无法让浏览器呈现正确的字符。

我的问题是:是否存在 Content-type 和/或 new String(request.getParameter("external_title").getBytes(), "UTF-8") 的组合; 和/或其他会导致 Yahoo!TM 出现在 SERVLET 输出中的内容?

最佳答案

你快到了。 EncodeURIComponent 正确编码为 UTF-8,这是您现在应该始终在 URL 中使用的内容。

问题是提交的查询字符串在进入服务器端脚本的过程中被破坏了,因为 getParameter() 使用 ISO-8559-1 而不是 UTF-8。这源于古代网络在 URI/IRI 上采用 UTF-8 之前的时代,但遗憾的是 Servlet 规范尚未更新以适应现实,或者至少为其提供可靠、受支持的选项。

(Servlet 2.3中有request.setCharacterEncoding,但不影响查询字符串解析,如果之前读取过单个参数,可能是由其他框架元素读取,则根本不起作用。)

因此,您需要使用特定于容器的方法来获得正确的 UTF-8,通常涉及 server.xml 中的内容。这对于分发应该可以在任何地方工作的 Web 应用程序来说是非常糟糕的。对于 Tomcat,请参阅 https://cwiki.apache.org/confluence/display/TOMCAT/Character+Encoding还有What's the difference between "URIEncoding" of Tomcat, Encoding Filter and request.setCharacterEncoding .

关于java - 如何正确解码传递给 servlet 的 unicode 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/469874/

相关文章:

java - 如何使用 Fortify 软件安全中心 REST API 下载保存的报告?

python - 相同的字符,不同的长度和字节

java - 从 .jsp 访问 .class'es 和 .jar's

html - 悬停时未突出显示链接中的 Unicode 字符

C# Unicode(日语字符)

java - 获取servlet属性而不加载当前jsp页面

java - 通过 servlet 使用 MEncoder 进行视频编码

java - Android注入(inject)类返回null

java - 如何在 JSONObject 中获取没有名称的 JSONArrays

java - Google Foobar,字符串清理,测试失败 5