ServiceGlobalExceptionHandler.java
4.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package com.yoho.error.exception.handler;
import com.alibaba.fastjson.support.spring.FastJsonJsonView;
import com.yoho.error.event.ServiceServerExceptionEvent;
import com.yoho.error.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
/**
*
* 服务的全局异常处理
* spring mvc server 通用的异常处理。 2种响应:
* 1. 返回200,并且用json作为消息体,并且设置消息头(方便resttemplate处理)
* 2. 返回500,设置消息头
* Created by chunhua.zhang@yoho.cn on 2015/11/19.
*/
public class ServiceGlobalExceptionHandler implements HandlerExceptionResolver, ApplicationEventPublisherAware {
private final Logger logger = LoggerFactory.getLogger(getClass());
private ApplicationEventPublisher publisher;
private static final String SPLIT_ADD = "%%";
//如果服务异常,需要把异常信息加入到头中
public static String HEADER_ERROR_CODE = "x-yh-service-error-code";
public static String HEADER_ERROR_MESSAGE = "x-yh-service-error-message";
public static String HEADER_ERROR_ADD = "x-yh-service-error-addon";
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception exception) {
//publish event
publisher.publishEvent(new ServiceServerExceptionEvent(httpServletRequest.getRequestURI(), exception));
//如果不是服务异常,直接返回500,并且打印异常
if (!(exception instanceof ServiceException)) {
logger.error("unknown exception happened at:{}", httpServletRequest.getRequestURI());
logger.error("unknown exception is ", exception);
httpServletResponse.setStatus(500);
httpServletResponse.addHeader(HEADER_ERROR_MESSAGE, exception.getMessage());
return new ModelAndView();
}
//处理服务异常。 需要添加异常信息到头中,并且返回json
ServiceException se = (ServiceException) exception;
int code = se.getCode();
String message = se.getErrorMessage();
//add header
httpServletResponse.addHeader(HEADER_ERROR_CODE, String.valueOf(code));
httpServletResponse.addHeader(HEADER_ERROR_MESSAGE, message);
String params[] = se.getParams(); //添加其他的参数,用于重组ServiceException
if (params != null) {
try {
httpServletResponse.addHeader(HEADER_ERROR_ADD, URLEncoder.encode(String.join(SPLIT_ADD, params), "UTF-8"));
} catch (UnsupportedEncodingException e) {
logger.error("encode exception.", e);
}
}
ModelAndView mv = getErrorJsonView(code, message);
return mv;
}
public static String[] getParams(String headerValue) {
return headerValue.split(SPLIT_ADD);
}
/**
* 使用FastJson提供的FastJsonJsonView视图返回,不需要捕获异常
*/
public static ModelAndView getErrorJsonView(int code, String message) {
ModelAndView modelAndView = new ModelAndView();
FastJsonJsonView jsonView = new FastJsonJsonView();
Map<String, Object> errorInfoMap = new HashMap<>();
errorInfoMap.put("code", code);
errorInfoMap.put("message", message);
jsonView.setAttributesMap(errorInfoMap);
modelAndView.setView(jsonView);
return modelAndView;
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
}