package com.api.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ResponseResult {
}
拦截器用来拦截请求,并根据该URI是否添加@ResponseResult
来设置该RUI是否需要对返回数据进行封装
package com.api.interceptor;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.api.annotation.ResponseResult;
import com.api.cache.ResponseURICache;
@Component
public class ResponsResultInterceptor implements HandlerInterceptor {
@Override
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();
String rui = request.getRequestURI();
if(null == ResponseURICache.getInstance().get(rui)) {
if(clazz.isAnnotationPresent(ResponseResult.class)){
ResponseURICache.getInstance().set(rui, true);
}else if(method.isAnnotationPresent(ResponseResult.class)){
ResponseURICache.getInstance().set(rui, true);
}else{
ResponseURICache.getInstance().set(rui, false);
}
}
}
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception)
throws Exception {
// TODO Auto-generated method stub
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView view)
throws Exception {
// TODO Auto-generated method stub
}
}
package com.api.config;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.api.interceptor.ResponsResultInterceptor;
@Configuration
public class WebConfigurer implements WebMvcConfigurer {
@Autowired
private ResponsResultInterceptor responsResultInterceptor;
@Override
public void addInterceptors(InterceptorRegistry interceptorRegistry) {
// addPathPatterns("/**") 表示拦截所有的请求,
// excludePathPatterns("/login", "/register") 表示除了登陆与注册之外,因为登陆注册不需要登陆也可以访问
interceptorRegistry.addInterceptor(responsResultInterceptor).addPathPatterns("/**");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry resourceHandlerRegistry) {
// TODO Auto-generated method stub
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> arg0) {
// TODO Auto-generated method stub
}
@Override
public void addCorsMappings(CorsRegistry arg0) {
// TODO Auto-generated method stub
}
@Override
public void addFormatters(FormatterRegistry arg0) {
// TODO Auto-generated method stub
}
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> arg0) {
// TODO Auto-generated method stub
}
@Override
public void addViewControllers(ViewControllerRegistry arg0) {
// TODO Auto-generated method stub
}
@Override
public void configureAsyncSupport(AsyncSupportConfigurer arg0) {
// TODO Auto-generated method stub
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer arg0) {
// TODO Auto-generated method stub
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer arg0) {
// TODO Auto-generated method stub
}
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> arg0) {
// TODO Auto-generated method stub
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> arg0) {
// TODO Auto-generated method stub
}
@Override
public void configurePathMatch(PathMatchConfigurer arg0) {
// TODO Auto-generated method stub
}
@Override
public void configureViewResolvers(ViewResolverRegistry arg0) {
// TODO Auto-generated method stub
}
@Override
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> arg0) {
// TODO Auto-generated method stub
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> arg0) {
// TODO Auto-generated method stub
}
@Override
public MessageCodesResolver getMessageCodesResolver() {
// TODO Auto-generated method stub
return null;
}
@Override
public Validator getValidator() {
// TODO Auto-generated method stub
return null;
}
}
package com.api.result;
public enum ResultCode {
//成功
SUCCESS(1,"成功"),
//参数错误100-199
PARAM_IS_INVALID(101,"参数无效"),
PARAM_IS_BLANK(102,"参数为空"),
PARAM_TYPE_BIND_ERROR(103,"参数类型错误"),
PARAM_NOT_COMPLETE(104,"参数缺失"),
//用户错误200-299
USER_NOT_LOGGED_IN(201,"用户未登录,访问的路径需要验证,请登录"),
USER_LOGIN_ERROR(202,"账号不存在或密码错误"),
USER_ACCOUNT_FORBIDDEN(203,"账号已被禁用"),
USER_NOT_EXIST(204,"用户不存在"),
USER_HAS_EXISTED(205,"用户已存在");
private Integer code;
private String message;
ResultCode(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer code() {
return this.code;
}
public String message() {
return this.message;
}
}
package com.api.result;
import java.io.Serializable;
public class Result implements Serializable {
private static final long serialVersionUID = 1L;
private Integer code;
private String message;
private Object data;
public Result() {
}
public Result(ResultCode resultCode, Object data) {
this.code = resultCode.code();
this.message = resultCode.message();
this.data = data;
}
public static Result success(){
Result result = new Result();
result.setResultCode(ResultCode.SUCCESS);
return result;
}
private void setResultCode(ResultCode resultCode) {
this.code = resultCode.code();
this.message = resultCode.message();
}
public static Result success(Object data){
Result result = new Result();
result.setResultCode(ResultCode.SUCCESS);
result.setData(data);
return result;
}
public static Result failure(ResultCode resultCode){
Result result = new Result();
result.setResultCode(resultCode);
return result;
}
public static Result failure(ResultCode resultCode, Object data){
Result result = new Result();
result.setResultCode(resultCode);
result.setData(data);
return result;
}
public static Result failure(Integer code, String message, Object errors) {
Result result = new Result();
result.setCode(code);
result.setMessage(message);
result.setData(errors);
return result;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
package com.api.result;
public class ErrorResult {
private Integer code;
private String message;
private Object errors;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getErrors() {
return errors;
}
public void setErrors(Object errors) {
this.errors = errors;
}
}
package com.api.handler;
import javax.servlet.http.HttpServletRequest;
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.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import com.api.cache.ResponseURICache;
import com.api.result.ErrorResult;
import com.api.result.Result;
@ControllerAdvice
public class ResponseResultHandle implements ResponseBodyAdvice<Object> {
//是否请求包含了包装注解标记,没有就直接返回,不需要重写返回体
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = sra.getRequest();
//判断请求是否有包装标记
return ResponseURICache.getInstance().get(request.getRequestURI());
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
//进入返回体重写格式
if(body instanceof ErrorResult){
//返回值异常,作包装处理
ErrorResult errorResult = (ErrorResult) body;
return Result.failure(errorResult.getCode(), errorResult.getMessage(), errorResult.getErrors());
}
return Result.success(body);
}
@ExceptionHandler(Exception.class)
@ResponseBody
public ErrorResult handleRuntimeException(Exception e){
ErrorResult errorResult = new ErrorResult();
errorResult.setCode(500);
errorResult.setMessage("服务器异常");
errorResult.setErrors(errorResult.getErrors());
return errorResult;
}
}
可以根据具体需求使用缓存数据库代替缓存类,这里使用一个用hashMap实现缓存类
package com.api.cache;
import java.util.HashMap;
import java.util.Map;
public class ResponseURICache {
//缓存map
private Map<String, Boolean> cacheMap = new HashMap<String, Boolean>();
//禁止指令重排优化
private static volatile ResponseURICache URICACHE;
private ResponseURICache(){}
public static ResponseURICache getInstance(){
if(null == URICACHE){
synchronized(ResponseURICache.class){
if(null == URICACHE){
URICACHE = new ResponseURICache();
}
}
}
return URICACHE;
}
/**
* 设置缓存值
* @param key
* @param value
*/
public void set(String key, Boolean value) {
cacheMap.put(key, value);
}
/**
* 获取缓存key的value值
* @param key
* @return
*/
public Boolean get(String key) {
if (!cacheMap.containsKey(key)) {
return null;
}
return cacheMap.get(key);
}
}
package com.api.controll;
import java.util.HashMap;
import java.util.Map;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.api.annotation.ResponseResult;
@RestController
@ResponseBody
public class BookControll {
@GetMapping("book")
@ResponseResult
public Object getBook(){
Map<String, String> map = new HashMap<String, String>();
map.put("title", "倾城之恋");
map.put("author", "张爱玲");
return map;
}
@GetMapping("/book/name")
public Object getBookById(){
Map<String, String> map = new HashMap<String, String>();
map.put("title", "金锁记");
map.put("author", "张爱玲");
return map;
}
}