SpringMvc菜鸟详解

来源:互联网 发布:河头店农村淘宝地址 编辑:程序博客网 时间:2024/06/17 22:07

1、引言

今天写一点关于框架的东西,因为大多数企业现在都是用的SSH框架,所以我想把框架复习一下,我真的没有想到一个程序猿不经常敲代码会变成一个手残党,我真的很伤心,但是我觉得那些都不是事,只要努力,因为有底子,相信很快能找回感觉,同时还可以让基础更加扎实!

首先在了解SpringMvc前你要了解什么是MVC,我想只要能找到这篇博客的童鞋,多多少少会有所了解!

那么我们来说一下什么是SpringMVC:

SpringMVC是基于java实现了webMVC设计模式的请求驱动类型轻量级框架!前面的这一句话我们得到了很多信息1实现了MVC设计模式,2请求驱动类型的框架,3他是轻量级,那么往往伴随着这几个名词的,那么他出现的目的就是能简便开发,将一些功能进行了解耦,总之就是逼哥大大,功能强大!

优点:

进行更加简洁的web层开发

天生可以和spring集成

支持灵活的URL映射

可以很方便灵活的和其他视图技术集成(如FREEMARKER)

提供了方便的数据验证机制

提供了强大的jsp标签库

对静态资源支持

以上就是我所知道的优点,如果大家还有什么要补充的,就在评论里面猛戳!

2、SpringMVC请求处理流程!

其实,有时候理解一个技术的流程你可以把它想成记录公司的报销流程,这样你就可以更用心的记住,其实有时候面对那些生涩难懂的ABC我也有点无奈,谁让自己木有好好上学,英文那么差呢?不过没关系,只要理解他的思想就行下面就请欣赏我找的图片吧

上面就是就是他完整的一个流程!

好了上面是的我们很容易能理解的一个流程,下面我们看一下官方的一个架构和流程


两张图我们可以看出他的2个特点

1.所有的流程都要经过dispatcherServlet(前端控制器)

2.springMVC它是基于servlet完成的(所以这里面一定将我们的servlet进行了封装,里面一定和servlet有很多共同的地方,所以为了更好的理解我们有时间去扎实一下servlet的基础)

既然知道了它是基于dispatcherServlet完成的所有调度,那么我们来看一下他的源码,毕竟他是开源的不得不再一次感谢那些致力于OpenSource的大牛们,他们让我们的开发更加简便,门坎更低谢谢他们!

    //前端控制器分派方法      protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {              HttpServletRequest processedRequest = request;              HandlerExecutionChain mappedHandler = null;              int interceptorIndex = -1;                    try {                  ModelAndView mv;                  boolean errorView = false;                        try {                         //检查是否是请求是否是multipart(如文件上传),如果是将通过MultipartResolver解析                      processedRequest = checkMultipart(request);                         //步骤2、请求到处理器(页面控制器)的映射,通过HandlerMapping进行映射                      mappedHandler = getHandler(processedRequest, false);                      if (mappedHandler == null || mappedHandler.getHandler() == null) {                          noHandlerFound(processedRequest, response);                          return;                      }                         //步骤3、处理器适配,即将我们的处理器包装成相应的适配器(从而支持多种类型的处理器)                      HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());                              // 304 Not Modified缓存支持                      //此处省略具体代码                            // 执行处理器相关的拦截器的预处理(HandlerInterceptor.preHandle)                      //此处省略具体代码                            // 步骤4、由适配器执行处理器(调用处理器相应功能处理方法)                      mv = ha.handle(processedRequest, response, mappedHandler.getHandler());                            // Do we need view name translation?                      if (mv != null && !mv.hasView()) {                          mv.setViewName(getDefaultViewName(request));                      }                            // 执行处理器相关的拦截器的后处理(HandlerInterceptor.postHandle)                      //此处省略具体代码                  }                  catch (ModelAndViewDefiningException ex) {                      logger.debug("ModelAndViewDefiningException encountered", ex);                      mv = ex.getModelAndView();                  }                  catch (Exception ex) {                      Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);                      mv = processHandlerException(processedRequest, response, handler, ex);                      errorView = (mv != null);                  }                        //步骤5 步骤6、解析视图并进行视图的渲染      //步骤5 由ViewResolver解析View(viewResolver.resolveViewName(viewName, locale))      //步骤6 视图在渲染时会把Model传入(view.render(mv.getModelInternal(), request, response);)                  if (mv != null && !mv.wasCleared()) {                      render(mv, processedRequest, response);                      if (errorView) {                          WebUtils.clearErrorRequestAttributes(request);                      }                  }                  else {                      if (logger.isDebugEnabled()) {                          logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +                                  "': assuming HandlerAdapter completed request handling");                      }                  }                        // 执行处理器相关的拦截器的完成后处理(HandlerInterceptor.afterCompletion)                  //此处省略具体代码                          catch (Exception ex) {                  // Trigger after-completion for thrown exception.                  triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);                  throw ex;              }              catch (Error err) {                  ServletException ex = new NestedServletException("Handler processing failed", err);                  // Trigger after-completion for thrown exception.                  triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);                  throw ex;              }                    finally {                  // Clean up any resources used by a multipart request.                  if (processedRequest != request) {                      cleanupMultipart(processedRequest);                  }              }          }  

这里面我有很多代码都没有往上放,只是在网上找到了一个简单点的(我觉得简单点的),毕竟我只是一个小小的菜鸟

从代码块里我们可以看到,他里面用到了一些设计模式,这里我希望自己和大家有时间看一下设计模式,毕竟设计模式是一个个前辈去糟糠留精华总结出来的,可以为我们简洁代码,严谨思维的东西,我们还是要好好去看一下!后面我们去找一些资料看看,然后将自己的理解和大家分享一下

当我们将她(dispatcherServlet)衣服扒光,看到她时觉得她已经不再神秘,所以大家有时间的时候可以将她拉到自己的IDE里面强暴一下!(说的有点黄了,原谅我这个臭屌丝)

核心架构的具体流程步骤如下:

1、  首先用户发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;

2、  DispatcherServlet——>HandlerMapping, HandlerMapping将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor拦截器)对象,通过这种策略模式,很容易添加新的映射策略;

3、  DispatcherServlet——>HandlerAdapter,HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;

4、  HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView对象(包含模型数据、逻辑视图名);

5、  ModelAndView的逻辑视图名——> ViewResolver, ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;

6、  View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;

7、返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。

看到这7步是不是觉得springMVC就是很简单?其实不是,我觉得有时间还是看一下其他处理器的源码还是比较好的,如果我去看了我会记录下来和大家分享

基本上看完上面的东西我们已经大概对springMVC有了一个初步的理解,那么光说不练毕竟到最后还是一个空架子,所以下面我们就来实际操作一下,让我们加深记忆和理解!(这是我的学习方法,可能觉得很累赘,但是毕竟工作中你还是必须要有产生,所以还是快乐的享受一下敲代码的赶脚)


由于昨天maven没有弄好,所以我就下载了springMVC所需要的所有jar包,累赘就累赘点吧,大家将就着看,还是很适合新手的!

上图:



这些是我下载下来的一会我会把源码和资料放上的

1.新建一个web项目


2.将这些jar包copy到lib目录里面(好像少了有注解的那个包)

3. 编写web.xml文件

<?xml version="1.0" encoding="UTF-8"?>      <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee           http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">          <display-name></display-name>                              <!-- 配置Spring MVC DispatcherServlet -->          <servlet>              <servlet-name>springMVC</servlet-name>              <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>                     </servlet>                <!-- 配置DispatcherServlet所需要拦截的 url -->          <servlet-mapping>              <servlet-name>springMVC</servlet-name>              <url-pattern>/</url-pattern>          </servlet-mapping>                <welcome-file-list>              <welcome-file>index.jsp</welcome-file>          </welcome-file-list>                  </web-app>  

4.编写springMVC-servlet.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:p="http://www.springframework.org/schema/p"        xmlns:context="http://www.springframework.org/schema/context"        xmlns:mvc="http://www.springframework.org/schema/mvc"        xsi:schemaLocation="                http://www.springframework.org/schema/beans                http://www.springframework.org/schema/beans/spring-beans-3.0.xsd                http://www.springframework.org/schema/context                http://www.springframework.org/schema/context/spring-context-3.0.xsd               http://www.springframework.org/schema/mvc                http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">     <!-- 让spring扫描 com.ts.controller下的注解--><context:component-scan base-package="com.ts.controller"></context:component-scan>         <!-- 配置SpringMVC的视图渲染器, 让其前缀为:/page/ 后缀为.jsp  将视图渲染到/page/<method返回值>.jsp中 -->     <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">        <property name="prefix" value="/"/>         <property name="suffix" value=".jsp"/>    </bean>     </beans>

5.编写controller.java类

package com.ts.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;@Controllerpublic class TestController {@RequestMapping("/message")public ModelAndView message(){String str = "羊駝先生";return new ModelAndView("message","str",str);}}

6.编写两个JSP文件

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <base href="<%=basePath%>">        <title>My JSP 'index.jsp' starting page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0">    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page">  </head>  <script type="text/javascript">  function test(){  window.location.href="http://localhost:8080/testSpringMvc/message";  }  </script>  <body>    <input type="button" value="测试" onclick="test()">  </body></html>

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <base href="<%=basePath%>">        <title>My JSP 'index.jsp' starting page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0">    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">-->  </head>    <body>   ${str}下午好!  </body></html>

然后再上页面效果图:

好了基本就是这样完成了

(里面很有多细节上的东西,如果要是报错了大家就动手查一下,这样会让自己加深印象,别忘了将错误记录下来哈!)





0 0