杰克逊在 json 中添加反斜杠

新手上路,请多包涵

我在 Jersey 上构建 REST 服务,并使用 Jackson 从我的模型的 java 类生成 JSON。绝对简单值的模型,我认为这是最典型的情况。但我得到奇怪的结果:

 [{\"name\":\"Nick\",\"role\":\"admin\",\"age\":\"32\",\"rating\":47}]

我的预期结果:

 [{"name":"Nick","role":"admin","age":"32","rating":47}]

我的字段源值不包含任何特殊字符。这些都是简单的话。

有我的 Java 类。实体:

 public class User {

  private String name;

  private String role;

  private String age;

  private Integer rating;

休息服务等级:

 @ServiceConfig(contextName = "myContext")
@Path("/myrest")
public class MyRestService {

  private static final String JSON_CONTENT_TYPE = MediaType.APPLICATION_JSON + ";charset=UTF-8";

  @Context
  protected HttpServletResponse response;

  @GET
  @Path("/users")
  @OpenTransaction
  @Produces({MediaType.APPLICATION_JSON})
  public String findUsers(@QueryParam("department") String department) {

    response.setContentType(JSON_CONTENT_TYPE);
    PDTResponse.status(response).sendStatus(Response.Status.OK.getStatusCode());

    List<User> users = new ArrayList<>();
    users.add(new User("Nick", "admin", "32", 47));

    String jsonInString;
    ObjectMapper mapper = new ObjectMapper();
    try {
        jsonInString = mapper.writeValueAsString(users);
    } catch (JsonProcessingException ex) {
        jsonInString = "thrown exception: " + ex.getMessage();
    }
    return jsonInString;
}

我尝试将注释 @JsonRawValue 用于字符串属性:

 @JsonRawValue
private String name;

但在这种情况下的结果是:

 [{\"name\":Nick,\"role\":admin,\"age\":32,\"rating\":47}]

我期望:

 [{"name":"Nick","role":"admin","age":"32","rating":47}]

很明显,杰克逊以某种方式转义了响应结果 json 中的引号。但它为什么要这样做,最重要的是如何避免呢?它们本身只是字符串!没有任何引号或特殊字符。

我使用 Java 7Jackson 2.6.1 。和 Postman 测试结果。解决我的问题有什么想法吗?

原文由 François Esthète 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 669
2 个回答

看起来您的 JAX-RS 资源类过于复杂了。

要将 Jackson 用作 Jersey 2.x 的 JSON 提供程序,您不需要像那样创建 ObjectMapper 实例。有更好的方法来实现它。继续阅读以获取更多详细信息。

添加 Jackson 模块依赖项

要使用 Jackson 2.x 作为您的 JSON 提供程序,您需要将 jersey-media-json-jackson 模块添加到您的 pom.xml 文件:

 <dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.25.1</version>
</dependency>

注册杰克逊模块

然后在你的 Application / ResourceConfig 子类中注册 JacksonFeature

 @ApplicationPath("/api")
public class MyApplication extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> classes = new HashSet<Class<?>>();
        classes.add(JacksonFeature.class);
        return classes;
    }
}

 @ApplicationPath("/api")
public class MyApplication extends ResourceConfig {

    public MyApplication() {
        register(JacksonFeature.class);
    }
}

If you don’t have an Application / ResourceConfig subclass, you can register the JacksonFeature in your web.xml deployment descriptor.可以在 jersey.config.server.provider.classnames 初始化参数的 逗号分隔值 中提供特定资源、提供者和功能完全限定的类名。

 <init-param>
    <param-name>jersey.config.server.provider.classnames</param-name>
    <param-value>org.glassfish.jersey.jackson.JacksonFeature</param-value>
</init-param>

杰克逊提供的 MessageBodyWriterJacksonJsonProvider 。有关如何将 Jackson 用作 JSON 提供程序的更多详细信息,请查看此 答案。如果您需要自定义 ObjectMapper ,请参阅此 答案

修复你的资源类

通过使用上述方法,您的资源类可以很简单:

 @Path("/users")
public class MyRestService {

  @GET
  @Produces({MediaType.APPLICATION_JSON + ";charset=UTF-8"})
  public List<User> findUsers() {

    List<User> users = new ArrayList<>();
    users.add(new User("Nick", "admin", "32", 47));

    return Response.ok(users).build();
}

当请求这样的端点时,它会给你预期的 JSON 作为结果。

原文由 cassiomolin 发布,翻译遵循 CC BY-SA 3.0 许可协议

您可以配置 ObjectMapper:

 final ObjectMapper mapper = new ObjectMapper();
mapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false);
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
String jsonUsers = mapper.writeValueAsString(users);

更多信息 在这里

原文由 JuanGG 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题