通知返回实体
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.apache.http.HttpStatus;
import java.io.Serializable;
/**
* @author 王守钰
* @version 1.0
* @program boqin
* @date 2019年12月11日
* @description: 返回值
*/
@Data
@ToString
@EqualsAndHashCode
public class R<T> implements Serializable {
/**
* 状态码
*/
private Integer code;
/**
* 返回消息
*/
private String msg;
/**
* 返回数据
*/
private T data;
public R(Integer code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public R(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public R(Integer code) {
this.code = code;
}
/**
* 操作成功
* @return
*/
public static R success(){
return new R(HttpStatus.SC_OK);
}
/**
* 操作成功
* @param t
* @param <T>
* @return
*/
public static <T> R success(T t){
return new R(HttpStatus.SC_OK, null, t);
}
/**
* 操作失败
* @return
*/
public static R fail() {
return new R(HttpStatus.SC_INTERNAL_SERVER_ERROR);
}
/**
* 失败
* @param msg
* @return
*/
public static R fail(String msg){
return new R(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
}
}
定义注解
import java.lang.annotation.*;
/**
* @author 王守钰
* @version 1.0
* @program boqin
* @date 2020年01月30日
* @description: 返回R类型
*/
@Documented
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE, ElementType.METHOD})
public @interface ResponseR {
}
定义常量
主要为了在mvc请求时候判断这个请求的返回结果,设置Attribute使用
/**
* @author 王守钰
* @version 1.0
* @program boqin
* @date 2020年01月30日
* @description: MVC返回值常量
*/
public class MvcConstant {
/**
* 返回R类型Attribute
*/
public static final String RESPONSE_R_ANN = "RESPONSE-R-ANN";
}
Mvc拦截器设置
这里面可以自己根据头部,或者parameter参数,或者注解等方式来进行判断是否要统一包装成想要的结果集。
import com.google.common.base.Strings;
import org.springframework.beans.factory.annotation.Autowired;
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 王守钰
* @version 1.0
* @program boqin
* @date 2020年01月30日
* @description: 返回R类型拦截器
*/
@Component
public class ResponseResultInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if(handler instanceof HandlerMethod){
// 参数匹配
String parameter = request.getParameter("Result-Format");
if(!Strings.isNullOrEmpty(parameter) && parameter.equalsIgnoreCase("R")){
request.setAttribute(MvcConstant.RESPONSE_R_ANN,ResponseR.class);
return true;
}
// 注解匹配
HandlerMethod handlerMethod = (HandlerMethod) handler;
Class<?> clazz = handlerMethod.getBeanType();
Method method = handlerMethod.getMethod();
// 判断类上是否有ResponseR注解
if(clazz.isAnnotationPresent(ResponseR.class) || method.isAnnotationPresent(ResponseR.class)){
request.setAttribute(MvcConstant.RESPONSE_R_ANN,ResponseR.class);
}
}
return true;
}
}
ResponseBodyAdvice处理器
这里面做了个R类型的返回值的判断,如果原返回值已经被R包装了,就不需要再进行包装了。
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.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import javax.servlet.http.HttpServletRequest;
/**
* @author 王守钰
* @version 1.0
* @program boqin
* @date 2020年01月30日
* @description: 返回R类型处理器
*/
@ControllerAdvice
public class ResponseResultHandler implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = servletRequestAttributes.getRequest();
return request.getAttribute(MvcConstant.RESPONSE_R_ANN) != null ;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
if(body instanceof R){
return body;
}
return R.success(body);
}
}
Mvc拦截器激活
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
/**
* @author 王守钰
* @version 1.0
* @program boqin
* @date 2020年01月30日
* @description: mvc配置
*/
@Configuration
public class MvcConfig extends WebMvcConfigurationSupport {
@Autowired
private ResponseResultInterceptor responseResultInterceptor;
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(responseResultInterceptor).addPathPatterns("/**");
super.addInterceptors(registry);
}
}