JAX-RS:如何将对象列表作为JSON返回?

day*_*mer 4 java jax-rs jackson

我查看了杰克逊的文档,它让我困惑:(我的实体看起来像:

 @Entity
 @Table(name = "variable")
 public class Variable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(unique = true, nullable = false)
    private String name;

    @Column
    @Enumerated(EnumType.STRING)
    private VariableType type;

    @Column(nullable = false)
    private String units;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "created_on", nullable = false)
    private Date createdOn;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "retired_on", nullable = true)
    private Date retiredOn;

    @Column(nullable = false)
    private boolean core;

}
Run Code Online (Sandbox Code Playgroud)

我的JAX-RS服务看起来像

@Path("/variable")
public class VariableResource {
    @Inject private VariableManager variableManager;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response getVariables() {
        return Response.ok(variableManager.getVariables()).build();
    }

}
Run Code Online (Sandbox Code Playgroud)

当我使用测试此服务时curl http://localhost:8080/app/rest/variable,我在服务器日志中看到以下内容

[javax.ws.rs.core.Application]] (http--127.0.0.1-8080-6) Servlet.service() for servlet javax.ws.rs.core.Application threw exception: java.lang.NoSuchMethodError: org.codehaus.jackson.type.JavaType.<init>(Ljava/lang/Class;)V
Run Code Online (Sandbox Code Playgroud)

有什么最简单的方法可以将我的变量列表作为JSON返回?

Ale*_*lex 13

通常它就像添加@XmlRootElement你的实体一样简单(我可以看到你正在使用JPA/Hibernate @Entity/ @Table,但你错过了@XmlRootElement).

@Entity
@Table(name = "variable")
@XmlRootElement
public class Variable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(unique = true, nullable = false)
    private String name;

    // ...

    @Column(nullable = false)
    private boolean core;
}
Run Code Online (Sandbox Code Playgroud)

这是针对服务的,使用Response来自JAX-RS,并且还直接返回将由JAX-RS自动封送的对象:

@Path("/variable")
public class VariableResource {
    @Inject private VariableManager variableManager;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response getVariables() {
        return Response.ok(variableManager.getVariables()).build();
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    // Same method but without using the JAX-RS Response object
    public List<Variable> getVariablesAlso() {
        return variableManager.getVariables();
    }
}
Run Code Online (Sandbox Code Playgroud)

通常人们会创建一个DTO来避免将实体的内部值从数据库暴露给现实世界,但如果您可以公开整个对象,那么它并不是强制性的.

  • 一个澄清:JAX-RS不需要@XmlRootElement,但是如果正在使用JAXB,则不需要。对于JSON,通常不是这样(但是默认情况下用于XML输出)。添加它当然不会有伤害,并且可能更安全以确保XML输出正常工作。但是只是想为完整起见我会指出这一点。 (2认同)