Я пытаюсь реализовать веб-сервис, используя Jersey 2.22.2
и Jetty 9.1.1.v20140108
с сопоставлением исключений. Следующий класс представляет класс Exception с реализованным Mapper.
@Provider
public class NotFoundException extends Exception implements ExceptionMapper<NotFoundException> {
private static final long serialVersionUID = 1L;
public NotFoundException() {
}
public NotFoundException(String s) {
super(s);
}
@Context
private UriInfo uriInfo;
@Override
public Response toResponse(NotFoundException e) {
Status status = Status.NOT_FOUND;
ErrorWrapper errorWrapper = new ErrorWrapper();
errorWrapper.setStatusCode(status.getStatusCode());
errorWrapper.setTitle(status.getReasonPhrase());
errorWrapper.setErrorMessage("The resource you're looking for cannot be found.");
errorWrapper.setApiPath(uriInfo.getAbsolutePath().getPath());
return Response.status(status).entity(errorWrapper).type(MediaType.APPLICATION_JSON).build();
}
}
Чтобы проверить, работает это или нет, я создал конечную точку, которая просто генерирует указанное выше исключение, например:
@GET
@Path("test")
@Produces(MediaType.APPLICATION_JSON)
public Response test() throws NotFoundException {
throw new NotFoundException();
}
Вызов этой конечной точки возвращает JSON
, например:
{
"statusCode": 404,
"title": "Not Found",
"errorMessage": "The resource you're looking for cannot be found.",
"apiPath": "/users/test"
}
Исходя из этого, я с уверенностью предположил, что сопоставление исключений работает.
Теперь, что я попытка сделать это - выдать это исключение, если метод DAO
возвращает объект null
, например, при попытке извлечь строку базы данных, которая еще не существует. Ниже приведены мои попытки реализации:
DAO:
public User getUserById(Integer id) throws NotFoundException {
try (DSLContext ctx = new DSLContextFactory("iotrest")
.getDSLContext(getDbDataSource("iotrest"))) {
User user = queries.getUserById(ctx, id)
.fetchOne()
.into(User.class);
if (user == null
|| user.getId() == null) {
throw new NotFoundException("User with id " + id + " not found");
}
UserAccessRights userAccessRights = queries.getUserAccessRights(ctx, user.getId())
.fetchOne()
.into(UserAccessRights.class);
if (userAccessRights == null) {
throw new NotFoundException("Access rights not found for user id " + id);
}
setUserAccessRights(user, userAccessRights);
return user;
}
}
Служба:
public User getUserById(Integer id) throws NotFoundException {
return userDao.getUserById(id);
}
Ресурс:
@GET
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getUserById(@PathParam("id") Integer id) throws NotFoundException {
User user = new UserService().getUserById(id);
return Response.ok(user).build();
}
Но, когда я звоню конечная точка использует идентификатор, который еще не существует (2), и получает NullPointerException
, я все еще получаю HTTP 500 Request Failed
от Jetty вместо 404 от NotFoundException
, например:
<code> <html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1" />
<title>Error 500 </title>
</head>
<body>
<h2>HTTP ERROR: 500</h2>
<p>Problem accessing /users/2. Reason:
<pre> Request failed.
Powered by Jetty: // Может действительно помочь с этим.