Complete ControllerExceptionHandler

pull/98/head
johnniang 2019-02-20 23:44:25 +08:00
parent ee41a620f0
commit a08fac24a6
4 changed files with 170 additions and 3 deletions

View File

@ -23,11 +23,19 @@ public class JsonResult {
*/
private String msg;
/**
* Dev message.(only setting in dev environment)
*/
private String devMsg;
/**
*
*/
private Object result;
public JsonResult() {
}
/**
*
*
@ -71,4 +79,11 @@ public class JsonResult {
this.code = code;
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;
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -4,6 +4,7 @@ import cc.ryanc.halo.model.enums.BlogPropertiesEnum;
import cc.ryanc.halo.model.enums.TrueFalseEnum;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@ -28,6 +29,12 @@ public class ApiInterceptor implements HandlerInterceptor {
private static final String TOKEN = "token";
private final ObjectMapper objectMapper;
public ApiInterceptor(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
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.setContentType("application/json;charset=utf-8");
Map<String, Object> map = new HashMap<>(2);
ObjectMapper mapper = new ObjectMapper();
map.put("code", 400);
map.put("code", HttpStatus.BAD_REQUEST.value());
map.put("msg", "Invalid Token");
response.getWriter().write(mapper.writeValueAsString(map));
response.getWriter().write(objectMapper.writeValueAsString(map));
return false;
}
}