2017-07-20 89 views
2

我有一個休息方法如何DeferredResult,春季啓動hanlde例外

@RequestMapping(value = "wash/washHistory", method = RequestMethod.GET, produces = "application/json;charset=UTF-8") 
    @ResponseBody 
    public DeferredResult<String> getWashHistory(@RequestParam(value = "sid", required = true, defaultValue = "") String sid, 
      HttpServletResponse response, HttpServletRequest request, 
      @RequestParam(value = "sort", defaultValue = "") String sortType, 
      @RequestParam(value = "order", defaultValue = "") String order, 
      @RequestParam(value = "limit", defaultValue = "") String limit, 
      @RequestParam(value = "offset", defaultValue = "") String offset) { 

     System.out.println("Thread: "+Thread.currentThread()); 
     final Integer managerId = checkSession(sid);  
     DeferredResult<String> defResult = new DeferredResult<>(); 
     new Thread(() -> { 
       final String result = washController.getWashHistory(managerId, order, sortType, limit, offset); 
       defResult.setResult(result);    
     }).start(); 
    return defResult; 
    } 

內部「getWashHistory」我把下面的自定義異常

throw new InvalidUserInputException("Wrong offset", this.getClass().getSimpleName(), "getWashHist", params); 

,並處理這個異常我使用以下類

@ControllerAdvice 
@EnableWebMvc 
public class GlobalExceptionHandler { 
@ExceptionHandler(value = InvalidUserInputException.class) 
    public ResponseEntity<String> invalidUserInputExc(InvalidUserInputException e) { 
      logger.log("GMoika", e.error().getClassName(), e.error().getMethodName(), e.error().getParams(), e.error().getCause()); 
     return ResponseEntity. 
       status(HttpStatus.BAD_REQUEST). 
       body(e.error().getErrorCode()); 
    } 
} 

它工作正常,如果我不使用DeferredResult,但是當我不想使用非blo盛泰路,我在歌廳超時異常, 我發現修復它

defResult.onTimeout(new Runnable() { 
     @Override 
     public void run() { 
      defResult.setErrorResult("Explanation goes here."); 
      response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); //or SC_NO_CONTENT 
     } 
    }); 

一個方式,但它不是我要找的,因爲我把我自己的異常與特定的構造函數裏面寫所在班級原因這個異常被拋出。 是否有任何可能的方法來處理我的GlobalExceptionHandler類中的DeferredResult中的異常?

回答

1

DeferredResult具有方法setErrorResult可以採取異常,並根據documentation

的值可以是一個異常或Throwable的在這種情況下這將是 處理,如同一個處理程序引發的異常。

+0

這不是我要找的,因爲我在GlobalExceptionHandler中有一些業務邏輯,所以我需要處理這個類的異常 –

+0

我相信這正是會發生的事情。 'setErrorResult'中設置的異常將由'GlobalExceptionHandler'處理。 – jny

+0

謝謝,但我找到了另一種方式=) –

0

@jny的決定是正確的,大多數情況下,但對我來說,我發現在我的休息控制器的另一種方式 1)我添加以下代碼

new Thread(() -> {   
      Thread.currentThread().setUncaughtExceptionHandler(new SeparateThreadsExceptionHandler(defResult)); 
      final String result = washController.getWashHistory(managerId, order, sortType, limit, offset); 
      defResult.setResult(result); 
     }).start(); 

SeparateThreadsExceptionHandler類:

public class SeparateThreadsExceptionHandler implements Thread.UncaughtExceptionHandler{ 
    private DeferredResult<String> dr; 
    public SeparateThreadsExceptionHandler(DeferredResult<String> dr){ 
     this.dr = dr; 
    } 
    @Override 
    public void uncaughtException(Thread t, Throwable e) { 
     if(e instanceof InvalidUserInputException){ 
      InvalidUserInputException throwableException = (InvalidUserInputException)e; 
      dr.setResult(throwableException.error().getErrorCode()); 
     } else { 
      dr.setResult(UnknownException.UNKNOWN_ERROR_CODE); 
     } 
    } 

} 

當我的cusotm異常被拋出時,我可以將一些字符串傳遞給DeferredResult,在我的例子中它是前端的錯誤代碼