场景:
在项目中我们有统一的返回结果定义。我们自己定义内容
{
"code": 200,
"message": "success",
"data": {
"id": 507361327216709,
"pid": 507361220950085,
"title": "流程",
"parentTitle": null,
"sort": 2,
"createBy": 278787367246725,
"createTime": "2024-01-23 17:58:34",
"updateBy": 386208547649353,
"updateTime": "2024-01-26 17:33:31"
},
"timestamp": 1708396596121
}
这个在我们自己项目都是这种返回结构,但是在对接其他公司的系统的时候,有的公司规定的返回结果结构跟我们的不一样。他们的是这样的
{
"result": {
"access_token": "d527138ca51",
"expire_at": "20240220224436"
},
"success": true,
"message": null,
"desc": null
}
这和我们项目中的是不一样的。字段名和含义都不一样。需要在不改变我们项目结构的同时满足这种返回结果。我们在controller层可以自己定义一个返回结果对象,但是项目中抛出异常,就会走我们定义的第一种响应结构
解决方案:
1. 使用aop,或者过滤器WEBfilter. 这种处理方式,还不能解决这个问题。controller一旦抛出异常,就不会走这2个类了。会走到异常处理类。返回的就是我们项目定义的响应结构了。
2. 使用ResponseBodyAdvice解决
这种方案是,在响应之后,可以处理响应内容,具体代码如下:
package com.openapi.filter;
import com.common.response.YGGCBaseResponseVO;
import com.common.response.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import javax.servlet.http.HttpServletRequest;
import static org.springframework.web.util.WebUtils.ERROR_REQUEST_URI_ATTRIBUTE;
/**
* 返回值处理
*
* @author
* @since 2024/1/26 15:04
*/
//@Order(Ordered.HIGHEST_PRECEDENCE)
@Slf4j
@RestControllerAdvice
public class ResponseBodyHandler implements ResponseBodyAdvice<Object> {
private static final String PREFIX_YGGC = "/yggc";
@SuppressWarnings("all")
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@SuppressWarnings("all")
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
// 获取HttpServletRequest
HttpServletRequest sr = ((ServletServerHttpRequest) request).getServletRequest();
// 获取异常路径
String errorUri = (String) sr.getAttribute(ERROR_REQUEST_URI_ATTRIBUTE);
// 获取请求uri
String uri = sr.getRequestURI();
// 把R转成YGGCBaseResponseVO
if (StringUtils.isNotBlank(uri) && body instanceof R
&& (uri.startsWith(PREFIX_YGGC) || (StringUtils.isNotBlank(errorUri) && errorUri.startsWith(PREFIX_YGGC)))) {
if (body instanceof YGGCBaseResponseVO) {
return body;
}
R r = (R) body;
return new YGGCBaseResponseVO<>(r.getData(), 200 == r.getCode(), r.getMessage());
}
return body;
}
}