【问题标题】:Two try catch blocks on controller level控制器级别的两个 try catch 块
【发布时间】:2017-05-18 10:29:12
【问题描述】:

我有一个案例,我需要在控制器级别重复 try..catch 块。 让我提供此问题的示例代码:

List<String> loadedList =
engine.findSomething(param); //At this point we can obtain Exception, so this code block we should move to existing try block or create another.. but the problem if we move this to try block below, the WebApplicationException that throws in condition below will be catched in existing try block..

// if not found - return NOT_FOUND.
if (CollectionUtils.isEmpty(loadedList)) {
    log.info(errorMessage);
    throw new WebApplicationException(Response.status(Status.NOT_FOUND).entity(errorMessage).type("text/plain").build()); //exception from Jersey lib
}

try {
    for (String item : loadedList) {
        //some business logic
        //I know that on controller layer we should avoid business logic but it is not my code and I can not change it..
    }
    return Response.ok().build();

} catch (Exception e) {
    throw processException(e); //Helper method that avoids code duplication when preparing webException
}

如何重构这段代码?

谢谢!

【问题讨论】:

  • 这是一个 Spring 控制器吗?
  • "但它不是我的代码,我无法更改它.." 但是你想重构它吗?
  • 是的,它是 Spring 控制器,我无法移动业务逻辑,因为它不在当前任务的范围内:)
  • 可以捕获异常,检查是否是WebApplicationException,如果是则再次抛出。

标签: java exception-handling jersey try-catch throw


【解决方案1】:

您可以从@ControllerAdvice 中受益并实现全局控制器异常处理程序。

@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(Exception.class)
public String handleException(HttpServletRequest request, Exception ex){
    //handle error here
    return "error";
}

为了使 GlobalExceptionHandler 工作,必须从控制器中抛出异常。

【讨论】:

    【解决方案2】:

    您可以简单地为

    添加特定的try/catch 语句
    List<String> loadedList = engine.findSomething(param);
    

    调用。

    您应该在调用engine.findSomething(param); 之前声明List&lt;String&gt; loadedList,以便它在try catch 范围之外以便以后能够使用它。

    List<String> loadedList = null;
    try{
       loadedList = engine.findSomething(param); 
    }
    catch (Exception e){ // or a more specific exception if it makes sense
        // exception logging and processing    
    }
    

    【讨论】:

    • 但是在控制器中使用两个 try .. catch 块是一个好习惯吗?
    • 在控制器或其他地方进行操作本身并不是真正的问题。如果您需要捕获异常以进行处理,则必须捕获异常。如果不是这样,你必须让它传播得更高。
    【解决方案3】:
    try 
    {
        List<String> loadedList = engine.findSomething(param); 
    
        // if not found - return NOT_FOUND.
        if (CollectionUtils.isEmpty(loadedList)) {
           log.info(errorMessage);
           throw new WebApplicationException(Response.status(Status.NOT_FOUND).entity(errorMessage).type("text/plain").build()); //exception from Jersey lib
        }
    
        for (String item : loadedList) {
            //some business logic
            //I know that on controller layer we should avoid business logic but it is not my code and I can not change it..
        }
        return Response.ok().build();
    
    }
    //You can first catch WebApplicationException before the Exception and 
    //redirect the throw to the parent class
    catch(WebApplicationException we) 
    {
        throw we;
    }
    catch(Exception e)
    {
        throw processException(e);
    }
    

    【讨论】:

    • 我也考虑过这种方法,但不幸的是我不确定 engine.findSomething(param) 在另一种情况下是否可以抛出 WebApplicationException ..
    • @badCoder 然后创建您自己的异常并让“if”抛出该异常而不是 WebApplicationException
    【解决方案4】:

    另一种不同于 davidxxx 的方法。

    将代码移到try..catch 子句中。如果它碰巧抛出了 WebApplicationException 然后抓住它,做任何你需要做的事情,然后再次抛出它。

    try {
    
    List<String> loadedList =
    engine.findSomething(param); 
    
    // if not found - return NOT_FOUND.
    if (CollectionUtils.isEmpty(loadedList)) {
        log.info(errorMessage);
        throw new WebApplicationException(Response.status(Status.NOT_FOUND).entity(errorMessage).type("text/plain").build()); //exception from Jersey lib
    }
    
        for (String item : loadedList) {
            //some business logic
            //I know that on controller layer we should avoid business logic but it is not my code and I can not change it..
        }
        return Response.ok().build();
    
    } catch (WebApplicationException e1){
      //log the exception
      //throw it again using throw e1
    } catch (Exception e2) {
        throw processException(e2); //Helper method that avoids code duplication when preparing webException
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-20
      相关资源
      最近更新 更多