1

I developed a restful web service via Jersey in Java (JAX-RS) : http://www.vogella.com/articles/REST/article.html

Then I used the Hibernate Technology to map the data to the database.

Finally I developed an android application to display data.

This is an example of a method in my Web Service :

    @GET
    @Path("/project_id/username/get/{projectId}/{username}/")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response deliverableList(@PathParam("projectId") long projectId,
                            @PathParam("username") String username) {
                Session session = HibernateUtil.getSessionFactory().getCurrentSession();
                session.beginTransaction();
                List<Deliverable> list = null;
                try {
                    list= (List<Deliverable>) session.createQuery(
                            "from Deliverable as d where d.project.id= :id").setLong("id", projectId).list();   
                    } catch (HibernateException e) {
                        e.printStackTrace();
                        session.getTransaction().rollback();
                    }
                    session.getTransaction().commit();
                    return Response.status(201).entity(list).build();
                }

as you see I used "Response.status(201).entity(list).build()" to transfer the list of data. Is it a good way? if not what is your suggestion to transfer the data. Please support your explanation with some codes and examples.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Ali
  • 9,800
  • 19
  • 72
  • 152

2 Answers2

2
  1. Response.ok().enity(object).build() is the correct way to return data
  2. You really want to move your hibernate stuff to a data access tier... it's going to be hard to manage intermingled with your service tier
  3. I completely disagree with smcg about using a helper method to map the java to json. Use the jax-rs annotations on your beans to do it unless you have really complicated requirements: see http://wiki.fasterxml.com/JacksonAnnotations
Rick Mangi
  • 3,761
  • 1
  • 14
  • 17
  • "it's going to be hard to manage intermingled with your service tier." What is your suggestion? – Ali Jun 26 '12 at 12:06
  • Do you think I need to serialize and deserialize the data? If yes do have any example about how to do it? (considering that I want to use the data in my Android client) – Ali Jun 26 '12 at 12:11
  • 1
    Like I said, move you hibernate stuff to a data access tier (use a DAO). Jersey takes care of the serializing of the object for you to the client and also of unmarshalling the data coming from in. I am not sure if jerseys client libraries are used on the android, but I bet they work there. When you say @produces(json) that tells jersey to use Jackson for Marshalling (serializing) @consumes tells jersey to use Jackson for unmarshalling. Use the annotations I linked above for tuning the marshalling. You can get more control if you need it but that's unlikely. – Rick Mangi Jun 26 '12 at 12:19
  • Would you please let me know about benefits of using Dao instead of what I did? check this link: http://sberka.blogspot.se/2010/02/json-restfull-service-using-jersey-with.html Here exactly the same question has been rised up : "Most of the Hibernate-specific code should go into a DAO, with most of it into a generic DAO. But the recommended by Hibernate documentation generic DAO is defined in terms of state-oriented data access API (makePersistent() and makeTransient() methods), which are less intuitive for me. What is the advantage of using them?" – Ali Jun 26 '12 at 15:48
  • it's a matter of separating your code into manageable tiers of responsibility. If all of your hibernate code is mixed in other classes it's hard to make a single change that effects everything. Instead you should have 1 class (dao) that manages data access for a single object, or group of objects. It's following object oriented principles of encapsulation. So your dao is "wired" into your service tier (jersey) and you delegate the CRUD operations to the dao. See: http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html – Rick Mangi Jun 26 '12 at 16:32
  • well, there's no accounting for taste. I ran in to so many dead ends with Jackson that I had to rewrite all of my REST resource classes. – smcg Jun 27 '12 at 13:33
  • Really? I've found it to be one of the most flexible serialization packages I've used, and we have a fairly complex json api. – Rick Mangi Jun 27 '12 at 15:04
0

It seems to me like you are relying on something to automagically map your Java objects to JSON - probably Jackson. I do not personally prefer this method. Instead, I use Jettison and create my own mapping from Java to a Jettison JSONObject object. Then I use the JSONObject (or JSONArray) as the entity. My return statement would be something like this:

return Response.ok().entity(myObjectAsJSON).build();

In the case of returning a list of things, use a JSONArray instead of a JSONObject.

You'll want a helper method to map the Java object to JSON.

public JSONArray deliverableListToJSON(List<Deliverable> deliverables) 
throws JSONException {
JSONArray result = new JSONArray();
for(Deliverable deliverable : deliverables) {
    JSONObject deliverableJSON = new JSONObject();
    deliverableJSON.put("importantValue", deliverable.getImportantValue());
    result.put(deliverableJSON);
    }
return result;
}

This approach gives you more flexibility and doesn't force you to have public getters and setters for all your fields.

smcg
  • 3,195
  • 2
  • 30
  • 40
  • I appreciate for your reply. Do you know what is the difference between ok(), status(201)? They both works fine. – Ali Jun 25 '12 at 16:05
  • Do you mean : @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) are not flexible? In your method you iterate over all elements of the list, but with @Produces annotation, we do not iterate. it transfers the data in Json format. – Ali Jun 25 '12 at 16:06
  • It does the mapping somehow. I recommend you figure out how Jersey/JAX-RS is doing it under the covers if you are going to continue using this approach. As for statuses, 201 is Created, not Okay. 201 is improper for a GET. Response.ok() is the same as status(200) or Response.status(Status.OK). – smcg Jun 25 '12 at 17:15