【问题标题】:JAX-RS with RESTeasy Factory带有 RESTeasy 工厂的 JAX-RS
【发布时间】:2017-06-01 06:23:39
【问题描述】:

我试图避免通过JAX-RSRESTeasy 处理客户请求中的样板代码。我有几个类,例如

class User{
    private String name;
    private String username;
    private String address;
    private long id;

    //getters and setters
}

class Company{
    private String name;
    private String address;
    private String location;

    //getters and setters
}

我想要create()update()delete()getAll() 回复。例如,对于用户,我将拥有以下具有创建方法和后续更新、删除和 getAll 的类:

@Path ("/user")
public class UserApi {

    @PersistenceUnit
    private EntityManagerFactory emf;

    @POST
    @Path("/create")
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public String Create(@Form User user){

        EntityManager em = emf.createEntityManager();
        try{
            em.getTransaction().begin();
            em.merge(user);
            em.getTransaction().commit();
        }
        catch (Exception e){
            e.printStackTrace();
            em.getTransaction().rollback();

            return "{\"success\":false, \"msg\":\"Error occured, please  try later\"}";
        }
        return "{\"success\":true, \"msg\": \"Saved successfully\"}";
    } 

我必须为我拥有的每个课程重复相同的代码。有人评论过使用工厂类来避免这种情况,可能使用泛型或接口。我很难弄清楚。请提出一个好的设计来解决这个问题。

【问题讨论】:

    标签: java jax-rs factory resteasy


    【解决方案1】:

    您必须问自己所有实现之间的区别是什么。 在这种情况下,不多。您可以复制/粘贴这段代码,将@Path("/user") 替换为@Path("/company"),将User 替换为Company,Bob 是您的叔叔。 Em.merge() 接受任何对象,所以我们并不关心。

    所以因为@Path注解对所有人都不同,所以像这样创建一个新的Api是可以接受的;

    @Path("/users")
    @Stateless
    public class UserApi extends AbstractCrudApi<User> {}
    

    定义了此 REST 服务独有的所有元素。我们有作为通用类型传递的@Path 和用户。

    现在我们创建这个 AbstractCrudApi 抽象类。 abstract,因为我们要实现所有未来服务的通用逻辑。如您所知,接口不能实现方法。 (让我们忘记 java 8 default 方法)

    @Produces(MediaType.APPLICATION_JSON)
    public abstract class AbstractCrudApi<T> {
    
        @PersistenceContext
        private EntityManager em;
    
        @POST
        @Path("/create")
        @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
        public String create(@Form T entity) {
            try {
                em.getTransaction().begin();
                em.merge(entity);
                em.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                em.getTransaction().rollback();
                return "{\"success\":false, \"msg\":\"Error occured, please  try later\"}";
            }
            return "{\"success\":true, \"msg\": \"Saved successfully\"}";
        }
    }
    

    这就是它的全部。 我不太明白工厂在这里有什么优势。

    另一个提示;尝试使用 javax.ws.rs.core.Response 返回类型而不是字符串。这将允许您设置 http 响应状态以及响应正文。您也可以尝试使用 Jackson 来编组您的响应对象。检查resteasy-jackson2-provider

    【讨论】:

    • 谢谢.. 只是一个简单的问题,为什么我必须用@Produces 注释AbstractCrudApi&lt;T&gt;
    • 我认为,默认情况下,所有响应类型都是 JSON。所以我把它添加到AbstractCrudApi,所以你不需要重复自己。
    猜你喜欢
    • 2014-02-03
    • 2016-10-02
    • 2016-09-11
    • 1970-01-01
    • 1970-01-01
    • 2020-09-08
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多