Alex Aube
Alex Aube

Reputation: 210

Java Jersey PathParams Checking and NotFoundException custom message

I am using Jersey for rest API, JerseyTests to unit test.

I have been following what seems to be conventional practice over the internet for PathParams checking and Exception Handling, but I don't quite understand what I am doing wrong here:

RoomApplicationResource.java

@Path("demandes")
public class RoomApplicationResource {
    @GET
    @Path("/{email}/{requestNumber}")
    public Response getRoomApplication(
            @PathParam("email") String email, 
            @PathParam("requestNumber") String requestNumber) throws NoRoomApplicationFoundException {

        if (email == "[email protected]" || requestNumber == "wrong") {
            throw new NoRoomApplicationFoundException("bad request");
        }

        String response =requestNumber+" is valid for "+email;

        return  Response.ok(response).build();
    }
}

I handle Exceptions like this:

NotFoundMapper.java

@Provider
public class NotFoundMapper implements ExceptionMapper<NoRoomApplicationFoundException>{

    @Override
    public Response toResponse(NoRoomApplicationFoundException e) {
        return Response.status(Response.Status.NOT_FOUND)
                .entity(e.getMessage()).build();
    }
}

NoRoomApplicationFoundException.java

public class NoRoomApplicationFoundException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    public NoRoomApplicationFoundException() {
        super();
    }

    public NoRoomApplicationFoundException(String msg) {
        super(msg);
    }

    public NoRoomApplicationFoundException(String msg, Exception e) {
        super(msg, e);
    }
}

And I test like this:

RoomApplicationResourceTest.java

public class RoomApplicationResourceTest extends JerseyTest {

    @Override
    protected Application configure() {
        return new ResourceConfig(RoomApplicationResource.class, NotFoundMapper.class);
    }

    // This test works fine as expected
    @Test
    public void whenParametersAreExistantReturnTheOkResponse() {
        final Response res = target("demandes").path("[email protected]").path("12345").request().get();

        assertEquals(200, res.getStatus());
        assertEquals("12345 is valid for [email protected]", res.readEntity(String.class));
    }

    // This does not work as expected
    @Test
    public void whenEmailParameterDoNotMatchToAnyRoomApplicationThenReturns404() {
        final Response res = target("demandes").path("[email protected]").path("12345").request().get();

         assertEquals(404, res.getStatus());
         assertEquals("bad request", res.readEntity(String.class));
    }

}

Question 1: Is this way of doing conditional checking on params wrong? The result of the second test where the email is invalid should throw my custom exception and return a 404, but instead returns a 200 and the valid message.

Question 2: How should I handle missing parameters in this case? It seems Jersey throws a NotFoundException by default. Is there a simple way to customize the message of that error or perhaps use my custom exception as the throws NoRoomApplicationFoundException at the end of my resource method does not seem to be doing anything?

Thanks in Advance. Alex

Upvotes: 1

Views: 2163

Answers (1)

Paul Samsotha
Paul Samsotha

Reputation: 208944

Question 1

Yes. The problem is your use of == to compare Strings. You should instead be using String.equals(). See How do I compare Strings in Java?

if ("[email protected]".equals(email) || "wrong".equals(requestNumber)) {
    throw new NoRoomApplicationFoundException("bad request");
}

Question 2:

This question seems to be related to your first question. But for me, as a general rule (this is just me), if I am authoring the exception class and the exception is specific to my JAX-RS application (meaning I will have no use for it outside the JAX-RS application), I will just make the exception extend WebApplicationException. This exception will be handled by default, and you can create the Response in that class. No need for any ExceptionMapper. For example

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;

public class NoRoomApplicationFoundException extends WebApplicationException {

    private static final long serialVersionUID = 1L;

    public NoRoomApplicationFoundException() {
        this("Room not found", 400);
    }

    public NoRoomApplicationFoundException(String msg, int status) {
        this(Response.status(status).entity(msg).build());
    }

    public NoRoomApplicationFoundException(Response response) {
        super(response);
    }
}

You could completely get rid of the NotFoundMapper and this would work just fine.

if ("[email protected]".equals(email) || "wrong".equals(requestNumber)) {
    throw new NoRoomApplicationFoundException();
}

Some Resources:

Upvotes: 1

Related Questions