为啥我的 Servlet 不响应 UTF-8 格式的 JSON 请求?

Posted

技术标签:

【中文标题】为啥我的 Servlet 不响应 UTF-8 格式的 JSON 请求?【英文标题】:Why won't my Servlet respond to JSON requests in UTF-8?为什么我的 Servlet 不响应 UTF-8 格式的 JSON 请求? 【发布时间】:2011-04-13 20:02:14 【问题描述】:

我的 Servlet 只是不会将 UTF-8 用于 JSON 响应。

MyServlet.java

public class MyServlet extends HttpServlet 

  protected void doPost(HttpServletRequest req, HttpServletResponse res) throws Exception 

    PrintWriter writer = res.getWriter();

    res.setCharacterEncoding("UTF-8");
    res.setContentType("application/json; charset=UTF-8");

    writer.print(getSomeJson());
  

但是特殊字符没有出现,当我检查我在 Firebug 中返回的标题时,我看到了Content-Type: application/json;charset=ISO-8859-1

我在我的 Servlet 目录中创建了一个 grep -ri iso .,但没有找到任何结果,所以我没有明确地将类型设置为 ISO-8859-1。

我还应该指定我在 Eclipse 中的 Tomcat 7 上运行它,并以 J2EE 目标作为开发环境,使用 Solaris 10 和他们所谓的 Web 服务器环境(由其他人管理)作为生产环境,并且行为是一样的。

我还确认提交的请求是 UTF-8,只有响应是 ISO-8859-1。

更新

我已经修改了代码以反映我在设置字符编码之前正在调用 PrintWriter。我从原始示例中省略了这一点,现在我意识到这是我的问题的根源。我读到here,您必须在调用HttpServletResponse.getWriter() 之前设置字符编码,否则getWriter 将为您将其设置为ISO-8859-1。

这是我的问题。所以上面的例子应该调整为

public class MyServlet extends HttpServlet 

  protected void doPost(HttpServletRequest req, HttpServletResponse res) throws Exception 

    res.setCharacterEncoding("UTF-8");
    res.setContentType("application/json");

    PrintWriter writer = res.getWriter();
    writer.print(getSomeJson());
  

【问题讨论】:

感谢您的“更新”,这正是我正在寻找的:首先设置字符编码,其次获取作者。 【参考方案1】:

一旦为响应设置了编码,就无法更改。

强制使用 UTF-8 的最简单方法是创建您自己的过滤器,它是第一个查看响应并设置编码的过滤器。

看看how Spring 3.0 does this。即使你不能在你的项目中使用 Spring,也许你能得到一些灵感(确保你的公司政策允许你从开源许可证中获得灵感)。

【讨论】:

您无法更改编码是对的。我设置了两次,但没有明确设置。我是用 getWriter 隐式做的。请参阅我更新的问题。感谢您的回答,并 +1。【参考方案2】:

代码看起来不错。要么你没有运行你认为你正在运行的代码,要么有一些Filter或代理在请求-响应链的某处修改了这样的内容类型。

【讨论】:

我不知道这可能发生在哪里,除非这是我的环境的默认行为。有一个源文件,我是从头开始编写的。不过这也是我的第一个Servlet,所以不知道Filter是什么。 webapp 的/WEB-INF/web.xml 中没有其他内容?究竟是什么Tomcat版本?下载/安装后,您是否修改了其/conf/web.xml 文件中的任何内容? 换句话说,您问题中的原始代码看起来不错,并且您没有运行您认为正在运行的代码:) 是的。你在技术上是正确的——最好的正确!感谢您的回复,但这并没有真正为我指明正确的方向。不过,谢谢。【参考方案3】:

除了具体问题,你真的应该考虑获取输出流,使用 JSON 库将内容直接写入为 UTF-8 编码的 JSON;使用 writer 没有任何好处。 一些 JSON 包仅适用于字符串,这很不幸,但大多数都允许使用更高效的流(更安全、更高效,因为解析器/生成器可以同时处理转义和编码方面)。

【讨论】:

感谢您的建议。我会调查一下。这是我的第一个 servlet,所以我对可用的库不太熟悉。我一定会使用我们默认的 Solaris 10 环境中可用的任何东西。

以上是关于为啥我的 Servlet 不响应 UTF-8 格式的 JSON 请求?的主要内容,如果未能解决你的问题,请参考以下文章

我的keil 4为啥不能改变编码格式?没有那个选项?

为啥我的 servlet 不根据请求创建新线程? [关闭]

servlet请求编码与响应编码问题(编码不一致可能会导致乱码)

处理Servlet响应中文乱码

win10文本文档默认为啥是UTF-8,而且改变不了编码格式

Servlet处理中文乱码问题(请求/响应)