Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAX-RS: How can I return my list of objects as JSON?

I looked at the documentation of Jackson, and it left me confused :( My entity looks like :

 @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;

}

and my JAX-RS service looks like

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

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

}

When I test this service using curl http://localhost:8080/app/rest/variable, I see the following in my server logs

[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

What are some simplest ways I can return my list of variables as JSON?

like image 469
daydreamer Avatar asked Dec 12 '22 18:12

daydreamer


1 Answers

Normally it is as simple as adding the @XmlRootElement on your Entity (I can see you're using JPA/Hibernate @Entity/@Table, but you're missing the @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;
}

And this is for the service, using the Response from JAX-RS, and also returning directly an object that will be marshaled automatically by 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();
    }
}

Often people would create a DTO to avoid exposing internal values of the Entity from the database to the real world, but it is not mandatory, if it is fine for you to expose the whole object.

like image 85
Alex Avatar answered Mar 03 '23 21:03

Alex