Spring Model 和 Map
水三丫 人气:1Model 和 Map
为什么在Model和Map中放值传入后会出现在request的上面。
9.1、源码解析
准备测试代码
@GetMapping("/goto") public String go(HttpServletRequest request, Map<String,Object> map, Model model){ request.setAttribute("msg","传过来...."); map.put("map","map hello word!!"); model.addAttribute("model","model hello word!!"); return "forward:success"; } @ResponseBody @GetMapping("/success") public Map success(@RequestAttribute(value = "msg",required = false) String msg, HttpServletRequest request){ Map<String,Object> hashMap = new HashMap<>(); Object msg1 = request.getAttribute("msg"); Object map = request.getAttribute("map"); Object model = request.getAttribute("model"); hashMap.put("map1",map); hashMap.put("model",model); hashMap.put("msg1",msg1); return hashMap; }
第一步进入DispatchServlet 的 doDispatch中
主要的三步
DispatchServlet类中的 doDispatch方法 // Determine handler for the current request. mappedHandler = getHandler(processedRequest);//获取反射的方法处理器 // Determine handler adapter for the current request. //获取参数处理器 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // Actually invoke the handler. //反射执行方法和解析Model和Map mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
在获取参数阶段,解Model和Map
- 获取Map 的 处理器器 MapMethodProcessor
- 处理Map这个参数
MapMethodProcessor类中的 @Override @Nullable public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception { Assert.state(mavContainer != null, "ModelAndViewContainer is required for model exposure"); return mavContainer.getModel(); } 然后进入ModelAndViewContainer类中的 private final ModelMap defaultModel = new BindingAwareModelMap(); public ModelMap getModel() { if (useDefaultModel()) { return this.defaultModel;//获取ModelMap } ......
- 把这个ModelMap对象返回
- 获取Model的 处理器器 ModelMethodProcessor
- 处理Model这个参数
ModelMethodProcessor类中的 @Override @Nullable public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception { Assert.state(mavContainer != null, "ModelAndViewContainer is required for model exposure"); return mavContainer.getModel(); } 然后进入ModelAndViewContainer类中的 private final ModelMap defaultModel = new BindingAwareModelMap(); public ModelMap getModel() { if (useDefaultModel()) { return this.defaultModel;//获取ModelMap 这个和那个Map获取的是同一个 } ......
把同一个ModelMap对象返回
反射调用方法
由于是同一个对象所有 map 和 model中的值都样,所以往map和Model放值都一样
把model和map的数据放入request
第一步
ServletInvocableHandlerMethod类中 invokeAndHandle方法 //获取返回值的一个处理器 try { this.returnValueHandlers.handleReturnValue( returnValue, getReturnValueType(returnValue), mavContainer, webRequest); } HandlerMethodReturnValueHandlerComposite类中的 HandlerMethodReturnValueHandler方法 进行获取
这里获取的ViewNameMethodReturnValueHandler
这个处理器
第二步
把Map和 Model携带的参数和返回值(路径)进行整合为ModelAndView
RequestMappingHandlerAdapter类中 handleInternal方法 ... ModelAndView mav; ... mav = invokeHandlerMethod(request, response, handlerMethod); ...
第三步
准备派发和放入参数
DispatchServlet类中的 doDispatch方法 render(mv, request, response); view.render(mv.getModelInternal(), request, response); AbstractView类中的 render方法 //把BindingAwareModelMap的参数封装为Map Map<String, Object> mergedModel = createMergedOutputModel(model, request, response); prepareResponse(request, response); //准备方法和放入参数到reques中 renderMergedOutputModel(mergedModel, getRequestToExpose(request), response); InternalResourceView类中的 renderMergedOutputModel // Expose the model object as request attributes. exposeModelAsRequestAttributes(model, request);//把参数放入到request中 AbstractView类中的 //把参数放入到原生的request域中 protected void exposeModelAsRequestAttributes(Map<String, Object> model, HttpServletRequest request) throws Exception { model.forEach((name, value) -> { if (value != null) { request.setAttribute(name, value); } else { request.removeAttribute(name); } }); }
加载全部内容