response 获取相应内容_从SpringMVC获取用户信息谈起

本文介绍了在SpringMVC中获取响应数据和用户信息的三种方式,包括直接解析请求头、在过滤器中处理以及利用Web容器特性。作者探讨了这些方式的优缺点,并提出通过扩展Spring的数据绑定接口来实现更优雅的获取用户信息的方法,包括创建自定义的DataBinderFactory和HandlerMethodArgumentResolver。此外,还提供了GitHub上的示例代码供读者参考。
摘要由CSDN通过智能技术生成

c08bde5ae7abaf46bd1d72e636706c63.png

作者:A稻田守望者,Java工程师一枚,热爱开源技术,架构师社区合伙人!


上周末拜读了一位牛人的公众号文章<>,语言风趣,引人入胜,

回顾一下文章内容,为了在Controller的方法中获取已经认证过的用户信息(比如通过JWT-JSON Web Token传输的Token),文中提供了三种方式:

  • 方式一(很挫)直接在Controller方法中获取Token头,然后解析;

  • 方式二(优雅)在过滤器Filter中验证JWT后,直接使用HttpServletRequestWrapper偷梁换柱,覆盖getHeader方法,然后在Controller方法中调用getHeader,这样就不需要再次解析了;

  • 方式三(很优雅)同样在过滤器Filter中使用HttpServletRequestWrapper,只是覆盖getParameterNamesgetParameterValues(针对表单提交)和getInputStream(针对JSON提交),然后就可以和客户端参数相同的方式获取了。

方式一需要重复解析JWT,而且控制器和Servlet API绑定,不方便测试,但是胜在简单直接。方式二和方式三虽然是一个很好的练习HttpServletRequestWrapper的示例,但是可能还算不上是优雅的获取用户信息的方式。

不妨思考一下:

  • 除了获取userId外,如果还想获取JWT中PAYLOAD的其它信息,能不能做到只修改Controller?还是需要再次修改验证JWT的过滤器Filter呢?

  • HttpServletRequestgetInpustStream()方法,Web容器实现基本都是只能调用一次的,因而方式三在扩展getInpustStream()的时候,先将其转换为byte[],然后为了添加用户信息,再将byte[]反序列化为map,添加用户信息之后又序列化为byte[],反复多次,这种方式性能怎么样?如果是文件上传,这种方式能否行得通?

  • 方式三中HttpServletRequestWrapper会无形中启到屏蔽loginUserId参数的作用,但如果客户端的的确确传入了一个loginUserId的参数(当然,这种情况还是需要尽量避免),在Controller中怎么又获取到客户端的这个参数?

有没有什么其它的方式呢?

SpringMVC中关于参数绑定有很多接口,其中很关键的一个是HandlerMethodArgumentResolver,可以通过添加新实现类来实现获取用户信息吗?当然可以,对应该接口的两个方法,首先要能够识别什么情况下需要绑定用户信息,一般来说,可以根据参数的特殊类型,也可以根据参数的特殊注解;其次要能够获取到用户信息,类似于原文中做的那样。虽然这样做也可以实现功能,但是却很繁琐。

不如抛开怎么获取用户信息不谈,先来看看SpringMVC在控制器的处理方法HandlerMethod中绑定参数是怎么做的?

熟悉SpringMVC处理流程的朋友,自然知道,主控制器是DispatcherServlet,在doDispatch()方法中根据HandlerMapping找到处理器,然后找到可以调用该处理器的HandlerAdapter,其中最常用也最核心的莫过于RequestMappingHandlerMappingHandlerMethodRequestMappingHandlerAdapter组合了。查看RequestMappingHandlerAdapter的源码,找到调用HandlerMethod的方法:

@Override
protected ModelAndView handleInternal(HttpServletRequest request,
        HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

    ModelAndView mav;
    checkRequest(request);

    // Execute invokeHandlerMethod in synchronized block if required.
    if (this.synchronizeOnSession) {
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值