2017-12-19 14:55:52 +08:00
|
|
|
package com.nis.restful;
|
|
|
|
|
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.LinkedHashMap;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
|
|
import org.springframework.beans.TypeMismatchException;
|
|
|
|
|
import org.springframework.beans.factory.InitializingBean;
|
|
|
|
|
import org.springframework.http.HttpStatus;
|
|
|
|
|
import org.springframework.http.converter.HttpMessageNotReadableException;
|
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
|
|
|
|
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
|
|
|
|
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
|
|
|
|
import org.springframework.web.bind.MissingServletRequestParameterException;
|
|
|
|
|
import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException;
|
|
|
|
|
@Component
|
|
|
|
|
public class DefaultRestErrorResolver implements RestErrorResolver,InitializingBean{
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 预先定义的所有异常类型
|
|
|
|
|
*/
|
|
|
|
|
private Map<String, String> exceptionMappings = Collections.emptyMap();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 配置文件中自定义扩展错误
|
|
|
|
|
*/
|
|
|
|
|
private Map<String, String> exceptionMappingDefinitions = Collections.emptyMap();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public RestResult resolveError(HttpServletRequest request, Object handler,
|
|
|
|
|
Exception ex) {
|
|
|
|
|
RestResult error = this.buildError(ex, request);
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private RestResult buildError(Exception ex, HttpServletRequest request) {
|
|
|
|
|
RestResult error = new RestResult();
|
|
|
|
|
error.setStatus(this.getHttpStatusByEx(ex));// 设置http状态
|
|
|
|
|
//获取日志源[只有日志需要返回日志源和ActiveSys]
|
|
|
|
|
String logSource = ((RestServiceException) ex).getLogSource();
|
|
|
|
|
String activeSys = ((RestServiceException) ex).getActiveSys();
|
|
|
|
|
if(logSource != null ){
|
|
|
|
|
error.setLogSource(logSource);
|
|
|
|
|
}
|
|
|
|
|
if(activeSys != null ){
|
|
|
|
|
error.setActiveSys(activeSys);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//RestServiceException 包含有错误code
|
|
|
|
|
if(ex instanceof RestServiceException){
|
|
|
|
|
int errorCode = ((RestServiceException) ex).getErrorCode();
|
|
|
|
|
error.setBusinessCode(RestBusinessCode.valueOf(errorCode));
|
|
|
|
|
} else {
|
|
|
|
|
error.setBusinessCode(RestBusinessCode.valueOf(998));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
error.setMsg(ex.getMessage());
|
|
|
|
|
if(null != request){
|
|
|
|
|
error.setFromUri(request.getRequestURI());
|
|
|
|
|
}else {
|
|
|
|
|
error.setFromUri("unknow url");
|
|
|
|
|
}
|
2018-05-19 11:30:50 +08:00
|
|
|
error.setTraceCode(((RestServiceException) ex).getTraceCode());
|
2017-12-19 14:55:52 +08:00
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private HttpStatus getHttpStatusByEx(Exception ex){
|
|
|
|
|
if(this.exceptionMappingDefinitions.containsKey(ex.getClass().getName())){
|
|
|
|
|
return HttpStatus.valueOf(Integer.parseInt(this.exceptionMappingDefinitions.get(ex.getClass()
|
|
|
|
|
.getName())));
|
|
|
|
|
}
|
|
|
|
|
else return HttpStatus.INTERNAL_SERVER_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void afterPropertiesSet() throws Exception {
|
|
|
|
|
//初始化所有预先定义的错误
|
|
|
|
|
this.exceptionMappings = createDefaultExceptionMappingDefinitions();
|
|
|
|
|
//如果存在自定义的错误,添加到预定义错误中
|
|
|
|
|
if (this.exceptionMappingDefinitions != null && !this.exceptionMappingDefinitions.isEmpty()) {
|
|
|
|
|
this.exceptionMappings.putAll(this.exceptionMappingDefinitions);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 将spring中的http状态和异常互相对应 参考 spring的defaultExceptionHandler实现类似
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
private final Map<String, String> createDefaultExceptionMappingDefinitions() {
|
|
|
|
|
|
|
|
|
|
Map<String, String> m = new LinkedHashMap<String, String>();
|
|
|
|
|
|
|
|
|
|
// 400
|
|
|
|
|
applyDef(m, HttpMessageNotReadableException.class,
|
|
|
|
|
HttpStatus.BAD_REQUEST);
|
|
|
|
|
applyDef(m, MissingServletRequestParameterException.class,
|
|
|
|
|
HttpStatus.BAD_REQUEST);
|
|
|
|
|
applyDef(m, TypeMismatchException.class, HttpStatus.BAD_REQUEST);
|
|
|
|
|
applyDef(m, "javax.validation.ValidationException",
|
|
|
|
|
HttpStatus.BAD_REQUEST);
|
|
|
|
|
|
|
|
|
|
// 404
|
|
|
|
|
applyDef(m, NoSuchRequestHandlingMethodException.class,
|
|
|
|
|
HttpStatus.NOT_FOUND);
|
|
|
|
|
applyDef(m, "org.hibernate.ObjectNotFoundException",
|
|
|
|
|
HttpStatus.NOT_FOUND);
|
|
|
|
|
|
|
|
|
|
// 405
|
|
|
|
|
applyDef(m, HttpRequestMethodNotSupportedException.class,
|
|
|
|
|
HttpStatus.METHOD_NOT_ALLOWED);
|
|
|
|
|
|
|
|
|
|
// 406
|
|
|
|
|
applyDef(m, HttpMediaTypeNotAcceptableException.class,
|
|
|
|
|
HttpStatus.NOT_ACCEPTABLE);
|
|
|
|
|
|
|
|
|
|
// 409
|
|
|
|
|
applyDef(m, "org.springframework.dao.DataIntegrityViolationException",
|
|
|
|
|
HttpStatus.CONFLICT);
|
|
|
|
|
|
|
|
|
|
// 415
|
|
|
|
|
applyDef(m, HttpMediaTypeNotSupportedException.class,
|
|
|
|
|
HttpStatus.UNSUPPORTED_MEDIA_TYPE);
|
|
|
|
|
return m;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void applyDef(Map<String, String> m, Class clazz, HttpStatus status) {
|
|
|
|
|
applyDef(m, clazz.getName(), status);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void applyDef(Map<String, String> m, String key, HttpStatus status) {
|
|
|
|
|
m.put(key, status.value() + "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Map<String, String> getExceptionMappings() {
|
|
|
|
|
return exceptionMappings;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setExceptionMappings(Map<String, String> exceptionMappings) {
|
|
|
|
|
this.exceptionMappings = exceptionMappings;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Map<String, String> getExceptionMappingDefinitions() {
|
|
|
|
|
return exceptionMappingDefinitions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setExceptionMappingDefinitions(
|
|
|
|
|
Map<String, String> exceptionMappingDefinitions) {
|
|
|
|
|
this.exceptionMappingDefinitions = exceptionMappingDefinitions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|