SpringMVC响应结果的生成
来源:互联网 发布:好听有内涵的名字知乎 编辑:程序博客网 时间:2024/04/26 10:49
SpringMVC响应结果的生成
前面的文章讲过,SpringMVC接收到来自客户端的请求,找到处理请求的Handler,然后构造适配器HandleAdapter。HandleAdapter处理请求后返回ModelAndView对象(也可能返回null)。以RequestMappingHandlerAdapter为例,看看ModelAndView是怎样生成的,它的invokeHandlerMethod方法用来处理请求,生成ModelAndView。
private ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response,HandlerMethod handlerMethod) throws Exception {ServletWebRequest webRequest = new ServletWebRequest(request, response);WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);ServletInvocableHandlerMethod requestMappingMethod = createRequestMappingMethod(handlerMethod, binderFactory);ModelAndViewContainer mavContainer = new ModelAndViewContainer();mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));modelFactory.initModel(webRequest, mavContainer, requestMappingMethod);mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);requestMappingMethod.invokeAndHandle(webRequest, mavContainer);modelFactory.updateModel(webRequest, mavContainer);if (mavContainer.isRequestHandled()) {return null;}else {ModelMap model = mavContainer.getModel();ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model);if (!mavContainer.isViewReference()) {mav.setView((View) mavContainer.getView());}if (model instanceof RedirectAttributes) {Map<String, ?> flashAttributes = ((RedirectAttributes) model).getFlashAttributes();RequestContextUtils.getOutputFlashMap(request).putAll(flashAttributes);}return mav;}}
它先创建一个ModelAndViewContainer对象,这个对象包含了请求的处理结果。然后根据ModelAndViewContainer的结果创建、设置ModelAndView。如果请求的结果已经发送到客户端了(比如直接向response的OutputStream写入返回数据)则返回null,否则利用view的名字或者view创建ModelAndView并返回。那么ModelAndViewContainer中的结果是如何被设置的呢?要看ServletInvocableHandlerMethod的invokeAndHandle方法:
public final void invokeAndHandle(NativeWebRequest request, ModelAndViewContainer mavContainer,Object... providedArgs) throws Exception {Object returnValue = invokeForRequest(request, mavContainer, providedArgs);setResponseStatus((ServletWebRequest) request);if (returnValue == null) {if (isRequestNotModified(request) || hasResponseStatus() || mavContainer.isRequestHandled()) {mavContainer.setRequestHandled(true);return;}}mavContainer.setRequestHandled(false);try {returnValueHandlers.handleReturnValue(returnValue, getReturnType(), mavContainer, request);} catch (Exception ex) {if (logger.isTraceEnabled()) {logger.trace(getReturnValueHandlingErrorMessage("Error handling return value", returnValue), ex);}throw ex;}}
下面我们详细分析一下这个方法,returnValue就是调用Controller方法的返回值,它可以是任意类型的值,但是并不意味着我们返回任何值,spring都能正确处理。具体我们可以返回哪些值,由returnValueHandlers决定。returnValueHandlers的设计采用了SpringMVC中随处可见的组合模式和策略模式。默认情况下,有如下的returnValueHandler:
根据名字可以推断,Controller方法可以直接返回ModelAndView,也可以返回view的名字等等。DispatcherServlet获取到ModelAndView之后需要解析出View对象,然后渲染这个View。
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {// Determine locale for request and apply it to the response.Locale locale = this.localeResolver.resolveLocale(request);response.setLocale(locale);View view;if (mv.isReference()) {// We need to resolve the view name.view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);if (view == null) {throw new ServletException("Could not resolve view with name '" + mv.getViewName() + "' in servlet with name '" +getServletName() + "'");}}else {// No need to lookup: the ModelAndView object contains the actual View object.view = mv.getView();if (view == null) {throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " +"View object in servlet with name '" + getServletName() + "'");}}// Delegate to the View object for rendering.if (logger.isDebugEnabled()) {logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'");}view.render(mv.getModelInternal(), request, response);}
一般情况下,ModelAndView并不包含View对象,而是包含View的名字。然后Spring在利用view的名字找到View对象,一般情况下即JstlView。今天先到这里,后续研究一下JSP的运行原理。
0 0
- SpringMVC响应结果的生成
- Jmeter分析请求的响应结果
- Http请求常见的响应结果码
- springmvc + excel的生成
- 服务器端生成的 JavaScript 响应
- 服务器端生成的 JavaScript 响应
- SpringMVC 跳转结果的方式.练习笔记
- Insight springmvc 对controller 结果的处理
- SpringMVC 结果的转发和重定向
- 【SpringMVC】SpringMVC结果的转发和重定向(十六)
- Http响应结果码
- 解析Ajax响应结果的两种简单方法.
- 解析ajax响应结果的两种简单方法
- *总的表扬,大家齐力攻坚,积极响应的结果
- JMETER处理jdbc请求后的响应结果
- JMETER处理jdbc请求后的响应结果
- Jmeter-获取响应结果中参数出现的次数
- 使用ASP.NET生成XMLHttpRequest的响应
- 员工离职停用ebs账号时,需要检查的内容
- (学习)C++ Primer(1)
- iOS开发——网络连接判断
- jsp清空input
- 解决firefox页面刷新后退,按钮禁用状态无法恢复
- SpringMVC响应结果的生成
- 1295: [SCOI2009]最长距离
- thinkphp 3.2 =》0625-2_ =>css/js /mages路径
- sublime 好用的插件
- 107Binary Tree Level Order Traversal II
- Stream API:有状态的转换
- Ceph Storange Cluster----配置
- 安装git
- 以太网为什么要限制最小帧长?