Exception jax-rs异常映射器实现问题

Exception jax-rs异常映射器实现问题,exception,jersey,mapping,jax-rs,Exception,Jersey,Mapping,Jax Rs,我正在尝试使用带有异常映射的Jersey 2.22.2和Jetty 9.1.1.v20140108实现一个web服务。下面的类表示实现了映射器的异常类 @Provider public class NotFoundException extends Exception implements ExceptionMapper<NotFoundException> { private static final long serialVersionUID = 1L;

我正在尝试使用带有异常映射的
Jersey 2.22.2
Jetty 9.1.1.v20140108
实现一个web服务。下面的类表示实现了映射器的异常类

    @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();
    }
}
调用此端点将返回一个
JSON
,如下所示:

@GET
@Path("test")
@Produces(MediaType.APPLICATION_JSON)
public Response test() throws NotFoundException {
    throw new NotFoundException();
}
{
"statusCode": 404,
"title": "Not Found",
"errorMessage": "The resource you're looking for cannot be found.",
"apiPath": "/users/test"
}
    <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.</pre>
    </p>
    <hr /><i><small>Powered by Jetty://</small></i>
</body>

</html>
User user = queries.getUserById(ctx, id)
                .fetchOne()
                .into(User.class);
{
"statusCode": 404,
"title": "Not Found",
"errorMessage": "The resource you're looking for cannot be found.",
"apiPath": "/users/2"
}
因此,我有点安全地假设异常映射正在工作

现在,我要做的是抛出这个异常,如果
DAO
方法返回一个
null
对象,例如当试图获取一个还不存在的数据库行时。以下是我的实施尝试:

道:

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();
}
但是,当我使用一个尚不存在的id调用端点(2)并获得一个
NullPointerException
,我仍然从Jetty获得一个
HTTP 500请求失败的
,而不是从
NotFoundException
获得404,如下所示:

@GET
@Path("test")
@Produces(MediaType.APPLICATION_JSON)
public Response test() throws NotFoundException {
    throw new NotFoundException();
}
{
"statusCode": 404,
"title": "Not Found",
"errorMessage": "The resource you're looking for cannot be found.",
"apiPath": "/users/test"
}
    <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.</pre>
    </p>
    <hr /><i><small>Powered by Jetty://</small></i>
</body>

</html>
User user = queries.getUserById(ctx, id)
                .fetchOne()
                .into(User.class);
{
"statusCode": 404,
"title": "Not Found",
"errorMessage": "The resource you're looking for cannot be found.",
"apiPath": "/users/2"
}

误差500
HTTP错误:500
访问/users/2时出现问题。原因:
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;
        }
    }
请求失败。


由码头提供动力://

我真的需要一些帮助

您没有抛出NotFoundException。 您的代码正在抛出NullPointerException

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;
        }
    }
您需要将代码更改为以下内容:

@GET
@Path("test")
@Produces(MediaType.APPLICATION_JSON)
public Response test() throws NotFoundException {
    throw new NotFoundException();
}
{
"statusCode": 404,
"title": "Not Found",
"errorMessage": "The resource you're looking for cannot be found.",
"apiPath": "/users/test"
}
    <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.</pre>
    </p>
    <hr /><i><small>Powered by Jetty://</small></i>
</body>

</html>
User user = queries.getUserById(ctx, id)
                .fetchOne()
                .into(User.class);
{
"statusCode": 404,
"title": "Not Found",
"errorMessage": "The resource you're looking for cannot be found.",
"apiPath": "/users/2"
}

@galusben
的建议有助于找到解决方案。显然,这条线是在投掷NPE

UsersRecord usersRecord = queries.getUserById(ctx, id).fetchOne();
因此,基本上我所做的是,在将结果集提交给
User
之前,我检查记录本身是否存在于表中,如下所示

if (usersRecord == null) {
            throw new NotFoundException("User with id " + id + " not found");
        }
User user = usersRecord.into(User.class);
然后,对该对象执行空检查,并继续将记录存储到pojo中

http://localhost:7000/users/2
对端点进行如下测试:

@GET
@Path("test")
@Produces(MediaType.APPLICATION_JSON)
public Response test() throws NotFoundException {
    throw new NotFoundException();
}
{
"statusCode": 404,
"title": "Not Found",
"errorMessage": "The resource you're looking for cannot be found.",
"apiPath": "/users/test"
}
    <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.</pre>
    </p>
    <hr /><i><small>Powered by Jetty://</small></i>
</body>

</html>
User user = queries.getUserById(ctx, id)
                .fetchOne()
                .into(User.class);
{
"statusCode": 404,
"title": "Not Found",
"errorMessage": "The resource you're looking for cannot be found.",
"apiPath": "/users/2"
}
服务器现在终于返回了
NotFoundException


我做了你建议的修改,但那根本没用。我仍然得到
NullPointerException