Dropwizard/Jersey 中对资源的 REST 调用和 UTF-8 仅适用于开发机器

REST Call to Resource in Dropwizard/Jersey and UTF-8 works only on dev machine

我们使用的是 dropwizard 0.7.1,它带有 jetty 9.0.7 和 jersey http 客户端 1.18.1(是的,它很旧...)。 os 是 linux,我们使用的是 Java 1.8.

我是 运行 eclipse 内部的本地集成测试,它使用 jersey 对 vagrant box 内的 dropwizard 应用程序进行休息调用 运行。

其中一项测试应验证我是否可以将非拉丁字符发送到服务器。

我正在使用 jersey 在 POJO 的字符串字段中发送字符串“Владимир уладимир 度”:

req.type(MediaType.APPLICATION_JSON + "; charset=utf-8")//            
   .post(ClientResponse.class, user);

我发送的资源也是这样的:

@Path("/users")
@Produces(MediaType.APPLICATION_JSON + "; charset=utf-8")
@Consumes(MediaType.APPLICATION_JSON + "; charset=utf-8")
public class UserServiceResource{

  [...]

  @POST
  public Response createUser(UserCreate user) {...}

(您看到我们在客户端和服务器端都强制执行 utf-8 字符集,在我看来,实际上应该没有必要?)

这在本地完美运行,名称正确到达。

然而,在詹金斯上,这不起作用,我只收到“??????”在服务中而不是正确的字符。在 posts pojo 的客户端日志中,我仍然看到正确的字符。

设置非常相似:jenkins 构建一个 vagrant box,然后使用 maven 对此框运行测试(集成测试代码在 vagrant box 外部运行,服务在 vagrant 内部运行)。

Jenkins 使用 maven,但是当 运行 使用 maven 在本地进行集成测试时,它仍然可以正常工作。

我在本地使用的 vagrant box 也是由 jenkins 在不同的工作中构建和配置的。

我们现在正在尝试调查环境设置是否可能略有不同,已经尝试设置

LANG=en_US.UTF-8
LC_ALL=en_US.UTF-8
MAVEN_OPTS="-Dfile.encoding=UTF-8"

但这并没有帮助。

主要让我困惑的是,我希望在任何环境设置下都能工作,因为我们明确强制执行 UTF-8。

是否知道环境如何覆盖客户端和服务器中设置的编码?

这个问题吞噬了我的灵魂。根本问题最终出现在 JDBC 配置上。最初我的配置是这样的:

database:
  driverClass: com.mysql.jdbc.Driver
  user: ...
  password: ...
  url: jdbc:mysql://...
  properties:
    charSet: UTF-8
    hibernate.dialect: org.hibernate.dialect.MySQL5InnoDBDialect
  maxWaitForConnection: 1s
  validationQuery: "/* DropWizard Health Check */ SELECT 1"
  minSize: 5
  maxSize: 25
  checkConnectionWhileIdle: false
  checkConnectionOnBorrow: true

解决方案是更新 properties 块以定义 characterEncodinguseUnicode 属性。像这样:

properties:
  charSet: UTF-8
  characterEncoding: UTF-8
  useUnicode: true
  hibernate.dialect: org.hibernate.dialect.MySQL5InnoDBDialect

除了 adding a charset parameter to the Content-Type header 之外,还更新了我的 YAML 配置,解决了我的问题。