package org.hsweb.web.controller;
import org.hsweb.commons.ClassUtils;
import org.hsweb.ezorm.rdb.exception.ValidationException;
import org.hsweb.web.core.exception.BusinessException;
import org.hsweb.web.core.exception.ExceptionHandler;
import org.hsweb.web.core.message.ResponseMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.DefaultErrorAttributes;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
/**
* Created by zhouhao on 16-4-26.
*/
@Configuration
public class ExceptionHandlerConfiguration {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private List<ExceptionHandler> exceptionHandlers;
@Bean
public DefaultErrorAttributes errorAttributes() {
return new DefaultErrorAttributes() {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
super.resolveException(request, response, handler, ex);
ResponseMessage responseMessage = null;
//获取自定义的异常处理器
for (ExceptionHandler exceptionHandler : exceptionHandlers) {
if (exceptionHandler.support(ex.getClass())) {
responseMessage = exceptionHandler.handle(ex);
break;
}
}
if (responseMessage == null) {
responseMessage = ResponseMessage.error(ex.getMessage());
}
request.setAttribute("error.attributes", responseMessage.toMap());
// try {
request.setAttribute("javax.servlet.error.status_code", responseMessage.getCode());
// response.sendError(responseMessage.getCode());
// } catch (IOException e) {
// logger.error("", e);
// }
return null;
}
@Override
public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes,
boolean includeStackTrace) {
Map<String, Object> attrs = ((Map) requestAttributes.getAttribute("error.attributes", RequestAttributes.SCOPE_REQUEST));
//错误属性为空,说明可能不是由controller抛出的一次信息
if (attrs == null) {
Integer status = (Integer) this.getAttribute(requestAttributes, "javax.servlet.error.status_code");
Object message = this.getAttribute(requestAttributes, "javax.servlet.error.message");
Throwable throwable = getError(requestAttributes);
if (throwable != null) logger.error("", throwable);
if (message == null)
message = "None";
return ResponseMessage.error(String.valueOf(message), status).toMap();
}
return attrs;
}
public Object getAttribute(RequestAttributes requestAttributes, String name) {
return requestAttributes.getAttribute(name, 0);
}
};
}
@Bean
@Order(1000)
public ExceptionHandler defaultExceptionHandler() {
ExceptionHandler handler = new ExceptionHandler() {
@Override
public <T extends Throwable> boolean support(Class<T> e) {
return true;
}
@Override
public ResponseMessage handle(Throwable e) {
logger.error("", e);
return ResponseMessage.error(e.getMessage());
}
};
return handler;
}
@Bean
@Order(600)
public ExceptionHandler validationExceptionHandler() {
ExceptionHandler handler = new ExceptionHandler() {
@Override
public <T extends Throwable> boolean support(Class<T> e) {
return ClassUtils.instanceOf(e, ValidationException.class);
}
@Override
public ResponseMessage handle(Throwable e) {
return ResponseMessage.error(String.valueOf(((ValidationException) e).getValidateResult()), 400);
}
};
return handler;
}
@Bean
@Order(900)
public ExceptionHandler businessExceptionHandler() {
ExceptionHandler handler = new ExceptionHandler() {
@Override
public <T extends Throwable> boolean support(Class<T> e) {
return ClassUtils.instanceOf(e, BusinessException.class);
}
@Override
public ResponseMessage handle(Throwable e) {
return ResponseMessage.error(e.getMessage(), ((BusinessException) e).getStatus());
}
};
return handler;
}
}