首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JAX-RS在REST中的错误处理

JAX-RS在REST中的错误处理
EN

Stack Overflow用户
提问于 2016-08-16 09:46:20
回答 5查看 21.9K关注 0票数 15

的任务:不是在我的堆栈跟踪中接收通用的HTTP 500 Internal Server Error,而是在客户端看到相同的可怕的堆栈跟踪,我希望看到我用另一个状态代码(例如403)定制的消息,对于开发人员来说,这将更加清晰,已经发生了什么。并向用户添加一些有关异常的消息。

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

服务器部分:

AppException.class -所有我的服务器响应异常(在返回给客户端之前),我想转换成这个异常。类标准实体类

代码语言:javascript
运行
复制
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运行时,而不是标准异常.

代码语言:javascript
运行
复制
    @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的服务类

代码语言:javascript
运行
复制
 @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。在这里,我希望根据状态将每个响应异常转换为另一个异常。

代码语言:javascript
运行
复制
@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个状态代码。

代码语言:javascript
运行
复制
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有关。

代码语言:javascript
运行
复制
@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.

几乎再次更新了整个问题!

EN

回答 5

Stack Overflow用户

发布于 2016-08-16 11:21:01

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

票数 4
EN

Stack Overflow用户

发布于 2016-08-19 10:43:27

执行错误处理的正确方法是注册ExceptionMapper实例,这些实例知道在发生特定(或一般)异常时应该返回什么响应。

代码语言:javascript
运行
复制
@Provider
public class PermissionExceptionHandler implements ExceptionMapper<PermissionException>{
    @Override
    public Response toResponse(PermissionException ex){
        //You can place whatever logic you need here
        return Response.status(403).entity(yourMessage).build();
    }  
}

请看我的另一个答案,以获得更多细节:https://stackoverflow.com/a/23858695/2588800

票数 3
EN

Stack Overflow用户

发布于 2016-08-25 12:40:58

这是一个泽西实例,但是您可以从这里中提取所需的信息。最后,我只会抛出一个异常,并将此异常映射到任何想要的响应。

让我们假设您有以下ressource方法,发现了异常:

代码语言:javascript
运行
复制
@Path("items/{itemid}/")
public Item getItem(@PathParam("itemid") String itemid) {
  Item i = getItems().get(itemid);
  if (i == null) {
    throw new CustomNotFoundException("Item, " + itemid + ", is not found");
  }

  return i;
}

创建异常类:

代码语言:javascript
运行
复制
public class CustomNotFoundException extends WebApplicationException {

  /**
  * Create a HTTP 404 (Not Found) exception.
  */
  public CustomNotFoundException() {
    super(Responses.notFound().build());
  }

  /**
  * Create a HTTP 404 (Not Found) exception.
  * @param message the String that is the entity of the 404 response.
  */
  public CustomNotFoundException(String message) {
    super(Response.status(Responses.NOT_FOUND).
    entity(message).type("text/plain").build());
  }
}

现在添加异常映射程序:

代码语言:javascript
运行
复制
@Provider
public class EntityNotFoundMapper implements ExceptionMapper<CustomNotFoundException> {
  public Response toResponse(CustomNotFoundException  ex) {
    return Response.status(404).
      entity("Ouchhh, this item leads to following error:" + ex.getMessage()).
      type("text/plain").
      build();
  }
}

最后,您必须注册异常映射器,以便可以在应用程序中使用它。下面是一些伪代码:

代码语言:javascript
运行
复制
register(new EntityNotFoundMapper());
//or
register(EntityNotFoundMapper.class);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38971609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档