In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-03 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly introduces "what are the transmission methods of parameters in SpringMVC". In daily operation, I believe that many people have doubts about the transmission methods of parameters in SpringMVC. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the doubts about "what are the transmission methods of parameters in SpringMVC?" Next, please follow the editor to study!
1. Origin
When it comes to Web request parameter passing, what parameter passing methods can you think of?
Parameters can be placed in the address bar, but the length of the parameters in the address bar is limited, and in some scenarios we may not want the parameters to be exposed in the address bar. Parameters can be put in the request body, which is nothing to say.
Guys, imagine this scene:
In an e-commerce project, there is a request to submit an order, which is a POST request, and the request parameters are in the body of the request. When the user submits successfully, in order to prevent the user from refreshing the browser page and causing the order request to be submitted repeatedly, we usually redirect the user to a page that displays the order, so that even if the user refreshes the page, it will not cause the order request to be submitted repeatedly.
The approximate code looks like this:
@ Controller public class OrderController {@ PostMapping ("/ order") public String order (OrderInfo orderInfo) {/ / other processing logic return "redirect:/orderlist";}}
I believe we all understand this code! If you don't understand, you can take a look at Song GE's free SpringMVC tutorial (hardcore! Brother Song made another set of free videos, do it!).
But there is a problem here: what if I want to pass parameters?
If it is a server-side jump, we can put the parameters in the request object, and we can still get the parameters after the jump is completed. But if it is a client-side jump, we can only put the parameters in the address bar. For example, the return value of the above method can be written as: return "redirect:/orderlist?xxx=xxx";, this method has two defects:
The length of the address bar is limited, which means that the parameters that can be placed in the address bar are limited.
You don't want to put some special parameters in the address bar.
What are we going to do? Is there any way to pass parameters?
Yes! This is the flashMap that Songge is going to introduce to you today, which is specially used to solve the problem of parameter transfer when redirecting.
2.flashMap
When redirecting, if you need to pass parameters but do not want to put them in the address bar, we can pass parameters through flashMap. Brother Song, let's take a simple example to see the effect:
First, let's define a simple page with a post request submit button, as follows:
Title
Then receive the request on the server side and complete the redirection:
@ Controller public class OrderController {@ PostMapping ("/ order") public String order (HttpServletRequest req) {FlashMap flashMap = (FlashMap) req.getAttribute (DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE); flashMap.put ("name", "a little rain in Jiangnan"); return "redirect:/orderlist" @ GetMapping ("/ orderlist") @ ResponseBody public String orderList (Model model) {return (String) model.getAttribute ("name");}}
First, get the flashMap attribute in the order interface, and then store the parameters that need to be passed. These parameters will eventually be automatically put into the Model of the redirect interface by SpringMVC, so that we can get the attribute in the orderlist interface.
Of course, this is a rough way to write, and we can simplify this step through RedirectAttributes:
@ Controller public class OrderController {@ PostMapping ("/ order") public String order (RedirectAttributes attr) {attr.addFlashAttribute ("site", "www.javaboy.org"); attr.addAttribute ("name", "Wechat official account: a little rain in Jiangnan"); return "redirect:/orderlist" @ GetMapping ("/ orderlist") @ ResponseBody public String orderList (Model model) {return (String) model.getAttribute ("site");}}
There are two ways to add parameters in RedirectAttributes:
AddFlashAttribute: put the parameters into the flashMap.
AddAttribute: put the parameters in the URL address.
After the previous explanation, friends should now roughly understand the role of flashMap, that is, when you redirect, do not pass parameters through the address bar.
Many friends may wonder, redirection is actually a new request initiated by the browser, how can this new request get the saved parameters of the last request? Here we are going to look at the source code of SpringMVC.
3. Source code analysis
First of all, there is a key class called FlashMapManager, which is as follows:
Public interface FlashMapManager {@ Nullable FlashMap retrieveAndUpdate (HttpServletRequest request, HttpServletResponse response); void saveOutputFlashMap (FlashMap flashMap, HttpServletRequest request, HttpServletResponse response);}
The meaning of the two methods can be seen at a glance:
RetrieveAndUpdate: this method is used to restore parameters and remove recovered parameters and timeout parameters from the save media.
SaveOutputFlashMap: save the parameters.
The implementation classes of FlashMapManager are as follows:
From this inherited class, we can basically determine the default session when saving the media. The specific save logic is in the AbstractFlashMapManager class.
The whole process of parameter passing can be divided into three steps:
The first step, first, we set the parameters to outputFlashMap. There are two ways to set them: our previous code, req.getAttribute (DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE), is to get the outputFlashMap object directly and put the parameters in it. The second way is to add RedirectAttributes parameters to the interface, and then put the parameters to be passed into the RedirectAttributes, so that when the processor has finished processing, it will automatically set it to the outputFlashMap. The specific logic is in the RequestMappingHandlerAdapter#getModelAndView method:
Private ModelAndView getModelAndView (ModelAndViewContainer mavContainer, ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {/ / omitted. If (model instanceof RedirectAttributes) {Map flashAttributes = ((RedirectAttributes) model). GetFlashAttributes (); HttpServletRequest request = webRequest.getNativeRequest (HttpServletRequest.class); if (request! = null) {RequestContextUtils.getOutputFlashMap (request) .putAll (flashAttributes);}} return mav;}
As you can see, if model is an instance of RedirectAttributes, the outputFlashMap property is obtained through the getOutputFlashMap method, and then the related property is set in it.
This is the first step, which is to save the parameters that need to be passed into flashMap.
The second step is to redirect the corresponding view is RedirectView. In its renderMergedOutputModel method, the saveOutputFlashMap method of FlashMapManager is called to save the outputFlashMap to session, as follows:
Protected void renderMergedOutputModel (Map model, HttpServletRequest request, HttpServletResponse response) throws IOException {String targetUrl = createTargetUrl (model, request); targetUrl = updateTargetUrl (targetUrl, model, request, response); / / Save flash attributes RequestContextUtils.saveOutputFlashMap (targetUrl, request, response); / / Redirect sendRedirect (request, response, targetUrl, this.http10Compatible);}
The RequestContextUtils.saveOutputFlashMap method will eventually call the saveOutputFlashMap method of FlashMapManager to save the outputFlashMap. Let's take a look at the preservation logic:
Public final void saveOutputFlashMap (FlashMap flashMap, HttpServletRequest request, HttpServletResponse response) {if (CollectionUtils.isEmpty (flashMap)) {return;} String path = decodeAndNormalizePath (flashMap.getTargetRequestPath (), request); flashMap.setTargetRequestPath (path); flashMap.startExpirationPeriod (getFlashMapTimeout ()); Object mutex = getFlashMapsMutex (request); if (mutex! = null) {synchronized (mutex) {List allFlashMaps = retrieveFlashMaps (request); allFlashMaps = (allFlashMaps! = null? AllFlashMaps: new CopyOnWriteArrayList (); allFlashMaps.add (flashMap); updateFlashMaps (allFlashMaps, request, response);} else {List allFlashMaps = retrieveFlashMaps (request); allFlashMaps = (allFlashMaps! = null? AllFlashMaps: new ArrayList (1)); allFlashMaps.add (flashMap); updateFlashMaps (allFlashMaps, request, response);}}
In fact, the logic here is also very simple. Before saving, you will set two properties for flashMap, one is the redirected url address, and the other is the expiration time. The expiration time defaults to 180 seconds. These two attributes will be used when loading flashMap in the third step. Then put the flashMap into the collection and call the updateFlashMaps method to store it in the session.
Third, when the redirect request arrives at the DispatcherServlet#doService method, the FlashMapManager#retrieveAndUpdate method is called to get the outputFlashMap from the Session and set it to the standby property in the Request property (which will eventually be converted to the attribute in Model). The related code is as follows:
Protected void doService (HttpServletRequest request, HttpServletResponse response) throws Exception {/ / omitted. If (this.flashMapManager! = null) {FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate (request, response); if (inputFlashMap! = null) {request.setAttribute (INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap (inputFlashMap));} request.setAttribute (OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap ()); request.setAttribute (FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);} / / omitted.}
Notice that the outputFlashMap obtained here has changed its name to inputFlashMap, which is actually the same thing.
We can take a look at the logical AbstractFlashMapManager#retrieveAndUpdate obtained:
Public final FlashMap retrieveAndUpdate (HttpServletRequest request, HttpServletResponse response) {List allFlashMaps = retrieveFlashMaps (request); if (CollectionUtils.isEmpty (allFlashMaps)) {return null;} List mapsToRemove = getExpiredFlashMaps (allFlashMaps); FlashMap match = getMatchingFlashMap (allFlashMaps, request); if (match! = null) {mapsToRemove.add (match);} if (! mapsToRemove.isEmpty ()) {Object mutex = getFlashMapsMutex (request); if (mutex! = null) {synchronized (mutex) {allFlashMaps = retrieveFlashMaps (request) If (allFlashMaps! = null) {allFlashMaps.removeAll (mapsToRemove); updateFlashMaps (allFlashMaps, request, response);}} else {allFlashMaps.removeAll (mapsToRemove); updateFlashMaps (allFlashMaps, request, response);}} return match;}
First, call the retrieveFlashMaps method to get all the FlashMap from the session.
Call the getExpiredFlashMaps method to get all expired FlashMap,FlashMap. The default expiration time is 180 s.
To get the getMatchingFlashMap that matches the current request, the specific matching logic is as follows: the redirect address should be the same as the current request address, and the preset parameters should be the same. Generally speaking, we do not need to configure preset parameters, so this one can be ignored. If you want to set it, first set it to flashMap, like this: flashMap.addTargetRequestParam ("aa", "bb");, and then add this parameter to the redirected address bar: return "redirect:/orderlist?aa=bb";.
Put the matching FlashMap object into the mapsToRemove collection (the matching FlashMap is about to expire and will be emptied when placed in the collection).
Empty all mapsToRemove data in the allFlashMaps collection and call the updateFlashMaps method to update the FlashMap in the session.
The matching flashMap will eventually be returned.
This is the whole method of getting flashMap, on the whole, it is still very easy, and there is no difficulty.
At this point, the study of "what are the methods of passing parameters in SpringMVC" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.