来源:http://blog.csdn.net/u013979547/article/details/53449788

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 {@Autowiredprivate ResponseHolder responseHolder;private Logger logger = LogManager.getLogger(ResponseInterceptor.class);@Overridepublic boolean preHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception{return true;}@Overridepublic void postHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3, ModelAndView var4) throws Exception{//do noting}@Overridepublic 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接口,我们可以添加自己想加的拦截器,也能配置特殊不需要拦截的接口。代码虽简单,但值得细细揣摩,也有许多可优化的地方!

 

Spring拦截器拦截request与response业务数据相关推荐

  1. spring拦截器 拦截和排除接口冲突

    以下为springboot案例: 场景:  某个规则下的绝大部分接口路径不需要经过拦截器, 但其中的某几个接口又需要经过拦截器. 例如: "/api/register/**" 模式 ...

  2. 【项目经验】拦截器拦截入参出参

    文章目录 拦截器拦截入参出参 入参 出参 拦截器拦截入参出参 入参 @Overridepublic boolean preHandle(HttpServletRequest request, Http ...

  3. axios config里自定义属性,使用拦截器拦截,无法拿到自定义属性问题

    axios config里自定义属性,使用拦截器拦截,无法拿到自定义属性问题 最新版本axios限制了键,对键值做了白名单处理. 解决思路: 修改源码中的内容,添加一个键来报错额外属性. 或者:使用老 ...

  4. 在JSP中常见问题,防止SpringMVC拦截器拦截js等静态资源文件的解决方案

    在JSP中常见问题,防止SpringMVC拦截器拦截js等静态资源文件的解决方案 参考文章: (1)在JSP中常见问题,防止SpringMVC拦截器拦截js等静态资源文件的解决方案 (2)https: ...

  5. spring MVC中获取request和response

    spring MVC中获取request和response: Java代码   HttpServletRequest request = ((ServletRequestAttributes) Req ...

  6. Spring拦截器获取request请求体中的json数据,并转换成Java对象的解决办法

    1.要被拦截的Controller接口 我们需要一个更新用户信息接口,请求方式为POST,参数类型为对象类型(UserInfo),代码如下: @Resource private UserService ...

  7. spring mvc 拦截器拦截jsp页面

    spring mvc 拦截器怎么拦截jsp页面 你这个 是拦截带 /jsp 的 .do请求 解决方案 用spring 的拦截器 去拦截 所有的 .do 请求, 然后写一个 过滤器去拦截 所有的.jsp ...

  8. 5 拦截器拦截请求路由_手写简易版axios拦截器,实现微信小程序wx.request的封装与拦截...

    前言: axios是一个功能强大的网络请求库,其中拦截器又是axios的精髓.在小程序的开发或者需要手动实现ajax的时候,没有实现对请求的拦截,开发的时候非常不方便,因此手写一个简易版的axios拦 ...

  9. vue fromData提交表单(文件)的同时 axios通过将token封装一起发送,Springboot后端拦截器通过request.getParameter获取,Redis验证token

    一.前端: 1.在封装好的axios接口: import axios from 'axios'axios.defaults.withCredentials = true;// 允许跨域携带cookie ...

最新文章

  1. C++中operator关键字(重载操作符)
  2. [感动]看来的故事:小孩和鱼
  3. 组合恒等式7 组合变换的互逆公式 简介与简单例子
  4. linux下怎么编译贪吃蛇,Linux 环境下C语言编译实现贪吃蛇游戏(转载)
  5. SPS2003升级MOSS2007时SSO部件错误解决
  6. 采购的业务处理流程之 现购
  7. 两台电脑navicat数据传输_出门忘带数据线?可以来了解OPPO的多种数据传输方案...
  8. Java EE并发API教程
  9. 查找表的原理与结构 什么是竞争与冒险现象?怎样判断?如何消除?
  10. 登录计算机怎么保存用户名,浏览器保存了账号密码怎么查看,教您怎么查看
  11. flask-sqlalchemy 数据基本操作
  12. postgresql 动态添加过滤条件_XsqlFilterResult----动态生成sql语句的类,过滤一些为空的查询条件...
  13. C++中使用GSoap
  14. uniapp使用iconfont图标
  15. 投射式触摸屏自电容与互电容工作原理基础(未完待续)
  16. C语言设计一个投票程序,c语言程序设计投票程序
  17. 单片机测试开发板用什么软件,怎么知道单片机开发板的好坏
  18. SQL基础整理(四) 数据的插入,删除和更新,以及事物
  19. 演讲或报告拖延症的终结者,专克各种会议拖延 ppt 演讲 计时器
  20. 使用adb 命令时提示“adb”既不是内部或外部命令,也不是可运行的程序

热门文章

  1. [BJDCTF2020]伏羲六十四卦
  2. autocad.net 画多段线_解决AutoCAD2014绘制多段线的详细教程--系统之家
  3. 环境变量是什么?一看就懂
  4. 在html字体向上走,怎么使用PR制作好像电影结尾那种向上走的字幕?
  5. sketch up城市设计建模流程
  6. layer的简单的使用
  7. ubuntu (20.04 LTS) 屏幕亮度调节无效解决方法
  8. 怎样理解python中的GIL?
  9. MATLAB常用的快捷键
  10. pcb布线拐角处打地孔_PCB上的走线到底能不能走90°拐角?这是一个值得关注的问题...