【问题标题】:REST with Java (JAX-RS) using JerseyREST with Java (JAX-RS) 使用 Jersey
【发布时间】:2012-06-26 19:16:11
【问题描述】:

我通过 Jersey in Java (JAX-RS) 开发了一个宁静的网络服务:http://www.vogella.com/articles/REST/article.html

然后我使用 Hibernate 技术将数据映射到数据库。

最后我开发了一个安卓应用来显示数据。

这是我的 Web 服务中的一个方法示例:

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

如您所见,我使用“Response.status(201).entity(list).build()”来传输数据列表。这是一个好方法吗?如果不是,您对传输数据有什么建议。请用一些代码和例子来支持你的解释。

【问题讨论】:

    标签: jersey jax-rs


    【解决方案1】:
    1. Response.ok().enity(object).build() 是返回数据的正确方式
    2. 您确实希望将休眠内容移至数据访问层...与您的服务层混合管理会很困难
    3. 我完全不同意 smcg 关于使用辅助方法将 java 映射到 json。除非您有非常复杂的要求,否则请在您的 bean 上使用 jax-rs 注释:请参阅http://wiki.fasterxml.com/JacksonAnnotations

    【讨论】:

    • “与您的服务层混合在一起将很难管理。”你有什么建议?
    • 你认为我需要对数据进行序列化和反序列化吗?如果是的话,有任何关于如何做的例子吗? (考虑到我想在我的 Android 客户端使用数据)
    • 就像我说的,将休眠的东西移到数据访问层(使用 DAO)。 Jersey 负责为您将对象序列化到客户端,并解组来自 in 的数据。我不确定 jerseys 客户端库是否在 android 上使用,但我敢打赌它们在那里工作。当你说 @produces(json) 告诉 jersey 使用 Jackson 进行编组(序列化)时,@consumes 告诉 jersey 使用 Jackson 进行解组。使用我上面链接的注释来调整编组。如果需要,您可以获得更多控制权,但这不太可能。
    • 您能否告诉我使用 Dao 而不是我所做的事情的好处?检查此链接:sberka.blogspot.se/2010/02/… 这里提出了完全相同的问题:“大多数特定于 Hibernate 的代码应该进入 DAO,其中大部分进入通用 DAO。但是定义了 Hibernate 文档推荐的通用 DAO就面向状态的数据访问 API(makePersistent() 和 makeTransient() 方法)而言,这对我来说不太直观。使用它们有什么好处?”
    • 这是一个将您的代码分成可管理的责任层的问题。如果您的所有休眠代码都混合在其他类中,则很难进行影响所有内容的单个更改。相反,您应该有 1 个类 (dao) 来管理单个对象或一组对象的数据访问。它遵循面向对象的封装原则。因此,您的 dao 被“连接”到您的服务层(球衣)中,并且您将 CRUD 操作委托给 dao。见:java.sun.com/blueprints/corej2eepatterns/Patterns/…
    【解决方案2】:

    在我看来,您似乎在依赖某些东西将您的 Java 对象自动映射到 JSON - 可能是 Jackson。我个人不喜欢这种方法。相反,我使用 Jettison 并创建自己的从 Java 到 Jettison JSONObject 对象的映射。然后我使用 JSONObject(或 JSONArray)作为实体。我的退货声明是这样的:

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

    在返回事物列表的情况下,使用 JSONArray 而不是 JSONObject。

    您需要一个辅助方法来将 Java 对象映射到 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;
    }
    

    这种方法为您提供了更大的灵活性,并且不会强制您为所有字段使用公共 getter 和 setter。

    【讨论】:

    • 感谢您的回复。你知道ok()、status(201)有什么区别吗?他们都工作正常。
    • 你的意思是:@Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) 不灵活?在您的方法中,您迭代列表的所有元素,但使用 @Produces 注释,我们不会迭代。它以 Json 格式传输数据。
    • 它以某种方式进行映射。如果您要继续使用这种方法,我建议您弄清楚 Jersey/JAX-RS 是如何在幕后进行的。至于状态,201 是 Created,而不是 Okay。 201 不适合 GET。 Response.ok() 与 status(200) 或 Response.status(Status.OK) 相同。
    猜你喜欢
    • 1970-01-01
    • 2014-04-20
    • 2013-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多