泽西岛生产媒体类型冲突

2022-09-03 05:23:09

我目前正在尝试泽西岛,按照链接在netbeans中设置Web服务。我有我的实体类和我的 REST 类。它的工作原理是从javafx2客户端添加,编辑,删除,请求对象(在本例中为用户对象)。

但是,现在我尝试向我的Web服务添加一个新方法,以进行一些简单的身份验证。首先,我在 Users.java 文件中添加了一个新的命名查询 (Users.login):

@NamedQueries({
    @NamedQuery(name = "Users.findAll", query = "SELECT u FROM Users u"),
    @NamedQuery(name = "Users.login", query = "SELECT u FROM Users u WHERE u.username = :username AND u.password = :password"),
    @NamedQuery(name = "Users.findById", query = "SELECT u FROM Users u WHERE u.id = :id"),
    @NamedQuery(name = "Users.findByUserlevel", query = "SELECT u FROM Users u WHERE u.userlevel = :userlevel"),
    @NamedQuery(name = "Users.findByDisabled", query = "SELECT u FROM Users u WHERE u.disabled = :disabled")
})

之后,我将以下代码添加到我的UsersFacadeREST.java文件(由Netbeans 7.2生成):

@GET
@Path("{username}/{password}")
@Produces({"application/xml", "application/json"})
public Users login(@PathParam("username") String username, @PathParam("password") String password) {
    return em.createNamedQuery("login", Users.class)
            .setParameter("username", username)
            .setParameter("password", password)
            .getSingleResult();
}

但是,在尝试部署 Web 服务时收到以下错误:

SEVERE: Producing media type conflict. The resource methods public entities.Users service.UsersFacadeREST.login(java.lang.String,java.lang.String) and public java.util.List service.UsersFacadeREST.findRange(java.lang.Integer,java.lang.Integer) can produce the same media type

由于我是新手,我不知道为什么login()方法与findRange()发生冲突?第一个有 2 个 String 参数并给出一个 Users 对象,第二个有 2 个整数参数并返回一个 List 对象?有没有办法解决这个问题,因为我需要将一些自定义查询添加到我的Web服务中...

完成:

@GET
@Path("{from}/{to}")
@Produces({"application/xml", "application/json"})
public List<Users> findRange(@PathParam("from") Integer from, @PathParam("to") Integer to) {
    return super.findRange(new int[]{from, to});
}

超类中的代码(抽象外观.java)

public List<T> findRange(int[] range) {
    javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
    cq.select(cq.from(entityClass));
    javax.persistence.Query q = getEntityManager().createQuery(cq);
    q.setMaxResults(range[1] - range[0]);
    q.setFirstResult(range[0]);
    return q.getResultList();
}

答案 1

问题是,这两种方法都使用与相同 URI 匹配的路径模板。 等价于 - 以同样的方式等价于 。而且由于这两种方法也使用相同的媒体类型,因此存在歧义。您可以通过在路径模板中使用正则表达式来解决此问题,以使其更具体。即,由于应始终为数字,因此您可以通过更改它来消除歧义,如下所示:."{a}/{b}""{c}/{d}""{username}/{password}""{from}/{to}""{from}/{to}""{from: [0-9]+}/{to: [0-9]+}"

无论如何,您确定没有用户会从用户名和密码中选择纯数字吗?看起来在你的情况下,最好对两个资源中的每个资源使用不同的URI“子空间”。例如:和 .login/{username}/{password}ranges/{from}/{to}

但是,关于设计的几点:

  1. 将密码放在URI中是一个非常糟糕的主意。永远不要这样做!看看一些现有的经过验证的身份验证方案 - 不要试图重新发明轮子。
  2. 考虑使用查询参数来指定范围 - 例如,如果您有一些集合资源(如“myapp.com/calendar/events”),则可以使用查询参数对范围进行建模 - 例如“myapp.com/calendar/events?from=xxx&to=yyy。

答案 2

推荐