SpringMVC学习笔记一

1.SpringMVC介绍

Spring框架提供了完成企业级Web开发所需的功能,而SpringMVC是包含这些实现过程的一个子项目,它完全符合如今web应用程序开发框架中所广泛使用的MVC(Model View Controller,模型-视图-控制器)模式。

SpringMVC是一个分层的Java Web开发框架,MVC提供了一个分层体系结构。

Model(模型):是应用程序使用的特定域信息的表现形式;

View(视图):域模型的表现形式,如输入文本框,按钮等页面元素,这些元素与模型进行交互。

Controller(控制器):主要负责解释用户输入,并转换为模型,并将结果显示给用户。

SpringMVC是一个基于动作的MVC框架,该框架突出了HTTP协议中的请求/响应特性。在该框架中,用户的每一个请求都对应一个需要执行的动作,即每一个用户请求,都需要有对应的处理方法,SpringMVC将每个请求映射到一个可执行的方法来对其处理。

因为SpringMVC是Spring的子项目,所以SpringMVC集成了Spring的核心功能,如依赖注入。

2. SpringMVC处理请求流程解析

DsipatcherServet(前端控制器)是SpringMVC的核心元素,它是主要的Servlet,负责处理用户请求,并将请求分发给对应的Controller。

具体请求处理流程如下:

该图来自 :SpringMVC处理请求流程

请求处理流程解释:

      1. 用户向服务器发送请求,请求被前端控制器 DispatcherServlet捕获;

      2. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用处理器映射器HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;

      3. DispatcherServlet 根据获得的Handler,选择一个合适的处理器适配器HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法)

       4.  DispatcherServlet提取Request中的模型数据,填充Handler入参,然后由处理器适配器HandlerAdapter调用它的handle()方法,开始执行Handler(Controller)中对应处理方法。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:

      HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息

      数据转换:对请求消息进行数据转换。如String转换成Integer、Double等

      数据格式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等

      数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中

      5.  Handler执行完成后(handle()方法执行完成后),向DispatcherServlet 返回一个ModelAndView对象;

      6.  DispatcherServlet根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;

      7. ViewResolver 结合Model和View,来渲染视图

      8. DispatcherServlet将渲染结果返回给客户端。

 以下是DispatcherServlet源码中的doDispatch等方法,并未列全,帮助理解上面的请求处理过程。方法中加了一些注释,是自己的理解。

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
       //1.用户请求
 HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        boolean multipartRequestParsed = false;
        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

        try {
            try {
                ModelAndView mv = null;
                Exception dispatchException = null;

                try {
                    processedRequest = this.checkMultipart(request);
                    multipartRequestParsed = processedRequest != request;
//2.DispatcherServlet调用处理器映射器HandlerMapping,获得HandlerExecutionChain对象,包含Handler配置的所有相关的对象
                    mappedHandler = this.getHandler(processedRequest);
                    if (mappedHandler == null || mappedHandler.getHandler() == null) {
                        this.noHandlerFound(processedRequest, response);
                        return;
                    }

//3. DispatcherServlet 根据获得的Handler,获得一个合适的处理器适配器HandlerAdapter。
                    HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
                    String method = request.getMethod();
                    boolean isGet = "GET".equals(method);
                    if (isGet || "HEAD".equals(method)) {
                        long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                        if (this.logger.isDebugEnabled()) {
                            this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                        }

                        if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
                            return;
                        }
                    }

//如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法
                    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                        return;
                    }

//4.提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作.
//5.处理器方法执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                    if (asyncManager.isConcurrentHandlingStarted()) {
                        return;
                    }

//  6.  根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;
                    this.applyDefaultViewName(processedRequest, mv);
//拦截器中的方法,处理器方法执行完,返回ModelAndView前执行
                    mappedHandler.applyPostHandle(processedRequest, response, mv);
                } catch (Exception var19) {
                    dispatchException = var19;
                }

//     8. 将渲染结果返回给客户端。
                this.processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
            } catch (Exception var20) {
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, var20);
            } catch (Error var21) {
                this.triggerAfterCompletionWithError(processedRequest, response, mappedHandler, var21);
            }

        } finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                if (mappedHandler != null) {
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                }
            } else if (multipartRequestParsed) {
                this.cleanupMultipart(processedRequest);
            }

        }
    }

//获得HandlerExecutionChain
 protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        Iterator var2 = this.handlerMappings.iterator();

        HandlerExecutionChain handler;
        do {
            if (!var2.hasNext()) {
                return null;
            }
//处理器映射器
            HandlerMapping hm = (HandlerMapping)var2.next();
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Testing handler map [" + hm + "] in DispatcherServlet with name '" + this.getServletName() + "'");
            }

            handler = hm.getHandler(request);
        } while(handler == null);

        return handler;
    }

//
private void applyDefaultViewName(HttpServletRequest request, ModelAndView mv) throws Exception {
        if (mv != null && !mv.hasView()) {
            mv.setViewName(this.getDefaultViewName(request));
        }

    }

3. SpringMVC绑定机制

SpringMVC提供一种绑定机制,通过该机制可以从用户请求中提取数据,然后将数据转换为预定义格式,最后通过映射到一个模型类,从而创建一个对象。

每一个web应用程序都需要与表单进行交互,SpringMVC使用自定义的JSP表单标签库提供表单处理方法。表单标签库使用自定义标签创建视图,并提供了与模型类的绑定功能。通过SpringMVC框架绑定功能,可以将浏览器提交的Http请求中的参数映射到模型属性。

3.1 表单标签库使用

(1)通过taglib指令,将SpringMVC的JSP标签库定义添加到页面中。

(2)在页面中使用SpringMVC的jsp标签,如<mvc:input>等

<%@taglib prefix="mvc" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
		
	</head>
	<body style="background: #e1e9eb;">
		<mvc:form modelAttribute="user" action="/result">		
					<table  >
						<tbody>
							<tr>
							<td ><mvc:label path="userName">用户名</mvc:label></td>
							<td >
								<mvc:input  path="userName"/>
							</td>
							
						</tr>
						
					  </tbody>
					</table>

		</mvc:form>
	</body>
</html>

form标签的modelAttribute特性执行了模型类user,mvc:input的path特性实现了对模型属性的绑定,意思是将该输入框的数据与模型类user的属性userName绑定。这样,在提交表单请求给服务器时,Controller中可以获得模型user,其中属性userName的值是用户输入值。其他mvc输入标签类似。

4.SpringMVC常用注解

下面这个链接博客对SpringMVC常用的注解讲解的非常清楚。

springmvc常用注解标签详解

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值