先整体说一下思路:
当程序中:我们抛出自定异常,如
throw new BaseException(10002006);
那么BaseException类中利用方法,
public BaseException(int code) {
this(code, ResBundle.getMessage(String.valueOf(code)));
}
将配置文件中的错误信息存到改异常中,然后由继承HandlerExceptionResolver的ExceptionResolver拦截,向用户展示友好界面。
备注:之后又接触了一个更加简单处理Controller层异常的方法,利用@ControllerAdvice与@ExceptionHandler注解处理。
@ControllerAdvice
public class MyExceptionHandler {
@ResponseBody
@ExceptionHandler(value=Exception.class)
public Map errorHandler(Exception ex){
Map map=new HashMap();
map.put("code", -1);
map.put("msg", ex.getMessage());
return map;
}
}
新建异常处理类,要继承HandlerExceptionResolver。
@Component
public class ExceptionResolver implements HandlerExceptionResolver {
private final Logger logger = LoggerFactory.getLogger(ExceptionResolver.class);
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception e) {
String errorMessage = null;
if (e instanceof BaseException) {
errorMessage = e.getMessage();
} else if (e instanceof UnauthorizedException) {
errorMessage = "没有权限";
} else if (e instanceof MaxUploadSizeExceededException) {
errorMessage = "文件太大啦!
请选择更小一些的文件重试!";
} else if (e instanceof RuntimeException && e.getCause() instanceof BaseException) {
errorMessage = e.getCause().getMessage();
} else {
logger.error(e.getMessage(), e);
errorMessage = "未知错误,请联系管理员!";
}
Map result = new HashMap();
result.put("status", false);
result.put("msg", (Strings.isBlank(errorMessage) ? "未知错误,请联系管理员!" : errorMessage));
if (HttpUtils.isAjaxRequest(request)) {
return new ModelAndView(new FastJsonJsonView(), result);
}
if (handler instanceof HandlerMethod) {
if (HttpUtils.isJsonResponse(request, (HandlerMethod) handler)) {
return new ModelAndView(new FastJsonJsonView(), result);
}
}
// 页面指定状态为500,便于上层的resion或者nginx的500页面跳转,由于error/error不适合对用户展示
// response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return new ModelAndView("error/500", result);
}
}
其中的BaseException类是项目中所以自定义异常都要继承的。
/**
*
* 异常基类,所有异常都必须继承于此异常 .
*/
public class BaseException extends RuntimeException {
private static final long serialVersionUID = -5875371379845226068L;
/**
* 具体异常码
*/
protected int code;
protected BaseException() {
super();
}
public int getCode() {
return code;
}
/**
* 实例化异常
*
* @param msgFormat
* @param args
* @return
*/
protected BaseException newInstance(String msgFormat, Object... args) {
return new BaseException(this.code, msgFormat, args);
}
public BaseException(int code) {
this(code, ResBundle.getMessage(String.valueOf(code)));
}
public BaseException(int code, Object... args) {
this(code, ResBundle.getMessage(String.valueOf(code)), args);
}
protected BaseException(int code, String msgFormat, Object... args) {
super(String.format(msgFormat, args));
this.code = code;
}
protected BaseException(String message, Throwable cause) {
super(message, cause);
}
public BaseException(Throwable cause) {
super(cause);
}
protected BaseException(String message) {
super(message);
}
}
当我们抛出自定义异常时,我们利用自定义的ResBundle(其中封装了ResourceBundle的一些信息),
ResourceBundle是去读取配置文件的。
public class ResBundle {
private static Log log = LogFactory.getLog(ResBundle.class);
private static Map resMap = new HashMap();
private static final ResourceBundle NULL_BUNDLE = new ResourceBundle() {
public Enumeration getKeys() {
return null;
}
protected Object handleGetObject(String key) {
return null;
}
public String toString() {
return "NULL_BUNDLE";
}
};
private static ResourceBundle getBundle(String resourceName) {
ResourceBundle rb = resMap.get(resourceName);
if (rb == null) {
try {
rb = ResourceBundle.getBundle(resourceName, Locale.getDefault());
if (rb == null) {
rb = NULL_BUNDLE;
}
resMap.put(resourceName, rb);
} catch (Throwable mre) {
log.error("No resource property file in the classpath or in the res folder.", mre);
}
}
return rb;
}
public static String getString(String key) {
return getResString("resource", key, null);
}
public static String getMessage(String key) {
return getResString("resource", key, null);
}
public static String getString(String key, String defaultValue) {
return getResString("resource", key, defaultValue);
}
public static String getMessage(String key, String defaultValue) {
return getResString("resource", key, defaultValue);
}
public static String getResString(String resourceName, String key) {
return getResString(resourceName, key, null);
}
public static String getResString(String resourceName, String key, String defaultValue) {
String value = getBundle(resourceName).getString(key).trim();
return Strings.isBlank(value) ? defaultValue : value;
}
}
配置错误信息如图。