mirror of https://github.com/halo-dev/halo
				
				
				
			Complete ControllerExceptionHandler
							parent
							
								
									ee41a620f0
								
							
						
					
					
						commit
						a08fac24a6
					
				|  | @ -23,11 +23,19 @@ public class JsonResult { | ||||||
|      */ |      */ | ||||||
|     private String msg; |     private String msg; | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Dev message.(only setting in dev environment) | ||||||
|  |      */ | ||||||
|  |     private String devMsg; | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * 返回的数据 |      * 返回的数据 | ||||||
|      */ |      */ | ||||||
|     private Object result; |     private Object result; | ||||||
| 
 | 
 | ||||||
|  |     public JsonResult() { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * 只返回状态码 |      * 只返回状态码 | ||||||
|      * |      * | ||||||
|  | @ -71,4 +79,11 @@ public class JsonResult { | ||||||
|         this.code = code; |         this.code = code; | ||||||
|         this.result = result; |         this.result = result; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     public JsonResult(Integer code, String msg, String devMsg, Object result) { | ||||||
|  |         this.code = code; | ||||||
|  |         this.msg = msg; | ||||||
|  |         this.devMsg = devMsg; | ||||||
|  |         this.result = result; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,33 @@ | ||||||
|  | package cc.ryanc.halo.utils; | ||||||
|  | 
 | ||||||
|  | import java.io.PrintWriter; | ||||||
|  | import java.io.StringWriter; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Exception utilities. | ||||||
|  |  * <p>Part from apache commons lang3 project.</p> | ||||||
|  |  * | ||||||
|  |  * @author johnniang | ||||||
|  |  * @see "org.apache.commons.lang3.exception.ExceptionUtils" | ||||||
|  |  */ | ||||||
|  | public class ExceptionUtils { | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * <p>Gets the stack trace from a Throwable as a String.</p> | ||||||
|  |      * | ||||||
|  |      * <p>The result of this method vary by JDK version as this method | ||||||
|  |      * uses {@link Throwable#printStackTrace(java.io.PrintWriter)}. | ||||||
|  |      * On JDK1.3 and earlier, the cause exception will not be shown | ||||||
|  |      * unless the specified throwable alters printStackTrace.</p> | ||||||
|  |      * | ||||||
|  |      * @param throwable the <code>Throwable</code> to be examined | ||||||
|  |      * @return the stack trace as generated by the exception's | ||||||
|  |      * <code>printStackTrace(PrintWriter)</code> method | ||||||
|  |      */ | ||||||
|  |     public static String getStackTrace(final Throwable throwable) { | ||||||
|  |         final StringWriter sw = new StringWriter(); | ||||||
|  |         final PrintWriter pw = new PrintWriter(sw, true); | ||||||
|  |         throwable.printStackTrace(pw); | ||||||
|  |         return sw.getBuffer().toString(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,113 @@ | ||||||
|  | package cc.ryanc.halo.web.controller.base; | ||||||
|  | 
 | ||||||
|  | import cc.ryanc.halo.exception.HaloException; | ||||||
|  | import cc.ryanc.halo.logging.Logger; | ||||||
|  | import cc.ryanc.halo.model.dto.JsonResult; | ||||||
|  | import cc.ryanc.halo.utils.ExceptionUtils; | ||||||
|  | import cc.ryanc.halo.utils.ValidationUtils; | ||||||
|  | import org.springframework.dao.DataIntegrityViolationException; | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.http.ResponseEntity; | ||||||
|  | import org.springframework.util.Assert; | ||||||
|  | import org.springframework.web.bind.MethodArgumentNotValidException; | ||||||
|  | import org.springframework.web.bind.MissingServletRequestParameterException; | ||||||
|  | import org.springframework.web.bind.annotation.ExceptionHandler; | ||||||
|  | import org.springframework.web.bind.annotation.ResponseStatus; | ||||||
|  | import org.springframework.web.bind.annotation.RestControllerAdvice; | ||||||
|  | import org.springframework.web.servlet.NoHandlerFoundException; | ||||||
|  | 
 | ||||||
|  | import javax.validation.ConstraintViolationException; | ||||||
|  | import java.util.Map; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Exception handler of controller. | ||||||
|  |  */ | ||||||
|  | @RestControllerAdvice | ||||||
|  | public class ControllerExceptionHandler { | ||||||
|  | 
 | ||||||
|  |     private final Logger log = Logger.getLogger(getClass()); | ||||||
|  | 
 | ||||||
|  |     @ExceptionHandler(DataIntegrityViolationException.class) | ||||||
|  |     @ResponseStatus(HttpStatus.BAD_REQUEST) | ||||||
|  |     public JsonResult handleDataIntegrityViolationException(DataIntegrityViolationException e) { | ||||||
|  |         JsonResult jsonResult = handleBaseException(e); | ||||||
|  |         if (e.getCause() instanceof org.hibernate.exception.ConstraintViolationException) { | ||||||
|  |             jsonResult = handleBaseException(e.getCause()); | ||||||
|  |         } | ||||||
|  |         jsonResult.setMsg("Failed to validate request parameter"); | ||||||
|  |         return jsonResult; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @ExceptionHandler(MissingServletRequestParameterException.class) | ||||||
|  |     @ResponseStatus(HttpStatus.BAD_REQUEST) | ||||||
|  |     public JsonResult handleMissingServletRequestParameterException(MissingServletRequestParameterException e) { | ||||||
|  |         JsonResult jsonResult = handleBaseException(e); | ||||||
|  |         jsonResult.setMsg(String.format("Missing request parameter, required %s type %s parameter", e.getParameterType(), e.getParameterName())); | ||||||
|  |         return jsonResult; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @ExceptionHandler(ConstraintViolationException.class) | ||||||
|  |     @ResponseStatus(HttpStatus.BAD_REQUEST) | ||||||
|  |     public JsonResult handleConstraintViolationException(ConstraintViolationException e) { | ||||||
|  |         JsonResult jsonResult = handleBaseException(e); | ||||||
|  |         jsonResult.setCode(HttpStatus.BAD_REQUEST.value()); | ||||||
|  |         jsonResult.setMsg("Filed validation error"); | ||||||
|  |         jsonResult.setResult(e.getConstraintViolations()); | ||||||
|  |         return jsonResult; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @ExceptionHandler(MethodArgumentNotValidException.class) | ||||||
|  |     @ResponseStatus(HttpStatus.BAD_REQUEST) | ||||||
|  |     public JsonResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { | ||||||
|  |         JsonResult jsonResult = handleBaseException(e); | ||||||
|  |         jsonResult.setCode(HttpStatus.BAD_REQUEST.value()); | ||||||
|  |         jsonResult.setMsg("Filed validation error"); | ||||||
|  |         Map<String, String> errMap = ValidationUtils.mapWithFieldError(e.getBindingResult().getFieldErrors()); | ||||||
|  |         jsonResult.setResult(errMap); | ||||||
|  |         return jsonResult; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @ExceptionHandler(NoHandlerFoundException.class) | ||||||
|  |     @ResponseStatus(HttpStatus.BAD_GATEWAY) | ||||||
|  |     public JsonResult handleNoHandlerFoundException(NoHandlerFoundException e) { | ||||||
|  |         JsonResult jsonResult = handleBaseException(e); | ||||||
|  |         HttpStatus status = HttpStatus.BAD_GATEWAY; | ||||||
|  |         jsonResult.setCode(status.value()); | ||||||
|  |         jsonResult.setMsg(status.getReasonPhrase()); | ||||||
|  |         return jsonResult; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @ExceptionHandler(HaloException.class) | ||||||
|  |     public ResponseEntity<JsonResult> handleHaloException(HaloException e) { | ||||||
|  |         JsonResult jsonResult = handleBaseException(e); | ||||||
|  |         jsonResult.setCode(e.getStatus().value()); | ||||||
|  |         jsonResult.setResult(e.getErrorData()); | ||||||
|  |         return new ResponseEntity<>(jsonResult, e.getStatus()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @ExceptionHandler(Exception.class) | ||||||
|  |     @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) | ||||||
|  |     public JsonResult handleGlobalException(Exception e) { | ||||||
|  |         JsonResult jsonResult = handleBaseException(e); | ||||||
|  |         HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR; | ||||||
|  |         jsonResult.setCode(status.value()); | ||||||
|  |         jsonResult.setMsg(status.getReasonPhrase()); | ||||||
|  |         return jsonResult; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private JsonResult handleBaseException(Throwable t) { | ||||||
|  |         Assert.notNull(t, "Throwable must not be null"); | ||||||
|  | 
 | ||||||
|  |         log.error("Captured an exception", t); | ||||||
|  | 
 | ||||||
|  |         JsonResult jsonResult = new JsonResult(); | ||||||
|  |         jsonResult.setMsg(t.getMessage()); | ||||||
|  | 
 | ||||||
|  |         if (log.isDebugEnabled()) { | ||||||
|  |             jsonResult.setDevMsg(ExceptionUtils.getStackTrace(t)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return jsonResult; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -4,6 +4,7 @@ import cc.ryanc.halo.model.enums.BlogPropertiesEnum; | ||||||
| import cc.ryanc.halo.model.enums.TrueFalseEnum; | import cc.ryanc.halo.model.enums.TrueFalseEnum; | ||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
| import com.fasterxml.jackson.databind.ObjectMapper; | import com.fasterxml.jackson.databind.ObjectMapper; | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
| import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||||
| import org.springframework.web.servlet.HandlerInterceptor; | import org.springframework.web.servlet.HandlerInterceptor; | ||||||
| import org.springframework.web.servlet.ModelAndView; | import org.springframework.web.servlet.ModelAndView; | ||||||
|  | @ -28,6 +29,12 @@ public class ApiInterceptor implements HandlerInterceptor { | ||||||
| 
 | 
 | ||||||
|     private static final String TOKEN = "token"; |     private static final String TOKEN = "token"; | ||||||
| 
 | 
 | ||||||
|  |     private final ObjectMapper objectMapper; | ||||||
|  | 
 | ||||||
|  |     public ApiInterceptor(ObjectMapper objectMapper) { | ||||||
|  |         this.objectMapper = objectMapper; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     @Override |     @Override | ||||||
|     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { |     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { | ||||||
|         if (StrUtil.equals(TrueFalseEnum.TRUE.getDesc(), OPTIONS.get(BlogPropertiesEnum.API_STATUS.getProp()))) { |         if (StrUtil.equals(TrueFalseEnum.TRUE.getDesc(), OPTIONS.get(BlogPropertiesEnum.API_STATUS.getProp()))) { | ||||||
|  | @ -37,10 +44,9 @@ public class ApiInterceptor implements HandlerInterceptor { | ||||||
|                 response.setCharacterEncoding("UTF-8"); |                 response.setCharacterEncoding("UTF-8"); | ||||||
|                 response.setContentType("application/json;charset=utf-8"); |                 response.setContentType("application/json;charset=utf-8"); | ||||||
|                 Map<String, Object> map = new HashMap<>(2); |                 Map<String, Object> map = new HashMap<>(2); | ||||||
|                 ObjectMapper mapper = new ObjectMapper(); |                 map.put("code", HttpStatus.BAD_REQUEST.value()); | ||||||
|                 map.put("code", 400); |  | ||||||
|                 map.put("msg", "Invalid Token"); |                 map.put("msg", "Invalid Token"); | ||||||
|                 response.getWriter().write(mapper.writeValueAsString(map)); |                 response.getWriter().write(objectMapper.writeValueAsString(map)); | ||||||
|                 return false; |                 return false; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 johnniang
						johnniang