zoukankan      html  css  js  c++  java
  • springmvc(一) springmvc框架原理分析和简单入门程序

          springmvc这个框架真的非常简单,感觉比struts2还更简单,好好沉淀下来学习~

                          --WZY

    一、什么是springmvc?

          我们知道三层架构的思想,并且如果你知道ssh的话,就会更加透彻的理解这个思想,struts2在web层,spring在中间控制,hibernate在dao层与数据库打交道,而前面刚写的mybatis跟hibernate一样,与数据库打交道在dao层的另一个框架,而今天所要讲解的springmvc是在web层的另一个框架。

          springmvc全名是spring web mvc,springmvc是spring的一个模块,并且看名字即可知道,springmvc是一个基于mvc设计模式的前端web框架。

          mvc:m(model模型)、v(view视图)、c(control控制)

          mvc的运用概念图

              

    二、springmvc的入门程序

          通过这个来快速了解springmvc大概的开发流程,其实通过上面的mvc分析图,差不多就知道了如何开发了。重点就是三步。

            1、在web.xml中配置一个serlvet,用来控制,

            2、编写一个handler(controller)类,用来做业务处理。

            3、编写jsp或者别的视图,用来展示数据

          思路已经有了,那么就开始编写把。

          问题描述:使用springmvc来完成前端请求的处理

          2.1、创建web工程

              

          2.2、添加jar包

              

          2.3、编程步骤

            前面三步只是通过mvc图的分析出最关键的三步,其中实现的时候步骤应该更多,比如spring的配置文件,但关键的重点还是那三个。

            1、创建po类

            2、配置前端控制器,DispatcherServlet

            3、创建springmvc的配置文件

            4、开发handler(controller)

            5、在springmvc的配置文件中(取名为springmvc.xml)配置handler

            6、开发jsp或者别的视图

            8、部署测试

          2.4、创建po类

              

                

          2.5、配置前端控制器

              

     1   <!-- springmvc 的前端控制器 -->
     2   <servlet>
     3       <servlet-name>springmvc</servlet-name>
     4       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
     5   <!-- 指定springmvc的配置文件的地址 -->
     6       <init-param>
     7           <param-name>contextConfigLocation</param-name>
     8           <param-value>classpath:springmvc.xml</param-value>
     9       </init-param>
    10   </servlet>
    11   <servlet-mapping>
    12       <servlet-name>springmvc</servlet-name>
    13       <!-- 这里有三种配置url-pattern方案
    14           1、*.do:后缀为.do的请求才能够访问到该servlet[用这个]
    15           2、/ :所有请求都能够访问到该servlet(除jsp),包括静态请求(处理会有问题,不用)
    16           3、/* :有问题,因为访问jsp也会到该servlet,而访问jsp时,我们不需要这样,也不用
    17        -->
    18       <url-pattern>*.do</url-pattern>
    19   </servlet-mapping>
    前端控制器的配置

          2.6、创建springmvc的配置文件

            在config目录下,创建springmvc.xml文件

               

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
            http://www.springframework.org/schema/mvc 
            http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context-3.2.xsd 
            http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 
            http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
    
    </beans>
    springmvc.xml

          2.7、开发handler(controller)类,也就是处理业务逻辑的类

          2.8、在springmvc.xml中配置handler类,也就是spring帮我们创建该类的实例,所以需要配置

            注意:2.7和2.8一起讲解,因为开发handler类讲解三种方式,所以配置也连在一起讲解,以免分开来,看不清楚

            Springmvc开发handler有多种方式,我们只讲解三种:实现HttpRequestHandler接口、实现Controller接口、使用注解开发(掌握)               

            实现HttpRequestHandler接口

              

     1 package com.wuhao.springmvc.controller;
     2 
     3 import java.io.IOException;
     4 import java.util.ArrayList;
     5 import java.util.List;
     6 
     7 import javax.servlet.ServletException;
     8 import javax.servlet.http.HttpServletRequest;
     9 import javax.servlet.http.HttpServletResponse;
    10 
    11 import org.springframework.web.HttpRequestHandler;
    12 
    13 import com.wuhao.springmvc.domain.Items;
    14 
    15 public class ItemController implements HttpRequestHandler {
    16 
    17     @Override
    18     public void handleRequest(HttpServletRequest request, HttpServletResponse response)
    19             throws ServletException, IOException {
    20         //获取商品列表(用静态数据模拟)
    21                 List<Items> itemsList = new ArrayList<Items>();
    22                 
    23                 Items items_1 = new Items();
    24                 items_1.setName("联想笔记本 HttpRequestHandler");
    25                 items_1.setPrice(6000f);
    26                 items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
    27 
    28                 Items items_2 = new Items();
    29                 items_2.setName("苹果手机");
    30                 items_2.setPrice(5000f);
    31                 items_2.setDetail("iphone6苹果手机!");
    32 
    33                 itemsList.add(items_1);
    34                 itemsList.add(items_2);
    35 
    36                 //把商品数据放到request域中
    37                 request.setAttribute("itemsList", itemsList);
    38                 //指定视图
    39                 request.getRequestDispatcher("/WEB-INF/jsp/items/itemsList.jsp").forward(request, response);
    40 
    41     }
    42 
    43 }
    实现HttpRequestHandler接口

            springmvc.xml中配置该处理器

              通过localhost:8080/项目名/queryItems01.do 就能够访问到DispatcherSerlvet,该servlet就会帮我们找到你对应的处理器(依据就是通过下面的这行配置,queryItems01对应了一个处理器的class,也就能够找到)

                

    1         <!-- 配置实现HttpRequestHander接口的处理器 -->
    2         <bean name="/queryItems01.do" class="com.wuhao.springmvc.controller.ItemController"></bean>
    配置实现HttpRequestHander接口的处理器

            实现Controller接口        

              

     1 package com.wuhao.springmvc.controller;
     2 
     3 import java.util.ArrayList;
     4 import java.util.List;
     5 
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 
     9 import org.springframework.web.servlet.ModelAndView;
    10 import org.springframework.web.servlet.mvc.Controller;
    11 
    12 import com.wuhao.springmvc.domain.Items;
    13 
    14 public class ItemController02 implements Controller {
    15 
    16     @Override
    17     public ModelAndView handleRequest(HttpServletRequest request,
    18             HttpServletResponse response) throws Exception {
    19         //获取商品列表(用静态数据模拟)
    20                 List<Items> itemsList = new ArrayList<Items>();
    21                 
    22                 Items items_1 = new Items();
    23                 items_1.setName("联想笔记本 Controller");
    24                 items_1.setPrice(6000f);
    25                 items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
    26 
    27                 Items items_2 = new Items();
    28                 items_2.setName("苹果手机");
    29                 items_2.setPrice(5000f);
    30                 items_2.setDetail("iphone6苹果手机!");
    31 
    32                 itemsList.add(items_1);
    33                 itemsList.add(items_2);
    34                 
    35                 //实现Controller接口的话,就必须使用MoldeAndView对象来将数据装载到对应的jsp视图上,然后返回该对象即可
    36                 //所以需要两步,将数据给该对象,将指定的视图在交给该对象,最后返回该对象即可。
    37                 ModelAndView mv = new ModelAndView();
    38                 //类似于request.setAttribute("itemsList", itemsList);
    39                 mv.addObject("itemsList", itemsList);
    40                 
    41                 //指定视图
    42                 mv.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
    43                 
    44                 return mv;
    45 
    46     }
    47 
    48 }
    实现Controller接口

            配置该handler类

              

            <!-- 配置实现Controller接口的处理器 -->
            <bean name="/queryItems02.do" class="com.wuhao.springmvc.controller.ItemController02"></bean>
    实现Controller接口的配置

            使用注解开发

              

            注解的配置,就是配置一个扫描器,扫描使用了注解的地方

              

            <!-- 使用注解的handle,则需要配置组件扫描器,加载handler
                base-package:指定要扫描的包
             -->
            <context:component-scan 
            base-package="com.wuhao.springmvc.controller"
            ></context:component-scan>
    注解的配置,扫描器

                

          2.9、开发jsp

            在WEB-INF/jsp/items/下创建jsp:itemsList.jsp

              

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix="fmt"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>查询商品列表</title>
    </head>
    <body> 
    <form action="${pageContext.request.contextPath }/item/queryItem.action" method="post">
    查询条件:
    <table width="100%" border=1>
    <tr>
    <td><input type="submit" value="查询"/></td>
    </tr>
    </table>
    商品列表:
    <table width="100%" border=1>
    <tr>
        <td>商品名称</td>
        <td>商品价格</td>
        <td>生产日期</td>
        <td>商品描述</td>
        <td>操作</td>
    </tr>
    <c:forEach items="${itemsList }" var="item">
    <tr>
        <td>${item.name }</td>
        <td>${item.price }</td>
        <td><fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/></td>
        <td>${item.detail }</td>
        
        <td><a href="${pageContext.request.contextPath }/editItems.do?id=${item.id}">修改</a></td>
    
    </tr>
    </c:forEach>
    
    </table>
    </form>
    </body>
    
    </html>
    itemList.jsp

          2.10、部署测试

            测试上面三种采用不同的方式编写的处理类。能够成功访问即成功

    三、springmvc框架原理图分析

          前面了解了springmvc的mvc设计模式的运用并且还编写了一个简单的实例,关键点就几个,配置DispatcherServlet,编写处理类以及配置,jsp,就mvc的三个关键点,但是这也是粗略的使用一下springmvc,并不知道其中运行的原理,比如

            springmvc是如何找到处理器的?

            springmvc如何执行处理器的?

            springmvc如何查找到视图对象的?

          看图即可

              

            1、发起请求到前端控制器(DispatcherServlet),该控制器中就会过滤出你哪些请求可以访问该servlet哪些不可以,就是url-pattern的作用,并且会加载springmvc.xml配置文件

            2、前端控制器会找到HandlerMapping(处理器映射器),通过HandlerMapping完成url到controller映射的组件,通俗点讲,就是将在springmvc.xml中配置的或者注解的url与对应的处理类找到并进行存储,实际上是用一个map集合来保存这种映射关系,map<url,handler>; 这样,就将所有的这种映射关系都记录保存了下来

            3、通过HandlerMapping有了这些映射关系,并且找到了url对应的处理器,HandlerMapping就会将其处理器(图中红色标明的handler)返回,在其返回之前,在加上很多的拦截器,其作用后面

    进行讲解,这里知道在返回的处理器前会有很多的拦截器即可。

            4、DispatcherServlet拿到了handler之后,找到HandlerAdapter(处理器适配器),通过它来访问处理器,并且执行处理器。

              这里会有人会有疑惑,为什么需要处理器适配器,我们都获得了处理类了,直接调用不就行了吗?

                不行,因为我们只知道处理类在哪里,并不知道执行处理类中的哪个方法,其实也就是不知道处理类是通过哪种方式创建出来的,实现HttpRequestHandler?还是注解方式,或者是           其他方式,我们不知道,所以需要HandlerAdapter来帮我们确认调用哪个方法。

            5、执行处理器

            6、处理器会返回一个ModelAndView对象给HandlerAdapter

            7、通过HandlerAdapter将ModelAndView对象返回给前端控制器(DispatcherServlet)

            8、前端控制器请求视图解析器(ViewResolver)去进行视图解析,根据逻辑视图名解析成真正的视图(jsp),其实就是将ModelAndView对象中存放视图的名称进行查找,找到对应的页面形成视图对象

            9、返回视图对象到前端控制器。

            10、视图渲染,就是将ModelAndView对象中的数据放到request域中,用来让页面加载数据的。

            11、通过第8步,通过名称找到了对应的页面,通过第10步,request域中有了所需要的数据,那么就能够进行视图渲染了。最后将其返回即可。

          通过上面的图和分析过程,就能够完美解答上面的三个问题了。理解了图,那么springmvc就会用了。很简单把,跟struts2差不多,记住原理图即可。

    四、组件分析(默认组件和手动配置组件)

          通过图可以看到

            前端控制器:对其他组件进行解耦,这样就增加了组件的可扩展性 无需开发直接配置      

            处理器映射器:无需开发,直接用,作用见上面

            处理器适配器:无需开发

            处理器:需要开发,方式很多

            视图解析器:无需开发

            视图:需要开发

          就这么点东西,真正需要写的就两个(处理器+视图)和一个配置(前端控制器),就是mvc中的三个重点,在第二小节中就是这样编写的,第三小结就是解释其中的原理。

          处理器映射器、处理器适配器、视图解析器这三个是默认配置的,在下面位置中可以查看

              

          DispatchServlet.properties

                     

          上面是使用默认的,如果没有配置这几个组件,那么就使用默认的,我们也可以手动指定。

          4.1、非注解的处理器映射器和处理器适配器  [看看即可]

            BeanNameUrlHandlerMapping:映射器    

               在springmvc配置文件中,配置BeanNameUrlHandlerMapping

                       

               他的作用是找到在springmvc.xml中配置的url和处理器的bean 

                

             HttpRequestHandlerAdapter:适配执行实现了HttpRequestHandler接口的处理类的方法

               在springmvc配置文件中,配置HttpRequestHandlerAdapter 

                

               它的作用就是适配实现了HttpRequestHandler接口的处理类,也就是找到该处理类对应的方法

                如何适配,就是需要看源码了,可以百度一下讲解该适配器的源码。

            SimpleControllerHandlerAdapter:适配执行实现了Controller接口的处理类的方法

              在springmvc配置文件中,配置SimpleControllerHandlerAdapter

                

          总结:这就是非注解的组件的配置方式,很简单,注意

             处理器映射器和处理器适配器可以配置多个

             处理器映射器和处理器适配器可以混用

        

          

          4.2、配置注解的处理器映射器和适配器(掌握)

            org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping 是在spring3.1之前使用的注解映射器        

            org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping是在spring3.1之后使用的注解映射器

            org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter 是在spring3.1之前使用的注解适配器

            org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter是在spring3.1之后使用的注解配置器

            注意:

            1、注解方式的映射器和适配器在3.1版本前后是不一样的,使用3.1之后的

            2、注解方式的处理器映射器和处理器适配器必须配对使用,不能与非注解的处理器映射器和适配器混用(用了注解的就不能在配置非注解的,二选一)

            配置方式有两种:

              1、使用bean标签配置

                

              2、使用mvc标签(推荐)

                

          4.3、视图解析器

            4.3.1、JSP视图解析器(默认的就是使用该解析器)

                

              其中两个配置的意思是:prefix:前缀    suffix:后缀  。 配置之后在指定视图时,就不用写这前缀和后缀了,直接写关键代码即可。看下图

                

              虽然指定视图只写 items/itemsList  但是会帮我们加上我们配置的前缀和后缀,也就是变为了 /WEB-INF/jsp/items/itemsList.jsp

            4.3.2 Freemarker视图解析器

                org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver 

                等什么时候使用到了在学习把。

    五、requestMapping注解的三种功能

          requestMapping有三种功能:映射请求url、窄化请求、限制请求方法

          5.1、映射请求url

            也就是写在方法上,上面我们已经用过了这种功能,这里详细讲解一下

            @RequestMapping(value="/item,/user")或@RequestMapping("/item”) value是数组,可以将多个url映射到同一个方法上,用逗号隔开即可。如果value中只有一个属性,则可以省去value,就像这样:@RequestMapping(value="/item ")写成@RequestMapping("/item”)

          5.2、窄化请求

            在class上面加上requestmapping注解,可以对url进行分类管理,这样也实现了请求的窄化 

              加在class上       

                

              加在方法上

                 

              访问路径为:http://localhost:8080/xxx/items/queryItems.do

          5.3、限制请求方法

            限制访问该方法必须是get或者post方式,相当于对请求进行过滤。

              限定GET方法,也就是只能允许get请求方式过来的请求访问

                @RequestMapping(method = RequestMethod.GET)

                

                 如果post请求方式的过来访问,则报错 HTTP Status 405 - Request method 'POST' not supported

                  

              限定post方法。

                @RequestMapping(method = RequestMethod.POST)

                

                如果get请求方式过来访问,报错  HTTP Status 405 - Request method 'GET' not supported

              get、post都可以

                @RequestMapping(method={RequestMethod.GET,RequestMethod.POST})

                

              

    六、controller类中的方法返回值问题

          同样有三种:ModelAndView对象、void、String

          6.1、返回ModelAndView对象

            controller方法中定义ModelAndView对象并返回,对象中可添加model数据、指定view。 然后通过视图解析器对其进行解析。上面用的就是这个。不用在过多的解释了

          6.2、void

            如果返回值为void的时候,可以在controller方法形参上定义request和response,使用request或response指定响应结果(这里在形参上定义request和response,还没讲到。但是可以这样用,相当于controller方法上默认有这两个形参。加上去就可以使用)

            使用request转向页面,如下

              request.getRequestDispatcher("页面路径").forward(request, response)

            通过response页面重定向

              response.sendRedirect("url")

            可以通过response指定响应结果,例如响应json数据如下

              response.setCharacterEncoding("utf-8");

              response.setContentType("application/json;charset=utf-8");

              response.getWriter().write("json串");

          6.3、String

            使用一:返回逻辑视图

              

            解释:形参中有Model对象,该对象也是默认形参,只要声明了,就可以拿过来用,该Model对象的作用就是添加属性到request作用域中的,就跟ModelAndView对象添加值到request作用域中一样,只是model对象不能够指定视图。正好其model就是modelAndView的一半,很好理解。 其次,因为没有采用modelAndView对象,所以不能够指定视图,但是可以直接返回视图地址即可,效果是跟使用modelAndView对象一样的。

            

            使用二:请求转发

              

  • 相关阅读:
    BEM(Block–Element-Modifier)
    http://element.eleme.io/#/zh-CN/component/quickstart
    Commit message 的写法规范。本文介绍Angular 规范(
    好的commit应该长啥样 https://github.com/torvalds/linux/pull/17#issuecomment-5654674
    代码管理
    if you have content fetched asynchronously on pages where SEO is important, SSR might be necessary
    Martin Fowler’s Active Record design pattern.
    The Zen of Python
    Introspection in Python How to spy on your Python objects Guide to Python introspection
    Object-Oriented Metrics: LCOM 内聚性的度量
  • 原文地址:https://www.cnblogs.com/whgk/p/7152732.html
Copyright © 2011-2022 走看看