使用JAX-RS在REST API中进行错误处理 [英] Error handling in REST API with JAX-RS

查看:138
本文介绍了使用JAX-RS在REST API中进行错误处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任务:而不是在我的堆栈跟踪中接收一般的 HTTP 500内部服务器错误,而不是在客户端上同样可怕的堆栈跟踪我希望看到我的自定义消息与另一个状态代码(例如 403 ),开发人员会更清楚,发生了什么。并向用户添加一些关于异常的消息。

The task: Instead of receiving general HTTP 500 Internal Server Error in my stacktrace and the same horrible stacktrace on the client side I want to see my customized message with another statuscode (403 for example), that it will be much clearer for the developer, what has happend. And add some message to User about the Exception.

以下是我的应用程序中的几个更改的类:

Here are couple of changed classes from my application:

服务器部分:

SERVER PART:

AppException.class - 我的所有服务器响应异常(在回馈客户端之前)我想转换为此异常。有点标准实体类

AppException.class - all my Server Response exceptions (before giving back to client) I want to transform into this exception. Kinda standard entity class

public class AppException extends WebApplicationException {

Integer status;

/** application specific error code */
int code;

/** link documenting the exception */
String link;

/** detailed error description for developers */
String developerMessage;

public AppException(int status, int code, String message, String developerMessage, String link) {
    super(message);
    this.status = status;
    this.code = code;
    this.developerMessage = developerMessage;
    this.link = link;
}

public int getStatus() {
    return status;
}

public void setStatus(int status) {
    this.status = status;
}

public int getCode() {
    return code;
}

public void setCode(int code) {
    this.code = code;
}

public String getDeveloperMessage() {
    return developerMessage;
}

public void setDeveloperMessage(String developerMessage) {
    this.developerMessage = developerMessage;
}

public String getLink() {
    return link;
}

public void setLink(String link) {
    this.link = link;
}

public AppException() {
}

public AppException(String message) {
    super("Something went wrong on the server");
}
}

ÀppExceptionMapper。 class - 将我的AppException映射到JAX-RS运行时,而不是标准异常,客户端接收AppException。

ÀppExceptionMapper.class - mapps my AppException to the JAX-RS Runtime, instead standard exception, client receives AppException.

    @Provider
public class AppExceptionMapper implements ExceptionMapper<AppException> {

    @Override
    public Response toResponse(AppException exception) {
        return Response.status(403)
                .entity("toResponse entity").type("text/plain").build();
    }


}

ApplicationService.class - 我的Service类抛出AppException

ApplicationService.class- my Service class that throws AppException

 @Path("/applications")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public interface ApplicationService {


    @DELETE
    @Path("/deleteById")
    void deleteById(@NotNull Long id) throws AppException;
}

客户端部分:

CLIENT PART:

ErrorHandlingFilter.class - 我的AppException响应捕手。在这里,我想根据状态将每个Response异常转换为另一个异常。

ErrorHandlingFilter.class- my Response catcher of the AppException. Here I want to transform each Response exception to another exception depending on the status.

@Provider
public class ErrorHandlingFilter implements ClientResponseFilter {

    private static ObjectMapper _MAPPER = new ObjectMapper();

    @Override
    public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
        if (responseContext.getStatus() != Response.Status.OK.getStatusCode()) {
            if(responseContext.hasEntity()) {
                Error error = _MAPPER.readValue(responseContext.getEntityStream(), Error.class);
                String message = error.getMessage();

                Response.Status status = Response.Status.fromStatusCode(responseContext.getStatus());
                AppException clientException;

                switch (status) {

                case INTERNAL_SERVER_ERROR:
                    clientException = new PermissionException(message);
                    break;


                case NOT_FOUND:
                    clientException = new MyNotFoundException(message);
                    break;

                default:
                    clientException =  new WhatEverException(message);
                }
                    throw clientException;
        }
    }
    }
}

PermissionException.class - 我想要转换AppException的异常,如果它带有500状态代码。

PermissionException.class - exception in what I want to transform AppException, if it came with 500 status code.

public class PermissionException extends AppException{

        public PermissionException(String message) {
    super("403 - Forbidden. You dont have enough rights to delete this Application");

}

Integer status;

/** application specific error code */
int code;

/** link documenting the exception */
String link;

/** detailed error description for developers */
String developerMessage;

public PermissionException(int status, int code, String message, String developerMessage, String link) {
    super(message);
    this.status = status;
    this.code = code;
    this.developerMessage = developerMessage;
    this.link = link;
}

public int getStatus() {
    return status;
}

public void setStatus(int status) {
    this.status = status;
}

public int getCode() {
    return code;
}

public void setCode(int code) {
    this.code = code;
}

public String getDeveloperMessage() {
    return developerMessage;
}

public void setDeveloperMessage(String developerMessage) {
    this.developerMessage = developerMessage;
}

public String getLink() {
    return link;
}

public void setLink(String link) {
    this.link = link;
}

public PermissionException() {}


}

ApplicationPresenter.class - 一段UI逻辑,我想要通过抛出的PermissionException来处理ErrorHandlingFilter。

ApplicationPresenter.class- piece of UI logic, where I want something to do with PermissionException thrown by the ErrorHandlingFilter.

@SpringPresenter
public class ApplicationPresenter implements ApplicationView.Observer {

@Resource
    private ApplicationService applicationService;

    @Resource
    private UiEnvironment uiEnvironment;

@Override
    public void deleteSelectedApplication(BeanItemGrid<Application> applicationGrid) {

        try {
applicationService.deleteById(applicationGrid.getSelectedItem().getId());
                    } catch (PermissionException e) {
                        e.printStackTrace();
                        e.getMessage();
                    } catch (AppException e2) {
                    }
}
}

如何解决我的问题?我仍然收到标准的 500 InternalErrorException。

How can I resolve my problem? I am still receiving standard 500 InternalErrorException.

更多时间更新了整个问题!

推荐答案

当你有一个ExceptionMapper时,你不会自己捕获异常,但是当框架捕获它时,在HTTP请求上调用资源方法。

When you have an ExceptionMapper, you don't catch the exception yourself, but have the framework catch it, when the resource method is invoked on an HTTP request.

这篇关于使用JAX-RS在REST API中进行错误处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆