mvc项目源码分享网站 mvc.

老铁们,大家好,相信还有很多朋友对于mvc项目源码分享网站和mvc.的相关问题不太懂,没关系,今天就由我来为大家分享分享mvc项目源码分享网站以及mvc.的问题,文章篇幅可能偏长,希望可以帮助到大家,下面一起来看看吧!

今天来聊一个JavaWeb中简单的话题,但是感觉却比较稀罕,因为这个技能点,有的小伙伴们可能没听过!

1.缘起

说到Web请求参数传递,大家能想到哪些参数传递方式?

参数可以放在地址栏中,不过地址栏参数的长度有限制,并且在有的场景下我们可能不希望参数暴漏在地址栏中。参数可以放在请求体中,这个没啥好说的。

小伙伴们试想这样一个场景:

在一个电商项目中,有一个提交订单的请求,这个请求是一个POST请求,请求参数都在请求体中。当用户提交成功后,为了防止用户刷新浏览器页面造成订单请求重复提交,我们一般会将用户重定向到一个显示订单的页面,这样即使用户刷新页面,也不会造成订单请求重复提交。

大概的代码就像下面这样:

@Controller\npublicclassOrderController{\n@PostMapping(&34;)\npublicStringorder(OrderInfoorderInfo){\n//其他处理逻辑\nreturn&34;;\n}\n}\n

这段代码我相信大家都懂吧!如果不懂可以看看松哥录制的免费的SpringMVC入门教程(硬核!松哥又整了一套免费视频,搞起!)。

但是这里有一个问题:如果我想传递参数怎么办?

如果是服务器端跳转,我们可以将参数放在request对象中,跳转完成后还能拿到参数,但是如果是客户端跳转我们就只能将参数放在地址栏中了,像上面这个方法的返回值我们可以写成:return&34;;,这种传参方式有两个缺陷:

地址栏的长度是有限的,也就意味着能够放在地址栏中的参数是有限的。不想将一些特殊的参数放在地址栏中。

那该怎么办?还有办法传递参数吗?

有!这就是今天松哥要和大家介绍的flashMap,专门用来解决重定向时参数的传递问题。

2.flashMap

在重定向时,如果需要传递参数,但是又不想放在地址栏中,我们就可以通过flashMap来传递参数,松哥先来一个简单的例子大家看看效果:

首先我们定义一个简单的页面,里边就一个post请求提交按钮,如下:

<!DOCTYPEhtml>\n<htmllang=&34;>\n<head>\n<metacharset=&34;>\n<title>Title</title>\n</head>\n<body>\n<formaction=&34;method=&34;>\n<inputtype=&34;value=&34;>\n</form>\n</body>\n</html>\n

然后在服务端接收该请求,并完成重定向:

@Controller\npublicclassOrderController{\n@PostMapping(&34;)\npublicStringorder(HttpServletRequestreq){\nFlashMapflashMap=(FlashMap)req.getAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE);\nflashMap.put(&34;,&34;);\nreturn&34;;\n}\n\n@GetMapping(&34;)\n@ResponseBody\npublicStringorderList(Modelmodel){\nreturn(String)model.getAttribute(&34;);\n}\n}\n

首先在order接口中,获取到flashMap属性,然后存入需要传递的参数,这些参数最终会被SpringMVC自动放入重定向接口的Model中,这样我们在orderlist接口中,就可以获取到该属性了。

当然,这是一个比较粗糙的写法,我们还可以通过RedirectAttributes来简化这一步骤:

@Controller\npublicclassOrderController{\n@PostMapping(&34;)\npublicStringorder(RedirectAttributesattr){\nattr.addFlashAttribute(&34;,&34;);\nattr.addAttribute(&34;,&34;);\nreturn&34;;\n}\n\n@GetMapping(&34;)\n@ResponseBody\npublicStringorderList(Modelmodel){\nreturn(String)model.getAttribute(&34;);\n}\n}\n

RedirectAttributes中有两种添加参数的方式:

addFlashAttribute:将参数放到flashMap中。addAttribute:将参数放到URL地址中。

经过前面的讲解,现在小伙伴们应该大致明白了flashMap的作用了,就是在你进行重定向的时候,不通过地址栏传递参数。

很多小伙伴可能会有疑问,重定向其实就是浏览器发起了一个新的请求,这新的请求怎么就获取到上一个请求保存的参数呢?这我们就要来看看SpringMVC的源码了。

3.源码分析

首先这里涉及到一个关键类叫做FlashMapManager,如下:

publicinterfaceFlashMapManager{\n@Nullable\nFlashMapretrieveAndUpdate(HttpServletRequestrequest,HttpServletResponseresponse);\nvoidsaveOutputFlashMap(FlashMapflashMap,HttpServletRequestrequest,HttpServletResponseresponse);\n}\n

两个方法含义一眼就能看出来:

retrieveAndUpdate:这个方法用来恢复参数,并将恢复过的的参数和超时的参数从保存介质中删除。saveOutputFlashMap:将参数保存保存起来。

FlashMapManager的实现类如下:

从这个继承类中,我们基本上就能确定默认的保存介质时session。具体的保存逻辑则是在AbstractFlashMapManager类中。

整个参数传递的过程可以分为三大步:

第一步,首先我们将参数设置到outputFlashMap中,有两种设置方式:我们前面的代码req.getAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE)就是直接获取outputFlashMap对象然后把参数放进去;第二种方式就是通过在接口中添加RedirectAttributes参数,然后把需要传递的参数放入RedirectAttributes中,这样当处理器处理完毕后,会自动将其设置到outputFlashMap中,具体逻辑在RequestMappingHandlerAdapterdoService方法后,此时会调用FlashMapManagerretrieveAndUpdate:

publicfinalFlashMapretrieveAndUpdate(HttpServletRequestrequest,HttpServletResponseresponse){\nList<FlashMap>allFlashMaps=retrieveFlashMaps(request);\nif(CollectionUtils.isEmpty(allFlashMaps)){\nreturnnull;\n}\nList<FlashMap>mapsToRemove=getExpiredFlashMaps(allFlashMaps);\nFlashMapmatch=getMatchingFlashMap(allFlashMaps,request);\nif(match!=null){\nmapsToRemove.add(match);\n}\nif(!mapsToRemove.isEmpty()){\nObjectmutex=getFlashMapsMutex(request);\nif(mutex!=null){\nsynchronized(mutex){\nallFlashMaps=retrieveFlashMaps(request);\nif(allFlashMaps!=null){\nallFlashMaps.removeAll(mapsToRemove);\nupdateFlashMaps(allFlashMaps,request,response);\n}\n}\n}\nelse{\nallFlashMaps.removeAll(mapsToRemove);\nupdateFlashMaps(allFlashMaps,request,response);\n}\n}\nreturnmatch;\n}\n

首先调用retrieveFlashMaps方法从session中获取到所有的FlashMap。调用getExpiredFlashMaps方法获取所有过期的FlashMap,FlashMap默认的过期时间是180s。获取和当前请求匹配的getMatchingFlashMap,具体的匹配逻辑就两点:重定向地址要和当前请求地址相同;预设参数要相同。一般来说我们不需要配置预设参数,所以这一条可以忽略。如果想要设置,则首先给flashMap设置,像这样:flashMap.addTargetRequestParam(&34;,&34;);,然后在重定向的地址栏也加上这个参数:return&34;;即可。将获取到的匹配的FlashMap对象放入mapsToRemove集合中(这个匹配到的FlashMap即将失效,放入集合中一会被清空)。将allFlashMaps集合中的所有mapsToRemove数据清空,同时调用updateFlashMaps方法更新session中的FlashMap。最终将匹配到的flashMap返回。

这就是整个获取flashMap的方法,整体来看还是非常easy的,并没有什么难点。

4.小结

好啦,今天就和小伙伴们分享了一下SpringMVC中的flashMap,不知道大家有没有在工作中用到这个东西?如果刚好碰到松哥前面所说的需求,用FlashMap真的还是蛮方便的。如果需要下载本文案例,小伙伴们可以在公众号【江南一点雨】后台回复20210302,好啦,今天就和大家聊这么多~

关于mvc项目源码分享网站,mvc.的介绍到此结束,希望对大家有所帮助。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平