java - 使用 JAX-RS 处理 REST API 中的错误

标签 java spring rest jersey jax-rs

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

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

服务器部分:

AppException.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。

    @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- 我的抛出 AppException 的服务类

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


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

客户部分:

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

@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 状态代码。

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 逻辑,我想要处理 ErrorHandlingFilter 抛出的 PermissionException。

@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。

几乎将整个问题再更新一次!

最佳答案

当您拥有 ExceptionMapper 时,您不会自己捕获异常,而是让框架在 HTTP 请求上调用资源方法时捕获它。

关于java - 使用 JAX-RS 处理 REST API 中的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38971609/

相关文章:

java - 确保始终从 Spring 应用程序的缓存中检索数据

java - @Autowired(required = false) 删除 bean 后失败

javascript - 跨域情况下 javascript 代码无法访问带有 "Location" header 的 XMLHttpRequest POST 响应

不调用 Spring Data Rest @HandleBeforeCreate 方法

java - 我在通过接口(interface)传递数据时遇到问题

java - 将接口(interface)传递给实现该接口(interface)的类

java 告诉找不到符号

spring - 离线在服务器上部署Maven Spring Boot项目

rest - 纯粹为了使用 HTTP 请求正文而发布

java - weblogic 12.1.3 config.sh 显示错误