JAX-RS 与 RESTeasy Factory

JAX-RS with RESTeasy Factory

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

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() 回复。例如,对于用户,我将使用以下 class 创建方法和后续更新、删除和 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\"}";
    } 

我将不得不为每个 classes 重复相同的代码。有人评论过使用工厂 class 来避免这种情况,可能使用泛型或接口。我很难弄明白。请提出一个好的设计来解决这个问题。

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

因为@Path 注释对所有人来说都是不同的,所以创建一个新的 Api 是可以接受的;

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

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

现在我们创建这个 AbstractCrudApi 摘要 class。 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 return 类型而不是字符串。这将允许您设置 http 响应状态以及您的响应正文。您也可以尝试使用 Jackson 来编组您的响应对象。检查 resteasy-jackson2-provider.