SpringMvc菜鸟详解

1、引言

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

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

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

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

优点:

进行更加简洁的web层开发

天生可以和spring集成

支持灵活的URL映射

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

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

提供了强大的jsp标签库

对静态资源支持

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

2、SpringMVC请求处理流程!

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

SpringMvc菜鸟详解_第1张图片

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

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

SpringMvc菜鸟详解_第2张图片

两张图我们可以看出他的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包,累赘就累赘点吧,大家将就着看,还是很适合新手的!

上图:

SpringMvc菜鸟详解_第3张图片


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

1.新建一个web项目

SpringMvc菜鸟详解_第4张图片

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

3. 编写web.xml文件

  
      
          
          
          
          
          
            springMVC  
            org.springframework.web.servlet.DispatcherServlet  
           
          
      
          
          
            springMVC  
            /  
          
      
          
            index.jsp  
          
      
      
      

4.编写springMVC-servlet.xml


 
    
	     
     
    
         
        
    
     

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+"/";
%>



  
    
    
    My JSP 'index.jsp' starting page
	
	
	    
	
	
	
  
  
  
    
  


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>



  
    
    
    My JSP 'index.jsp' starting page
	
	
	    
	
	
	
  
  
  
   	${str}下午好!
  


然后再上页面效果图:

SpringMvc菜鸟详解_第5张图片

SpringMvc菜鸟详解_第6张图片

好了基本就是这样完成了

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





你可能感兴趣的:(springMVC)