在使用spring的时候,如果Controller中抛出异常,会被spring显示在客户端界面,而日志中一般没有记录。
客户端对异常的显示也是经spring处理后的信息,没有堆栈,这不方便找错和改错。
可以通过RestControllerAdvice注解定义一个异常处理类来解决这个问题。代码如下
注:也可以不继承ResponseEntityExceptionHandler类,此处继承只是省了一些通用异常的处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.NoHandlerFoundException; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
@RestControllerAdvice public class ControllerExceptionHandler extends ResponseEntityExceptionHandler { private static final Log log = LogFactory.getLog(ControllerExceptionHandler.class);
@ExceptionHandler(Throwable.class) @ResponseBody ResponseEntity<Object> handleControllerException(Throwable ex, WebRequest request) { Map<String,String> responseBody = new HashMap<>(); responseBody.put("message","internal server error. " + ex.getMessage()); Exception e; if(ex instanceof Exception) { e = (Exception) ex; }else { e = new Exception(ex); } return handleExceptionInternal(e, responseBody, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR, request); }
@Override protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) { if(log.isErrorEnabled()) { log.error("内部错误", ex); } return super.handleExceptionInternal(ex, body, headers, status, request); } }
|