проблемы реализации картографирования исключений jax-rs - PullRequest
0 голосов
/ 10 марта 2020

Я пытаюсь реализовать веб-сервис, используя 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: //

Может действительно помочь с этим.

Ответы [ 2 ]

0 голосов
/ 10 марта 2020
Предложение

@galusben сыграло важную роль в поиске решения. Ясно, что в этой строке было выброшено NPE.

User user = queries.getUserById(ctx, id)
                .fetchOne()
                .into(User.class);

Итак, в основном я сделал, прежде чем поместить набор результатов в User, я проверил, существует ли сама запись в таблице, или нет .

UsersRecord usersRecord = queries.getUserById(ctx, id).fetchOne();

Затем произвел нулевую проверку этого объекта и приступил к сохранению записи в pojo.

if (usersRecord == null) {
            throw new NotFoundException("User with id " + id + " not found");
        }
User user = usersRecord.into(User.class);

Протестировал конечную точку следующим образом:

http://localhost:7000/users/2

Сервер наконец-то возвращает NotFoundException

{
"statusCode": 404,
"title": "Not Found",
"errorMessage": "The resource you're looking for cannot be found.",
"apiPath": "/users/2"
}
0 голосов
/ 10 марта 2020

Вы не выбрасываете NotFoundException. Ваш код генерирует исключение NullPointerException.

public User getUserById(Integer id) throws NotFoundException {
        try (DSLContext ctx = new DSLContextFactory("iotrest")
                .getDSLContext(getDbDataSource("iotrest"))) {
            User user = queries.getUserById(ctx, id)
         //The NullPointerException is coming from the following line
                    .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 {
        try (DSLContext ctx = new DSLContextFactory("iotrest")
                .getDSLContext(getDbDataSource("iotrest"))) {
            User user = queries.getUserById(ctx, id);
             if (user == null
                       || user.getId() == null) {
                    throw new NotFoundException("User with id " + id + " not found");
            }
            user.fetchOne()
                .into(User.class);

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