【问题标题】:How to set encoding in RESTeasy to UTF-8?如何将 RESTeasy 中的编码设置为 UTF-8?
【发布时间】:2013-01-18 23:19:21
【问题描述】:

我在 RESTeasy 中编码字符串时遇到问题。问题是无法正确显示中文字母或任何其他非拉丁字符。如果我尝试将它们打印出来(或作为响应发送),我会得到“?????”反而。 我相信 RESTeasy 中的默认编码是 us-ascii。您知道如何将其更改为 UTF-8 吗?也许这个问题还有其他解决方案?

这是我的代码中的一小段:

@POST
@Path("post")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public String uploadData(@MultipartForm DataUploadForm uploadForm) {

...

//the code below is just for the purpose of presentation

String text = "some non-latin alphabet signs here"
System.out.println(text);  // "??????" is printed out

return text; //"??????" is returned
}

我的 resteasy-jaxrs-3.0-beta-2 在 Tomcat 7.0 上运行。

谢谢!

【问题讨论】:

  • 应该有@Produces的注解吗? (可能在班级级别。)
  • 谢谢,我会试试的,但我想知道这个注释是否会影响方法内部发生的事情(在产生输出之前)?换句话说,它能让 System.out.println 显示正确的字符吗?
  • 如果System.out.println() 编码是您唯一的实际问题,那么您基本上需要在负责呈现标准输出的一侧配置它。如果它是例如 Eclipse,那么请前往这个答案:stackoverflow.com/questions/13452324/… 请注意,这与 Tomcat/Servlets/JAX-RS/RESTeasy完全无关

标签: tomcat servlets jax-rs resteasy


【解决方案1】:

如果您的 API 的使用者不能轻易地将字符集设置为 UTF-8(例如:使用 fetch 和 FormData),那么 RestEasy 默认使用美国 ASCII 编码。因此,如果您使用的是非 ascii 字符,它们的编码就会出现乱码。
对我有用的是将输入表单参数视为 byte[] 并自己使用 utf-8 字符集进行字符串转换。

@FormParam("data")
private byte[] data;

【讨论】:

    【解决方案2】:

    这对我有用

    @Produces(MediaType.APPLICATION_JSON+";charset=UTF-8")
    

    【讨论】:

      【解决方案3】:

      我在将 jaxrs1(球衣)迁移到 resteasy 3.0.17.final 时遇到了同样的问题。

      从自定义客户端上传表单/多部分时,客户端确实发送了内容类型,但没有字符集,然后 resteasy 假定为“us-ascii”(根据 MIME RFC,根据文档)。有趣的是,如果根本没有给出 content-type,resteasy 会假设“text/plain; charset=ISO-8859-1”(我假设遵循 http 规范?)。

      他们的文档建议使用 RestEasy 自定义拦截器来解决这个问题:

      https://docs.jboss.org/resteasy/docs/3.0.2.Final/userguide/html/Multipart.html#multipart_overwrite_content_type

      但这个拦截器实际上已被弃用,它宣传使用 jaxrs 2.0 拦截器机制。

      长话短说,为了让它以独立于实现的方式工作,你创建了这个类:

      package x.y.z;
      import java.io.IOException;
      import javax.ws.rs.WebApplicationException;
      import javax.ws.rs.ext.Provider;
      import javax.ws.rs.ext.ReaderInterceptor;
      import javax.ws.rs.ext.ReaderInterceptorContext;
      @Provider
      /**
       * If charset not given (form multipart upload), default to UTF-8 and not us-ascii (MIME RFC).
       */
      public class RestEasyDefaultCharsetInterceptor implements ReaderInterceptor {
          // Using string value instead of constant to limit references to RestEasy (this should be possible to set through web.xml imo)
          // private static final String RESTEASY_DEFAULT_CHARSET_PROPERTY = org.jboss.resteasy.plugins.providers.multipart.InputPart.DEFAULT_CHARSET_PROPERTY;
          private static final String RESTEASY_DEFAULT_CHARSET_PROPERTY = "resteasy.provider.multipart.inputpart.defaultCharset";
          @Override
          public Object aroundReadFrom(ReaderInterceptorContext ctx) throws IOException, WebApplicationException {
              ctx.setProperty(RESTEASY_DEFAULT_CHARSET_PROPERTY, "UTF-8");
              return ctx.proceed();
          }
      }
      

      接下来,将拦截器添加到 web.xml: <context-param> <param-name>resteasy.providers</param-name> <param-value>
      x.y.z.RestEasyDefaultCharsetInterceptor </param-value> </context-param>
      现在,我还没有完全理解整个机制,但是您应该也可以通过将 charset 参数指定为 content-type 来解决客户端的问题。

      【讨论】:

        【解决方案4】:

        我创建了一个网络过滤器。我不知道这是否是最好的方法,但可以肯定它确实解决了问题。

        @WebFilter(filterName = "CharacterEncodingFilter", urlPatterns = {"/api/*"})
        public class CharacterEncodingFilter implements Filter {
        
        public CharacterEncodingFilter() {
        }
        
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException 
        {      
            // setting the charset
            response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
            chain.doFilter(request, response);
        }
        
        }
        

        只需更改 urlPatterns 即可过滤您的 Resteasy 资源。

        【讨论】:

          【解决方案5】:

          对于因问题标题而来到这里的人,这里有一个解决方案。在您的 @Consumes 注释中,尝试将字符集设置为 UTF-8:

          @Consumes(MediaType.MULTIPART_FORM_DATA+";charset=UTF-8");
          

          【讨论】:

          • 对于我的 resteasy 2.3.2,在更新 @Consume 后,我收到以下错误:执行 POST [TheUrl] 失败:org.jboss.resteasy.spi.UnsupportedMediaTypeException:无法使用内容类型
          • 您在 POST 请求的 Content-Type 标头中发送了什么?如果你直接复制我的例子,它需要是“multipart/form-data”。如果您不是在表单中上传文件,则需要相应地更新 MediaType。
          【解决方案6】:

          这与 resteasy 或 jax-rs mate 无关。

          查看this post

          您可能需要研究几件事:

          1. 如果数据来自 DB,则需要确保 DB 中的数据编码正确。
          2. 您的 JVM 环境正在使用 utf8 进行编码
          3. 这可能是 IDE 的问题,因为 IDE 和您的 tomcat 可能在不同的平台上运行 配置。

          【讨论】:

            猜你喜欢
            • 2018-02-17
            • 1970-01-01
            • 2011-11-06
            • 2021-02-10
            • 1970-01-01
            • 2012-03-10
            • 2012-02-01
            • 2016-05-10
            • 2011-06-30
            相关资源
            最近更新 更多