Java Jersey PathParams Checking和NotFoundException自定义消息

时间:2015-03-13 16:26:18

标签: java rest exception-handling jax-rs jersey-2.0

我正在使用Jersey for rest API,JerseyTests进行单元测试。

我一直关注通过互联网进行PathParams检查和异常处理的传统做法,但我不太明白我在做错了什么:

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 == "wrong@email.com" || requestNumber == "wrong") {
            throw new NoRoomApplicationFoundException("bad request");
        }

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

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

我处理这样的例外:

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);
    }
}

我这样测试:

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("valid@email.com").path("12345").request().get();

        assertEquals(200, res.getStatus());
        assertEquals("12345 is valid for valid@email.com", res.readEntity(String.class));
    }

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

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

}

问题1 :这种对params进行条件检查的方法是错误的吗?电子邮件无效的第二次测试的结果应该抛出我的自定义异常并返回404,而是返回200和有效消息。

问题2 :在这种情况下,我该如何处理丢失的参数?看来Jersey默认抛出NotFoundException。是否有一种简单的方法来自定义该错误的消息,或者可能使用我的自定义异常作为抛出,在我的资源方法结束时NoRoomApplicationFoundException似乎没有做任何事情?

先谢谢。亚历

1 个答案:

答案 0 :(得分:1)

问题1

是。问题是您使用==来比较字符串。您应该使用String.equals()。见How do I compare Strings in Java?

if ("wrong@email.com".equals(email) || "wrong".equals(requestNumber)) {
    throw new NoRoomApplicationFoundException("bad request");
}

问题2:

这个问题似乎与您的第一个问题有关。但对我来说,作为一般规则(这只是我),如果我正在创作异常类,并且该异常特定于我的JAX-RS应用程序(意味着我在JAX-RS应用程序之外没有用它),我将使异常扩展WebApplicationException。默认情况下将处理此异常,您可以在该类中创建Response。不需要任何ExceptionMapper。例如

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);
    }
}

你可以完全摆脱NotFoundMapper,这样就可以了。

if ("wrong@email.com".equals(email) || "wrong".equals(requestNumber)) {
    throw new NoRoomApplicationFoundException();
}

部分资源: