简介
通过@ResponseResult
注解在controller方法上,定义返回的数据是否加上统一的返回数据格式。
内容
例如数据为{name:"张三",age:20}
,统一返回格式后,数据为{code:0,msg:"请求成功",data:{name:"张三",age:20}}
,在远程数据交互的时候,具有非常大的作用。
定义注解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 统一结果处理类
*
* @author lralin
* @date 2019年11月26日 17:57:05
*/
(RetentionPolicy.RUNTIME)
({ElementType.TYPE, ElementType.METHOD})
public ResponseResult {
}定义统一的返回结果类
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
import java.io.Serializable;
/**
* 返回结果
*
* @author lralin
* @create 2019年11月26日 17:03
**/
public class SharkResult<T> implements Serializable {
private int code;
private String msg;
private T data;
public SharkResult() {
}
public SharkResult(SharkCode sharkCode, T data) {
this.code = sharkCode.code();
this.msg = sharkCode.msg();
this.data = data;
}
private SharkResult(int code, String msg) {
this.code = code;
this.msg = msg;
}
public void setSharkCode(SharkCode sharkCode) {
this.code = sharkCode.code();
this.msg = sharkCode.msg();
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
//返回成功
public static SharkResult success() {
SharkResult sharkResult = new SharkResult();
sharkResult.setSharkCode(SharkCode.SUCCESS);
return sharkResult;
}
// public static SharkResult success(Object data) {
// SharkResult sharkResult = new SharkResult();
// sharkResult.setSharkCode(SharkCode.SUCCESS);
// sharkResult.setData(data);
// return sharkResult;
// }
//返回成功
public static <K> SharkResult<K> success(K data) {
SharkResult<K> sharkResult = new SharkResult<>();
sharkResult.setSharkCode(SharkCode.SUCCESS);
sharkResult.setData(data);
return sharkResult;
}
//返回失败
public static SharkResult failure() {
SharkResult sharkResult = new SharkResult();
sharkResult.setSharkCode(SharkCode.FAILURE);
return sharkResult;
}
//返回失败
public static SharkResult failure(SharkCode sharkCode) {
SharkResult sharkResult = new SharkResult();
sharkResult.setSharkCode(sharkCode);
return sharkResult;
}
//返回失败
public static SharkResult failure(String msg) {
return new SharkResult(SharkCode.WARN.code(), msg);
}
}定义统一的结果码类
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/**
* 返回结果 状态
*
* @author lralin
* @create 2019年11月26日 17:03
**/
public enum SharkCode {
SUCCESS(0, "成功"),
WARN(1001, "其他错误"),
FAILURE(9999, "失败");
private int code;
private String msg;
SharkCode(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int code() {
return this.code;
}
public String msg() {
return this.msg;
}
}定义拦截器
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
45import com.xgdfin.common.annotation.ResponseResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
/**
* 统一包装返回结果
*
* @author lralin
* @create 2019年11月26日 17:26
**/
0) (
public class ResponseResultInterceptor implements HandlerInterceptor {
private static Logger log = LoggerFactory.getLogger(ResponseResultInterceptor.class);
public static final String RESPONSE_RESULT_ANN = "RESPONSE-RESULT-ANN";
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//请求方法
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Class<?> clazz = handlerMethod.getBeanType();
Method method = handlerMethod.getMethod();
//判断是否在类上面加了注解
if (clazz.isAnnotationPresent(ResponseResult.class)) {
//设置此请求返回体,需要包装,往下传递,在ResponseBodyAdvice接口进行判断
request.setAttribute(RESPONSE_RESULT_ANN, clazz.getAnnotation(ResponseResult.class));
//判断是否在方法体上面加了注解
} else if (method.isAnnotationPresent(ResponseResult.class)) {
//设置此请求返回体,需要包装,往下传递,在ResponseBodyAdvice接口进行判断
request.setAttribute(RESPONSE_RESULT_ANN, method.getAnnotation(ResponseResult.class));
}
}
return true;
}
}controller类中,方法上添加@ResponseResult注解
1
2
3
4
5
6
7"product") (
public CreditRes insuranceProduct(CreditReq info) {
CreditRes result = getCreditRes(info);
return result;
}统一的异常处理和结果处理
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/**
* 异常处理
*
* @author lralin
*/
public class ExceptionController implements ResponseBodyAdvice<Object> {
private final static Logger logger = LoggerFactory.getLogger(ExceptionController.class);
public static final String RESPONSE_RESULT_ANN = "RESPONSE-RESULT-ANN";
(BusinessExp.class)
public SharkResult businessExp(BusinessExp exp) {
logger.error(exp.getMessage(), exp);
if (ServletUtils.isAjaxRequest(request)) {
return SharkResult.failure(exp.getMessage());
} else {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("errorMessage", exp.getMessage());
modelAndView.setViewName("error/business");
return modelAndView;
}
}
(Exception.class)
public SharkResult ajaxException(Exception e) {
logger.error("操作异常",e);
return SharkResult.failure("操作失败,请稍后重试");
}
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
ResponseResult responseResultAnn = (ResponseResult) request.getAttribute(RESPONSE_RESULT_ANN);
return responseResultAnn == null ? false : true;
}
public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
if (body instanceof SharkResult || !(MediaType.APPLICATION_JSON.equals(mediaType) || MediaType.APPLICATION_JSON_UTF8.equals(mediaType))) {
return body;
}
if (body == null) {
return SharkResult.failure("请求失败,数据为空");
}
return SharkResult.success(body);
}
}判断是否为ajax请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public static boolean isAjaxRequest(HttpServletRequest request) {
String accept = request.getHeader("accept");
if (accept != null && accept.indexOf("application/json") != -1) {
return true;
}
String xRequestedWith = request.getHeader("X-Requested-With");
if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1) {
return true;
}
String uri = request.getRequestURI();
if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")) {
return true;
}
String ajax = request.getParameter("__ajax");
if (StringUtils.inStringIgnoreCase(ajax, "json", "xml")) {
return true;
}
return false;
}前台ajax封装,统一处理返回结果
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121;(function ($) {
$.extend($, {
customAjax: function (options) {
var defaults = {
type: "POST",
dataType: "json", //返回结果的数据类型
async: true, //是否异步
cache: false, //是否缓存
// timeout: 1000 * 60 * 6,
data: {},
//是否处理返回信息
isHandleSuccess: true,
success: function (data) {
}
};
var opts = $.extend(defaults, options);
// if (opts.type.toUpperCase() == "POST") {
// var params = opts.data;
// //判断是否为 FormData数据格式。如果是,就把不是文件类型的数据拿出来进行加密传输。
// if (params instanceof FormData) {
// var dataTemp = {};
// // var i = params.entries();
// // while(i.next()){
// //
// // }
// for (const [key, value] of params.entries()) {
// if (!(value instanceof File)) {
// dataTemp[key] = value;
// }
// }
// $.each(dataTemp, function (n, v) {
// params.delete(n);
// });
// var rsaData = $.devilencrypt(JSON.stringify(dataTemp));
// opts.data.append("securekey", rsaData.encryptedrsa);
// opts.data.append("securevalue", rsaData.encrypted);
// } else {
// var rsaData = $.devilencrypt(JSON.stringify(params));
// opts.data = {
// securevalue: rsaData.encrypted,
// securekey: rsaData.encryptedrsa
// };
// }
// }
//
// if (opts.type.toUpperCase() == "GET") {
// var params = $.urlArgs(opts.url);
// var rsaData = $.devilencrypt(JSON.stringify(params));
// var indexT = opts.url.indexOf('?');
// var newUrl = opts.url.substring(0, indexT);
// opts.url = newUrl + '?securevalue=' + encodeURIComponent(rsaData.encrypted) + '&securekey=' + encodeURIComponent(rsaData.encryptedrsa);
// }
var _beforeSend = opts.beforeSend;
opts.beforeSend = function (request) {
if (_beforeSend) {
_beforeSend(httpRequest, status);
}
};
var _complete = opts.complete;
opts.complete = function (httpRequest, status) {
if (_complete) {
_complete(httpRequest, status);
}
};
//统一处理异常
var _error = opts.error;
opts.error = function (event, request, settings) {
$.alertWarning('网络异常');
// if (_error) {
// _error(event, request, settings);
// }
};
var _success = opts.success;
opts.success = function (data, textStatus, httpRequest) {
if (httpRequest.getResponseHeader("SessionStatus") == "sessionTimeOut") {
var loginUrl = httpRequest.getResponseHeader("loginUrl") || '';
$.confirm('会话失效,是否重新登录', function () {
// $.alert('You clicked Ok button');
window.location.href = loginUrl;
});
return;
}
if (_success) {
//统一处理错误码
if (data != null && data.hasOwnProperty("code") && opts.isHandleSuccess) {
if (data.code != 0) {
$.alertWarning(data.code == 1001 ? data.msg : "请求失败", 1000);
return;
}
_success(data.data, textStatus, httpRequest);
} else {
_success(data, textStatus, httpRequest);
}
}
};
// ajaxAsync
$.ajax(opts);
},
//处理URL
urlArgs: function (url) {
var args = {};
var index = url.indexOf('?');
var query = url.substring(index + 1);
var pairs = query.split('&');
for (var i = 0; i < pairs.length; i++) {
var pos = pairs[i].indexOf('=');
if (pos == -1) {
continue;
} // 如果没找到,就跳过
var name = pairs[i].substr(0, pos); // 获得名称
var value = pairs[i].substr(pos + 1); // 提取value
value = decodeURI(value);
args[name] = value;
}
return args
},
});
})(jQuery);
总结
通过统一处理前后台异常数据格式后,在写前端代码的时候,就可以只需考虑成功之后的业务逻辑。而后台的一些校验,可以直接抛出BusinessExp异常。从而大大的增加了写代码的效率和产出。