【问题标题】:All my Restful web services stopped working when I add new service添加新服务时,我所有的 Restful Web 服务都停止工作
【发布时间】:2012-10-15 17:34:27
【问题描述】:

好的,我有一个包含两个 RESTful Web 服务类 Login.class 和 Subscribe.class 的包。当我将它们部署到应用程序引擎并对其进行测试时,它们可以正常工作。现在,我向包中添加了一个新的服务类名称 User s.class

com.sun.jersey.spi.inject.Errors processErrorMessages: The following errors and warnings have been detected with resource and/or provider classes:

严重:产生媒体类型冲突。资源方法 public javax.ws.rs.core.Response com.ppsjamaica.webservices.PPSUsers.getUserById(java.lang.Long) 和 public javax.ws.rs.core.Response com.ppsjamaica.webservices.PPSUsers.getUserByUsernamePassword( java.lang.String,java.lang.String) 可以产生相同的媒体类型

Uncaught exception from servlet

com.sun.jersey.spi.inject.Errors$ErrorMessagesException 在 com.sun.jersey.spi.inject.Errors.processErrorMessages(Errors.java:170)

我的订阅课程是:

   @Path ("/subscriber")
public class Subscribe {

    @GET
    @Produces (MediaType.APPLICATION_JSON)
    public Response getSubscriber (@QueryParam("email")String email)
    {
        EntityManager entityManager = EMF.getInstance ().createEntityManager ();

        /*
         * Sends back a BAD_REQUEST HTTP status
         * if email query parameter is empty
         */
        if (email.isEmpty ())
            return Response.status(Status.BAD_REQUEST).build ();

        try
        {
            Query query = entityManager.createQuery ("SELECT FROM Subscriber WHERE email= :emailParam");
            query.setParameter("emailParam", email);
            return Response.status(Status.OK).entity((Subscriber) query.getSingleResult ()).build (); 
        }
        catch (NoResultException e)
        {
            return Response.status (Status.NOT_FOUND).build ();
        }

    }//end Subscriber method
}

我的登录类是:

    @Path ("/login")
public class Login {

    @GET
    @Produces (MediaType.APPLICATION_JSON)
    public User authenticate (@QueryParam("username") String username, @QueryParam("password")String password)
    {
        User user = new User ();
        return user;
    }//end authenticate method


    @GET
    @Path ("/Subscriber")
    @Produces (MediaType.APPLICATION_JSON)
    public Response getSubsriber (@QueryParam("email") String email)
    {
        EntityManager entityManager = EMF.getInstance ().createEntityManager();

        try
        {
            Query query = entityManager.createQuery("SELECT FROM Subscriber WHERE email= :emailParam");
            query.setParameter("emailParam", email);

            Subscriber subscriber = (Subscriber)query.getSingleResult();
            return Response.status(Status.OK).entity(subscriber).build ();
        }
        catch(Exception e)
        {
            throw new RuntimeException (e);
        }
    }//end getSubsriber method
}//end Login class

我的用户类别是:

@Path ("/users")
public class Users {


    /**
     * Gets all User objects from datastore. Returns
     * NOT_FOUND HTTP Response status if no result
     * found and OK HTTP Response status if it does with
     * a list of User objects. 
     * 
     * URL: domain-name/services/users/all
     * 
     * @author Mario Dennis
     * @return Response
     */
    @GET
    @Path ("/all")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getAllUsers ()
    {
        try
        {
            EntityManager entityManager = EMF.getInstance().createEntityManager();
            Query query = entityManager.createQuery("SELECT FROM User");

            @SuppressWarnings("unchecked")
            List<User> user = (List<User>) query.getSingleResult ();
            GenericEntity<List<User>> entity = new GenericEntity<List<User>>(user){};

            return Response.status(Status.OK).entity(entity).build ();
        }
        catch (NoResultException e)
        {
            return Response.status(Status.NOT_FOUND).build ();
        }
    }//end getAllUsers method



    /**
     * Gets User object with user name and password specified from
     * datastore. Returns NOT_FOUND HTTP Response status if no result
     * found and OK HTTP Response status if it is found and BAD_REQUEST
     * if parameter supplied is empty.
     * a list of User objects. 
     * 
     * URL: domain-name/services/users/{username}&{password}
     * 
     * @author Mario Dennis
     * @return Response
     */
    @GET
    @Produces (MediaType.APPLICATION_JSON)
    public Response getUserByUsernamePassword (@QueryParam("username")String username,@QueryParam("password") String password)
    {
        /*
         * Sends back a BAD_REQUEST HTTP status
         * if email query parameter is empty
         */
        if (username.isEmpty() || password.isEmpty())
            return Response.status(Status.BAD_REQUEST).build ();

        try
        {
            EntityManager entityManager = EMF.getInstance().createEntityManager ();
            Query query = entityManager.createQuery ("SELECT FROM User WHERE user_name= :usernameParam AND password= :passwordParam");
            query.setParameter("usernameParam", username);
            query.setParameter("passwordParam",password);
            User user = (User) query.getSingleResult ();

            return Response.status(Status.OK).entity(user).build ();
        }
        catch (NoResultException e)
        {
            return Response.status(Status.NOT_FOUND).build ();
        }
    }//end getUserByUsernamePassword method



    /**
     * Gets User object with id specified from datastore. 
     * Returns NOT_FOUND HTTP Response status if no result
     * found and OK HTTP Response status if it is found and 
     * BAD_REQUEST if parameter supplied is empty.
     * a list of User objects. 
     * 
     * URL: domain-name/services/users/{id}
     * 
     * @author Mario Dennis
     * @return Response
     */
    @GET
    @Produces (MediaType.APPLICATION_JSON)
    public Response getUserById (@QueryParam("id")Long id)
    {
        /*
         * Sends back a BAD_REQUEST HTTP status
         * if email query parameter is empty.
         */
        if (id == null)
            return Response.status(Status.BAD_REQUEST).build ();

        try
        {
            EntityManager entityManager = EMF.getInstance ().createEntityManager ();
            User user = entityManager.find(User.class,id);

            /*
             * Checks if user was found. Return a NOT_FOUND
             * HTTP status if user was not located. 
             */
            if (user == null)
                return Response.status(Status.NOT_FOUND).build ();

            else
                return Response.status(Status.OK).entity(user).build();
        }
        catch (NoResultException e)
        {
            return Response.status(Status.NOT_FOUND).build ();
        }
    }//end getUserById method




    /**
     * Save User object to database. Return NOT_MODIFIED
     * HTTP status if persisting of object failed. Otherwise
     * return OK HTTP status if it was successful.
     * 
     * URL: domain-name/services/users/{JSON}
     * 
     * @author Mario Dennis
     * @param user
     * @return Response
     */
    @POST
    @Consumes  (MediaType.APPLICATION_JSON)
    public Response saveUser (User user)
    {
        try
        {
            EntityManager entityManager = EMF.getInstance().createEntityManager();
            entityManager.getTransaction ().begin();
            entityManager.persist(user);
            entityManager.getTransaction().commit();

            return Response.status(Status.OK).build ();
        }
        catch(Exception e)
        {
            return Response.status(Status.NOT_MODIFIED).build ();
        }
    }//end saveUser method

}//end Users class

当我删除用户类并上传回来时,其他两个服务又开始工作了。这是什么原因造成的? web.xml

 <!-- Jersey Framework mapping -->
   <servlet>
        <servlet-name>RESTful</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <init-param>
          <param-name>com.sun.jersey.config.property.packages</param-name>
          <param-value>com.ppsjamaica.webservices</param-value>
        </init-param>
  </servlet>
  <servlet-mapping>
        <servlet-name>RESTful</servlet-name>
        <url-pattern>/service/*</url-pattern>
  </servlet-mapping>
    <!-- end Jersey Framework mapping -->

【问题讨论】:

  • 异常似乎表明 com.ppsjamaica.webservices.PPSUsers 类导致了问题。可以发一下吗?

标签: java web-services google-app-engine web-applications jersey


【解决方案1】:

请永远不要设计要求用户在 URI 中输入密码的服务。

关于失败的原因:两种方法都使用相同的 URI 模板(请注意,它们中的每一个都注入不同的查询参数并不意味着它们被映射到不同的 URI - 重要的是 @Path 注释的值- 两者都是一样的)。您必须通过将它们映射到不同的 URI 模板来消除它们的歧义。

【讨论】:

  • 我可以采取什么其他方法来通过 Web 服务对用户进行身份验证,因为所有数据层都将通过 Web 服务访问
  • Google 用于 HTTP 基本身份验证(始终与 SSL 一起使用 - 即 HTTPS)。
【解决方案2】:

On 方法是创建一个继承自WebApplicationException 的自定义异常;你可以看到more details here。您不应该直接抛出RuntimeException,因为容器不知道这是否是预期行为。

另一种方法是用@ApplicationException 注释您的自定义异常(直接从RuntimeException 继承)虽然我不知道这是否是在JAX-RS 中这样做的方法;仅在 EJB 中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 2018-04-08
    相关资源
    最近更新 更多