Spring拦截器实现controller层json数据返回

    xiaoxiao2021-12-14  16

    Controller层的作用是处理业务逻辑并返回数据,那怎么返回数据呢?接口的请求通过HttpServletRequest和HttpServletResponse实现前后端的交互,ServletResponse中有一个getWriter()方法获取到一个PrintWriter对象,通过PrintWriter的.print()方法即可将数据通过HttpServletResponse传递给前端。

          首先定义一个返回数据的module,

    public class ResponseModel {     public static final int SUCCESS = 200;     public static final int ERROR = 100;     private Integer status;     private String message;     private Object data;     private Locale locale;     public ResponseModel(){         this.status = SUCCESS;         this.locale = Locale.CHINA;     }     public ResponseModel put(String key, Object value){         if(this.data == null || !(data instanceof Map)){             this.data = new HashMap<String,Object>();         }         Map<String, Object> map = (Map<String,Object>)this.data;         map.put(key,value);         return this;     }     public Object getData(){         return data;     }     public ResponseModel setData(Object data){         this.data = data;         return this;     }     public ResponseModel setErrorMsg(ErrorMsg errorMsg){         this.setStatus(errorMsg.getCode());         this.setMessage(errorMsg.getMessage());         return this;     }     public ResponseModel setStatus(int status){         this.status = status;         if(ERROR == status){             this.setMessage("系统错误");         }         return this;     }     public ResponseModel setMessage(String message){         this.message = message;         return this;     }     public int getStatus(){         return status;     }     public String getMessage(){         return message;     } }   再定义一个holder的Bean,返回module作为一个线程级变量放到Bean中, @Component public class ResponseHolder {     private static ThreadLocal<Object> model = new ThreadLocal<>();     public void clean(){         model.remove();     }     public ResponseModel getModel(){         Object o = model.get();         if(o == null){             this.setModel(new ResponseModel());             o = this.getObject();         }         if(o != null && o instanceof ResponseModel){             return (ResponseModel) o;         }else {             return null;         }     }     public Object getObject(){         return model.get();     }     public void setModel(Object o){         model.set(o);     }     public ResponseModel put(String key, Object value){         ResponseModel responseModel = this.getModel();         Object data = responseModel.getData();         if(data == null || !(data instanceof Map)){             data = new HashMap<String,Object>();             responseModel.setData(data);         }         Map<String,Object> map = (Map<String,Object>) data;         map.put(key,value);         return responseModel;     }     public ResponseModel setData(Object data){         ResponseModel responseModel = this.getModel();         responseModel.setData(data);         return responseModel;     }     public ResponseModel setErrorMsg(ErrorMsg errorMsg){         ResponseModel responseModel = this.getModel();         responseModel.setStatus(errorMsg.getCode());         responseModel.setMessage(errorMsg.getMessage());         return responseModel;     } }   其中的ErrorMsg是一个错误枚举, public enum ErrorMsg {     TEST(1,"test"),     SUCCESS(200,"交易完成"),     LOGIN_FAIL(101,"登录失败"),     LOGOUT_SUCCESS(104,"登出成功"),     USER_NOT_FOUND(102,"未注册用户"),     USER_DISABLED(103,"无效用户"),     NO_LOGIN(105,"未登录"),     VERIFY_CODE_ERROR(106,"验证码错误"),     SYSTEM_ERROR(100,"系统错误");     private int code;     private String message;     public int getCode(){         return code;     }     public String getMessage(){         return message;     }     ErrorMsg(int code, String message){         this.code = code;         this.message = message;     } }   接下来定义拦截器,在每个controller完成后从holder中取出数据通过HttpServletResponse传递给前端, @Component public class ResponseInterceptor implements HandlerInterceptor {     @Autowired     private ResponseHolder responseHolder;     private Logger logger = LogManager.getLogger(ResponseInterceptor.class);     @Override     public boolean preHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception{         return true;     }     @Override     public void postHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3, ModelAndView var4) throws Exception{         //do noting     }     @Override     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception exception) throws Exception{         if(responseHolder == null){             logger.error("system error", exception);             responseHolder.setErrorMsg(ErrorMsg.SYSTEM_ERROR);         }         String json = JSON.toJSONString(responseHolder.getModel());         this.returnJson(response,json);         responseHolder.clean();     }     private void returnJson(HttpServletResponse response, String json) throws Exception{         PrintWriter writer = null;         response.setCharacterEncoding("UTF-8");         response.setContentType("text/html; charset=utf-8");         try {             writer = response.getWriter();             writer.print(json);         } catch (IOException e) {             logger.error("response error",e);         } finally {             if (writer != null)                 writer.close();         }     } }

    spring提供了拦截器HandlerInterceptorAdapter对应提供了三个preHandle,postHandle,afterCompletion方法。preHandle在业务处理器处理请求之前被调用,     postHandle在业务处理器处理请求执行完成后,生成视图之前执行,afterCompletion在DispatcherServlet完全处理完请求后被调用,可用于清理资源等 。

     

    拦截器定义完成后,不配置是不起作用的,传统的spring项目通过XML文件配置,spring—boot是为了实现无XML配置,所以可以通过如下方式添加,

    @Configuration public class WebAppConfig extends org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter {     @Autowired     private ResponseInterceptor responseInterceptor;     @Override     public void addInterceptors(InterceptorRegistry registry) {         registry.addInterceptor(responseInterceptor).addPathPatterns("/**").excludePathPatterns("/identifyCode/generate");     } }

     

    这里可是整个拦截器的核心,通过实现addInterceptors接口,我们可以添加自己想加的拦截器,也能配置特殊不需要拦截的接口。代码虽简单,但值得细细揣摩,也有许多可优化的地方!

     
    转载请注明原文地址: https://ju.6miu.com/read-971879.html

    最新回复(0)