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/xml/ns/javaee"  
        xmlns:xsi="http://www.w3/2001/XMLSchema-instance"  
        xsi:schemaLocation="http://java.sun/xml/ns/javaee   
        http://java.sun/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/schema/beans"    
    xmlns:xsi="http://www.w3/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework/schema/p"    
    xmlns:context="http://www.springframework/schema/context"    
    xmlns:mvc="http://www.springframework/schema/mvc"    
    xsi:schemaLocation="     
           http://www.springframework/schema/beans     
           http://www.springframework/schema/beans/spring-beans-3.0.xsd     
           http://www.springframework/schema/context     
           http://www.springframework/schema/context/spring-context-3.0.xsd    
           http://www.springframework/schema/mvc     
           http://www.springframework/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;

@Controller
public 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="测试" οnclick="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>

然后再上页面效果图:

好了基本就是这样完成了

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





更多推荐

SpringMvc菜鸟详解