Reputation: 210
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
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