泽西&的全球异常处理春天? [英] Global Exception Handling in Jersey & Spring?

查看:69
本文介绍了泽西&的全球异常处理春天?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Jersey& amp;开发RESTful Web服务. Spring 3.2和Open CMIS.

I am developing the RESTful webservices using Jersey & Spring 3.2 along with Open CMIS.

我没有使用Spring的MVC模式,而只是Spring IOC& Jersey SpringServlet,控制器类类似于下面的代码

I am not using MVC pattern of Spring and it's just Spring IOC & Jersey SpringServlet, the controller class is something like below code

@GET
@Path("/{objId:.+}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)

public statusMsg addObject(@PathParam("objId") String objId{

    return repoService.addObject(objId);
}

在repoService中,我正在执行使用CMIS添加对象的业务逻辑,我的问题是,我捕获了5个与CMIS相关的异常,然后是基本异常,即Exception,但是对于每种服务方法,我都必须重复它不想做.

In the repoService I am performing the business logic to add the object using CMIS, my question is that I am catching around 5 exceptions related to CMIS then the base exception i.e Exception but for every service method I have to repeat it which I don't want to do.

我在Google上进行搜索,发现@ControllerAdvice是解决此类问题的最佳解决方案,您可以定义所有选中的&未经检查的异常,以及从应用程序中删除所有try catch块的位置.但这仅适用于MVC模式.

I was searching on Google and found that @ControllerAdvice is the best solution for such problem wheer you can define all the checked & unchecked exceptions and wherever remove all the try catch blocks from the application. But it only work with MVC pattern.

问题1:是否可以在上述Jersey-Spring框架中使用此方法?

Question 1: Is there a way I can use this in above Jersey-Spring framework?

经过更多研究后,我发现Jersey提供了ExceptionMapper来处理自定义的异常,但我想捕获更多的CMIS异常或默认Exception或IO Exception等.

After more reserach I found that Jersey provides ExceptionMapper to handle customized exception but I want to catch more CMIS exception or default Exception or IO Exception etc.

问题2:如何使用ExceptionMapper做到这一点?

Question 2: How can I do it with ExceptionMapper?

问题3:我是采用正确的方法还是您提出任何更好的方法来处理此类问题?

Question 3: Am I on the correct approach or do you suggest any better approach to handle such issues.

谢谢.

推荐答案

我在Tomcat中使用jersey2.11,在ExceptionMapper中使用几乎异常处理. (在域逻辑中,仅数据库回滚过程使用try-catch代码.)

I use jersey2.11 with Tomcat and almost exception handle with ExceptionMapper. (In domain logic, only DB rollback process use try-catch code.)

我认为带有@Provider的ExceptionMapper会自动选择正确的ExceptionMapper.因此,我想此功能对我想捕获更多CMIS异常或默认异常或IO异常等"感到满意.

I think ExceptionMapper with @Provider automatically choose correct ExceptionMapper. So I suppose this function is satisfied with "I want to catch more CMIS exception or default Exception or IO Exception etc."

这段代码是我处理ExceptionMapper设计代码.

This code is my handling ExceptionMapper design code.

@GET
@Produces("application/json")
public String getUser(@NotNull @QueryParam("id") String id, 
  @NotNull @QueryParam("token") String token) throws Exception { // This level throws exceptions handled by ExceptionMapper

  someComplexMethod(id, token); // possible throw Exception, IOException or other exceptions.

  return CLICHED_MESSAGE;
}

2.ExceptionMapper软件包. com.yourdomain.exceptionmapper

AbstractExceptionMapper.java (所有ExceptionMapper类都扩展了此Abstract类)

2.ExceptionMapper package. com.yourdomain.exceptionmapper

AbstractExceptionMapper.java (All ExceptionMapper class extends this Abstract class)

public abstract class AbstractExceptionMapper {
  private static Logger logger = LogManager.getLogger(); // Example log4j2.

  protected Response errorResponse(int status, ResponseEntity responseEntity) {
    return customizeResponse(status, responseEntity);
  }

  protected Response errorResponse(int status, ResponseEntity responseEntity, Throwable t) {
    logger.catching(t); // logging stack trace.

    return customizeResponse(status, responseEntity);
  }

  private Response customizeResponse(int status, ResponseEntity responseEntity) {
     return Response.status(status).entity(responseEntity).build();
  }
 }

ExceptionMapper.java (至少此映射器可以捕获未定义的任何异常,请指定异常映射器.)

ExceptionMapper.java (At least this mapper can catch any exception which is not define specify exception mapper.)

@Provider
 public class ExceptionMapper extends AbstractExceptionMapper implements
 javax.ws.rs.ext.ExceptionMapper<Exception> {

 @Override
 public Response toResponse(Exception e) {
 // ResponseEntity class's Member Integer code, String message, Object data. For response format.
 ResponseEntity re = new ResponseEntity(Code.ERROR_MISC); 

  return this.errorResponse(HttpStatus.INTERNAL_SERVER_ERROR_500, re, e);
 }
}

WebApplicationExceptionMapper.java (指定WebApplicationException)

WebApplicationExceptionMapper.java (Specify WebApplicationException)

@Provider
public class WebApplicationExceptionMapper extends AbstractExceptionMapper implements
    ExceptionMapper<WebApplicationException> {

  @Override
  public Response toResponse(WebApplicationException e) {
    ResponseEntity re = new ResponseEntity(Code.ERROR_WEB_APPLICATION);

    return this.errorResponse(e.getResponse().getStatus(), re, e);
  }
}

ConstraintViolationExceptionMapper.java (指定休眠验证器ConstraintViolationException)

ConstraintViolationExceptionMapper.java (Specify Hibernate Validator ConstraintViolationException)

@Provider
public class ConstraintViolationExceptionMapper extends AbstractExceptionMapper implements
    ExceptionMapper<ConstraintViolationException> {

  @Override
  public Response toResponse(ConstraintViolationException e) {
    ResponseEntity re = new ResponseEntity(Code.ERROR_CONSTRAINT_VIOLATION);

    List<Map<String, ?>> data = new ArrayList<>();
    Map<String, String> errorMap;
    for (final ConstraintViolation<?> error : e.getConstraintViolations()) {
      errorMap = new HashMap<>();
      errorMap.put("attribute", error.getPropertyPath().toString());
      errorMap.put("message", error.getMessage());
      data.add(errorMap);
    }

    re.setData(data);

    return this.errorResponse(HttpStatus.INTERNAL_SERVER_ERROR_500, re, e);
  }
}

..和其他指定的异常可以创建ExceptionMapper类.

.. and other specify exception can create ExceptionMapper classes.

以我的经验,Exception Mapper是专注于域逻辑的高级概念.它可能会从域逻辑中排除无聊的分散try-catch块代码. 因此,我希望您能在问题3中感到是的我",以解决您所处环境中的问题.

In my experience, Exception Mapper is high level idea for focus to domain logic. It could drive out boring scattered try-catch block code from domain logic. So I hope that you feel the "Yes i am" at Question 3 to resolve the problem at your environment.

您还没有在应用程序中的任何地方使用try catch and throw.

我的代码设计使用抛出这样的方法,并通过ExceptionMapper类进行管理.

My code design use throws at method like this and this make to manage by ExceptionMapper classes.

public String getUser(@NotNull @QueryParam("id") String id, 
  @NotNull @QueryParam("token") String token) throws Exception

因此,在上述方法中,我仅为所有可能的异常创建了1个类,对于任何未知的异常,基本Exception都将在该类中捕获. 现在,在我的应用程序中的任何地方,如果发生任何异常,都会涉及到CentralControllerException,并将带有HTTP状态代码的适当响应发送回去. Q.2.您预见到上述方法是否有任何问题.

So in above approach I have created just 1 class for all the exceptions which I could expect and for any unknown exception the base Exception will be there to catch. Now wherever in my application if any exception occurs it comes to the CentralControllerException and appropriate response with http status code is sent back. Q.2. Do you foresee any issue in above approach.

我认为,如果是简单项目,或者从不更新/修改项目(项目生命周期较短),那么您的一类异常映射器就可以了. 但是...我从不采用这种方法.简而言之,如果需要管理更多的异常,此方法将变得庞大而复杂,并且难以阅读和维护.

I think if simple project or never update/modify project (project lifecycle short time), your one class exception mapper approach ok. But ... i never take this approach. Simply, if need to manage more exception, this method become big and complex, and hard to read and maintain becoming.

在我的政策中,OOP应该在任何级别的代码(类计划,DI计划)中使用多态策略,并且该方法的某些部分旨在消除代码中的if/switch块.这个想法使每种方法的代码简短,简单,对域逻辑"清晰明了,并且代码变得难以修改.

In my policy, OOP should use pleomorphism strategy any level code(class plan, DI plan) and this approach some part aim to drive out if/switch block in code. And this idea make each method short code and simple, clear to "domain logic" and code become to resistant to modify.

因此,我创建了一个实现ExceptionMapper并委托给ExceptionMapper类管理例外的DI. (因此,DI管理替换您的单个类.如果块管理哪个异常处理,通常这是一种重构方法,类似于Extract xxx http ://refactoring.com/catalog/extractClass.html . 在我们的讨论情况下,单个类和一个方法太忙了,因此提取每个接近ExceptionMapper的类,然后DI调用合适的类&.方法策略.)

So i create implements ExceptionMapper and delegate to DI which ExceptionMapper class manage to exception. (So DI manage replace your single class If block manage which exception handling, this is typically refactoring approach similar Extract xxx http://refactoring.com/catalog/extractClass.html. In our discussion case, single class and one method too busy, so extract each ExceptionMapper class approaching and DI call suitable class & method strategy.)

顺便说一句,目前系统处理结果是相同的.但是如果需要降低未来的开发成本,则不应采取一种一类的异常处理方案.因为如果仅放弃代码并重构状态,项目代码就会死得更快.

Btw, system processing result is same at present point. But if need to reduce future development cost ,should not took approach one class exception handling plan. Because if give up simply code and refactor status, project code is dead faster.

这是我的主意,为什么呢.

This is my idea and why this.

致谢.

这篇关于泽西&amp;的全球异常处理春天?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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