1

Ok I have a package with two restful web service class Login.class and Subscribe.class. When I deploy them to the app engine and test them they work. Now I add a new service class name User s.class to the package now none of my service works when I invoke them I get a internal server error.

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

SEVERE: Producing media type conflict. The resource methods public javax.ws.rs.core.Response com.ppsjamaica.webservices.PPSUsers.getUserById(java.lang.Long) and public javax.ws.rs.core.Response com.ppsjamaica.webservices.PPSUsers.getUserByUsernamePassword(java.lang.String,java.lang.String) can produce the same media type

Uncaught exception from servlet

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

my Subscribe class is:

   @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
}

my login class is:

    @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

and my users class is:

@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

When I delete the user class and upload back the other two services starts working again. What is causing this? 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 -->
Mario Dennis
  • 2,766
  • 10
  • 28
  • 47

2 Answers2

4

Please don't ever design a service that requires users to put password in the URI.

On why it is failing: both methods use the same URI template (note the fact that each of them injects different query parameters does not mean they are mapped to a different URI - it is the value of @Path annotation that matters - and it is the same for both). You have to disambiguate them by mapping them to a different URI template.

Martin Matula
  • 7,889
  • 1
  • 29
  • 35
0

On approach is to create a custom exception that inherits from WebApplicationException; you can see more details here. You should not throw directly a RuntimeException because the container does not know if it is an expected behavior.

Another approach is to annotate your custom exception (which inherits directly from RuntimeException) with @ApplicationException although I do not know if this is the way to do it in JAX-RS; only in EJB.

Community
  • 1
  • 1
Random42
  • 8,072
  • 6
  • 48
  • 79