我正在使用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似乎没有做任何事情?
先谢谢。亚历
答案 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();
}
部分资源: