【问题标题】:JAX-RS: How can I return my list of objects as JSON?JAX-RS:如何将我的对象列表返回为 JSON?
【发布时间】:2013-01-14 20:21:40
【问题描述】:

我查看了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;

}

我的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();
    }

}

当我使用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

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

【问题讨论】:

    标签: java jackson jax-rs


    【解决方案1】:

    通常它就像在您的实体上添加 @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;
    }
    

    这是针对服务的,使用来自 JAX-RS 的 Response,并且还直接返回一个将由 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();
        }
    }
    

    人们通常会创建DTO 以避免将实体的内部值从数据库暴露给现实世界,但这不是强制性的,如果您可以暴露整个对象。

    【讨论】:

    • 如果我需要将数据从用户映射/序列化到@Entity,它也可以工作吗?
    • 如果您希望 JAX-RS 从实体输出 JSON,则该实体应具有 @XmlRootElement。现在,如果您的资源服务的方法将 Variable 类型的元素作为 post 参数,JAX-RS 将为您创建对象,并且可以通过任何 Repository/EntityManager 保存它(它只是毕竟是一个对象,而且它确实有 @Entity 注释)。
    • 一个澄清:@XmlRootElement 不是 JAX-RS 要求的,而是 JAXB 要求的,如果它正在使用的话。而对于 JSON,它通常不是(默认情况下它用于 XML 输出)。添加它当然不会受到伤害,并且可能更安全地确保 XML 输出正常工作。但只是想为了完整起见我会指出它。
    猜你喜欢
    • 2015-05-25
    • 2012-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-06
    • 1970-01-01
    • 2017-05-08
    • 2019-04-30
    相关资源
    最近更新 更多