zoukankan      html  css  js  c++  java
  • spring MVC框架入门(外加SSM整合)

    spring MVC框架

    一、什么是spring MVC

      Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架,如Struts1(现在一般不用),Struts2等。

                                                                       ---------百度百科

      从spring官网中可以看出,Spring MVC原名叫Spring Web MVC,它是构建在Servlet API上的最初的Web框架,从一开始就包含在Spring框架中。正式名称“Spring Web MVC”来自其源模块spring-webmvc的名称, 但它通常被称为“Spring MVC”。Spring web mvcStruts2都属于表现层的框架,它是Spring框架的一部分。

    二、spring MVC框架的作用

      从请求中接收传入的参数,将处理后的结果返回给页面展示

    三、spring MVC执行流程

      

    1)、 用户发送请求至前端控制器DispatcherServlet

    2)、 DispatcherServlet收到请求调用HandlerMapping处理器映射器。

    3)、 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

    4)、 DispatcherServlet通过HandlerAdapter处理器适配器调用处理器

    5)、 执行处理器(Controller,也叫后端控制器)。

    6)、 Controller执行完成返回ModelAndView

    7)、 HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet

    8)、 DispatcherServlet将ModelAndView传给ViewReslover视图解析器

    9)、 ViewReslover解析后返回具体View

    10)   DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。

    11)   DispatcherServlet响应用户

    四、快速开发

    需求:显示商品列表

    1、导入所需基本依赖jar包

     jar包下载地址:springMVC_jar

     如果是maven。其相关依赖为

    <dependencies>
            <dependency>
                <!--使用Junit4,采用注解形式 -->
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.11</version>
                <scope>test</scope>
            </dependency>
            <!--数据库驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.38</version>
                <!--配置maven工作范围:因为驱动只有真正工作时才会启动 -->
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>c3p0</groupId>
                <artifactId>c3p0</artifactId>
                <version>0.9.1.2</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
                <scope>provided</scope>
            </dependency>
    
            <!--spring依赖 -->
            <!--1.spring核心依赖 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>4.1.7.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>4.1.7.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>4.1.7.RELEASE</version>
            </dependency>
            <!--2.spring Dao层依赖 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>4.1.7.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>4.1.7.RELEASE</version>
            </dependency>
            <!--3.spring web相关依赖:用于当启动服务器时加载配置文件 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>4.1.7.RELEASE</version>
            </dependency>
            <!--用于springMVC需要 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>4.1.7.RELEASE</version>
            </dependency>
            <!--4.spring test测试相关依赖 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>4.1.7.RELEASE</version>
            </dependency>
        </dependencies>

    2、在项目工程上创建源码包,用来存放配置文件

    3、创建spring MVC核心配置文件,文件名就叫SpringMvc.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:dubbo="http://code.alibabatech.com/schema/dubbo"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
            http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">         
    </beans>

    4、创建日志文件,用于打印日志(log4j.properties)

    # Global logging configuration
    log4j.rootLogger=DEBUG, stdout
    # Console output...
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

    5、定义Controller类

      ItemController是一个普通的java类,不需要实现任何接口,只需要在类上添加@Controller注解即可。@RequestMapping注解指定请求的url,其中“.action”可以加     也可以不加。注意:1.这里的配置@Controller注解 2.@RequestMapping用于识别域名后缀 3.modelAndView.setViewName用于设置跳转页面

    // 在添加注解的同时,还得配置扫描
    @Controller
    public class ItemsController {
        //指定url到请求方法的映射
        //url中输入一个地址,例如:localhost:8888/SpringMvc/list.action
        //用以替代了struts中采用的配置文件进行匹配来调用那个方法从而识别跳转那个页面
       @RequestMapping("/list")   
       public ModelAndView itemsList()throws Exception{
           List<Items> itemList = new ArrayList<Items>();
            
            //商品列表
            Items items_1 = new Items();
            items_1.setName("联想笔记本_3");
            items_1.setPrice(6000f);
            items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
            
            Items items_2 = new Items();
            items_2.setName("苹果手机");
            items_2.setPrice(5000f);
            items_2.setDetail("iphone6苹果手机!");
            
            itemList.add(items_1);
            itemList.add(items_2);
            //模型视图
            //model模型:模型对象中存放了返回给页面的数据
            //view视图:视图对象中指定给返回的页面的位置
            //创建modelandView对象
            ModelAndView modelAndView = new ModelAndView();
            //添加model(将返回给页面的数据放入模型和视图对象中)
            modelAndView.addObject("itemList", itemList);
            //添加视图(指定给 返回页面的位置)
            modelAndView.setViewName("jsp/itemList.jsp");
            return modelAndView;
        }
       }

    6、在SpringMvc.xml中配置注解扫描

      这里controller类是创建在cn.clj.controller包下的

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-4.1.xsd
                http://www.springframework.org/schema/mvc
                http://www.springframework.org/schema/mvc/spring-mvc.xsd">
            <context:component-scan base-package="com.clj.controller"/>            
            <mvc:annotation-driven></mvc:annotation-driven>
    </beans>

    7、在web.xml中配置前端控制器

      注意:指定核心配置文件名不能写错,否则会找不到Controller类

    <!-- springMvc前端控制器 -->
      <servlet>
         <servlet-name>springMvc</servlet-name>
         <!--路径:spring-webmvc-4.1.3.RELEASE.jarorg.springframework.web.servlet  -->
         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
         <!-- 如果没有指定springMvc核心配置文件那么默认会去找/WEB_INF/+<servlet-name>的内容+  -servlet.xml配置文件 -->
         <!-- 指定springMvc核心配置文件位置 -->
         <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:SpringMvc.xml</param-value>
         </init-param>
         <!-- tomcat启动时就加载这个servlet -->
         <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
         <servlet-name>springMvc</servlet-name>
         <url-pattern>*.action</url-pattern>
      </servlet-mapping>

      DispatcherServlet的路径为:

     

    8、配置jsp

     在WebRoot下创建jsp文件夹,用来存放jsp

      1.需引入jstl标签   2.因为传的是itemList,接收值不能写错

    <%@taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>

    <body> <form action="${pageContext.request.contextPath }/search.action" method="post"> 查询条件: <table width="100%" border=1> <tr> <!-- 如果controller接受的是vo,那么页面上input框中name属性值要等于vo属性.属性 (..)进行引用--> <td>商品名称:<input type="text" name="items.name"/></td> <td>商品价格:<input type="text" name="items.price"/></td> <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="${itemList}" 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 }/itemEdit.action?id=${item.id}">修改</a></td> </tr> </c:forEach> </table> </form>

    9、测试

      此时在浏览器中输入http://localhost:8080/项目名/list.action,如果成功跳转到显示页面为成功

    二、关于注解处理器映射器和注解处理器适配器

      注解式处理器映射器注解式处理器映射器,对类中标记@ResquestMapping的方法进行映射,根据ResquestMapping定义的url匹配ResquestMapping标记的方法,匹配成功返回HandlerMethod对象给前端控制器,HandlerMethod对象中封装url对应的方法Method

      注解式处理器适配器:注解式处理器适配器,对标记@ResquestMapping的方法进行适配。

      方式一:手动配置最新版本的映射器和适配器(缺点:随着版本更新的重新配置)

     <!-- 配置最新版的注解的处理器映射器 -->
             <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
             <!-- 配置最新版的注解的处理器适配器 -->
             <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>

      方式二:自动配置

    <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

      全部代码如下

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.1.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc.xsd">

            <!-- 配置@Controller注解扫描 -->
            <context:component-scan base-package="cn.clj.controller"/>
            
            <!-- 如果没有显示配置处理器映射器和处理器适配器那个springMvc会默认的dispatcherServlet.properties中查找
            对应的处理器映射器和处理器适配器去使用,每个请求都要扫描一次的默认配置文件,效率非常低,会降低访问速度,所以显示的配置处理器映射器和处理器适配器
             -->
             <!-- 注解形式的处理器适配器
             <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/> -->
             <!-- 注解形式的处理器映射器 
             <bean class="org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver"/>-->
             <!-- 配置最新版的注解的处理器映射器,以上已经过时
             <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>-->
             <!-- 配置最新版的注解的处理器适配器 
             <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>-->
             <!-- 注解驱动:能够自动配置最新版的处理器映射器和处理器适配器 -->
             <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
           
    </beans>

    三、关于视图解析器

    1.分析情形

     在controller中,每次配置跳转页面时,都要配置跳转视图的全部路径,有点麻烦

    2、配置视图解析器

     功能:在配置文件中配置全局跳转视图的前缀名和后缀名,在controller类只要写省去后缀的jsp名即可,配置如下:

     1)在SpringMvc.xml文件中配置视图解析器

          <!-- 配置视图解析器 -->
             <!-- 作用:在controller中指定页面路径的时候就不用写页面的完整路径名称,直接写去掉后缀的页面名 -->
             <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                 <!--真正页面路径=前缀+页面名称+后缀  -->
                 <!-- 跳转视图前缀 -->
                 <property name="prefix" value="/jsp/"></property>
                 <!-- 跳转视图后缀 -->
                 <property name="suffix" value=".jsp"></property>
          </bean>

     2)更改conroller类中的写法

            //添加视图(指定给 返回页面的位置)
           // modelAndView.setViewName("jsp/itemList.jsp");
            modelAndView.setViewName("itemList");    
            return modelAndView;

    四、SSM整合

          个人认为,SpringMvc与Mybatis整合其实就是SSM整合,因为Spring与SpringMvc同属于一家公司,无需整合,当然也需要用到Spring的IOC特性业务分配:此时控制层交给SpringMvc,持久层交给MyBatis,创建管理交给Spring

    思路:

    Dao层:

    1、SqlMapConfig.xml,空文件即可。需要文件头。
    
    2、applicationContext-dao.xml。
    
    a) 数据库连接池
    
    b) SqlSessionFactory对象,需要spring和mybatis整合包下的。
    
    c) 配置mapper文件扫描器。

    Service层:

    1、applicationContext-service.xml包扫描器,扫描@service注解的类。
    
    2、applicationContext-trans.xml配置事务。

    表现层:

    Springmvc.xml
    
    1、包扫描器,扫描@Controller注解的类。
    
    2、配置注解驱动。
    
    3、视图解析器
    
    Web.xml
    
    配置前端控制器。

    1、快速部署环境

     1)导入相应的依赖jar包

    此包含Mybatis依赖jar包与逆向工程依赖jar包、Spring依赖jar包与Spring-mybatis整合包、SpringMVc依赖包,数据库驱动包,第三方连接池

     

       

     2)在工程项目下(非src)创建源码包,用来存放配置文件,包名为config

     3)创建分层包,采用MVC模式开发,每个包的业务不同

     

     4)创建db.properties

    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://192.168.174.132:3306/SSM
    jdbc.username=root
    jdbc.password=root

     5)配置log4j.properties

    # Global logging configuration
    log4j.rootLogger=DEBUG, stdout
    # Console output...
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

     6)创建spring核心配置文件之applicationContext-dao.xml

      此文件用来管理dao层业务:配置数据源,配置SqlSessionFactory与dao层mapper扫描

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
    
        <!-- 加载配置文件 -->
        <context:property-placeholder location="classpath:db.properties"/>
        <!-- 数据库连接池 -->
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
            destroy-method="close">
            <property name="driverClassName" value="${jdbc.driver}"/>
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
            <property name="maxActive" value="10"/>
            <property name="maxIdle" value="5"/>
        </bean>
        <!-- mapper配置 -->
        <!-- 让spring管理sqlsessionfactory 使用mybatis和spring整合包中的 -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <!-- 数据库连接池 -->
            <property name="dataSource" ref="dataSource"/>
            <!-- 加载mybatis的全局配置文件 -->
            <property name="configLocation" value="classpath:SqlMapConfig.xml"/>
        </bean>
        <!-- 配置Mapper扫描器 -->
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="cn.clj.dao"/>
        </bean>
    
    </beans>

     7)创建spring核心配置文件之applicationContext-service.xml

      此文件主要是负责业务层:开启service注解扫描

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/util 
        http://www.springframework.org/schema/util/spring-util-4.0.xsd">
        <!-- @service扫描 -->
        <context:component-scan base-package="cn.clj.service"></context:component-scan>
        
    </beans>

     8)创建spring核心配置文件之applicationContext-transaction.xml

      此文件主要负责事务:配置事务管理并注入数据源,配置事务通知与切面

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
    
        <!-- 事务管理器 -->
        <bean id="transactionManager"
            class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <!-- 数据源 -->
            <property name="dataSource" ref="dataSource" />
        </bean>
        
        <!-- 通知 -->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <!-- 传播行为 -->
                <tx:method name="save*" propagation="REQUIRED" />
                <tx:method name="insert*" propagation="REQUIRED" />
                <tx:method name="delete*" propagation="REQUIRED" />
                <tx:method name="update*" propagation="REQUIRED" />
                <tx:method name="find*" propagation="SUPPORTS" read-only="true" />
                <tx:method name="get*" propagation="SUPPORTS" read-only="true" />
            </tx:attributes>
        </tx:advice>
        
        <!-- 切面 -->
        <aop:config>
            <aop:advisor advice-ref="txAdvice"
                pointcut="execution(* cn.clj.service.*.*(..))" />
        </aop:config>
        
    </beans>

      9)创建SpringMvc核心配置文件之SpringMvc.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:dubbo="http://code.alibabatech.com/schema/dubbo"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
            http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
            <!-- 配置@Controller注解扫描 -->
            <context:component-scan base-package="cn.clj.controller"/>
            
             <!-- 注解驱动:能够自动配置最新版的处理器映射器和处理器适配器 -->
             <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
             <!-- 配置视图解析器 -->
             <!-- 作用:在controller中指定页面路径的时候就不用写页面的完整路径名称,直接写去掉后缀的页面名 -->
             <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                 <!--真正页面路径=前缀+页面名称+后缀  -->
                 <!-- 跳转视图前缀 -->
                 <property name="prefix" value="/jsp/"></property>
                 <!-- 跳转视图后缀 -->
                 <property name="suffix" value=".jsp"></property>
             </bean>
             
    </beans>

      10)配置服务器启动扫描

        整合后以上的配置文件,服务器不能自动识别加载,需要在web.xml文件中开启包扫描

      <!-- 开启spring各核心配置文件扫描 -->
      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext-*.xml</param-value>
      </context-param>
      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
      <!-- 开启SpringMVc拦截器-->
      <servlet>
        <servlet-name>SpringMvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 配置SpringMvc核心配置文件所在路径  -->
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:SpringMvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>SpringMvc</servlet-name>
        <url-pattern>*.action</url-pattern>
      </servlet-mapping>

    以上整合环境部署大致完成

    2、整合开发

     需求1:从数据库查询到商品信息,并将数据返回到jsp中

      1)开启逆向工程自动生成pojo类和mapper接口和映射文件

       1.1: 导入逆向工程jar包mybatis-generator-core-1.3.2

       1.2 :在config包下创建generatorConfig.xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE generatorConfiguration
      PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
      "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
    
    <generatorConfiguration>
        <context id="testTables" targetRuntime="MyBatis3">
            <commentGenerator>
                <!-- 是否去除自动生成的注释 true:是 : false:否 -->
                <property name="suppressAllComments" value="true" />
            </commentGenerator>
            <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
            <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                connectionURL="jdbc:mysql://192.168.174.132:3306/SSM" userId="root"
                password="root">
            </jdbcConnection>
            <!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
                connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg" 
                userId="yycg"
                password="yycg">
            </jdbcConnection> -->
    
            <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 
                NUMERIC 类型解析为java.math.BigDecimal -->
            <javaTypeResolver>
                <property name="forceBigDecimals" value="false" />
            </javaTypeResolver>
    
            <!-- targetProject:生成PO类的位置 -->
            <javaModelGenerator targetPackage="cn.clj.pojo"
                targetProject=".src">
                <!-- enableSubPackages:是否让schema作为包的后缀 -->
                <property name="enableSubPackages" value="false" />
                <!-- 从数据库返回的值被清理前后的空格 -->
                <property name="trimStrings" value="true" />
            </javaModelGenerator>
            <!-- targetProject:mapper映射文件生成的位置 -->
            <sqlMapGenerator targetPackage="cn.clj.dao" 
                targetProject=".src">
                <!-- enableSubPackages:是否让schema作为包的后缀 -->
                <property name="enableSubPackages" value="false" />
            </sqlMapGenerator>
            <!-- targetPackage:mapper接口生成的位置 -->
            <javaClientGenerator type="XMLMAPPER"
                targetPackage="cn.clj.dao" 
                targetProject=".src">
                <!-- enableSubPackages:是否让schema作为包的后缀 -->
                <property name="enableSubPackages" value="false" />
            </javaClientGenerator>
            <!-- 指定数据库表 -->
            <table tableName="items"></table>
            <table tableName="user"></table>
            <!-- <table schema="" tableName="sys_user"></table>
            <table schema="" tableName="sys_role"></table>
            <table schema="" tableName="sys_permission"></table>
            <table schema="" tableName="sys_user_role"></table>
            <table schema="" tableName="sys_role_permission"></table> -->
            
            <!-- 有些表的字段需要指定java类型
             <table schema="" tableName="">
                <columnOverride column="" javaType="" />
            </table> -->
        </context>
    </generatorConfiguration>

      1.3:创建启动类

      这里需要配置generatorConfig.xml文件所在路径,并运行此类

    package cn.clj.start;
    
    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.mybatis.generator.api.MyBatisGenerator;
    import org.mybatis.generator.config.Configuration;
    import org.mybatis.generator.config.xml.ConfigurationParser;
    import org.mybatis.generator.internal.DefaultShellCallback;
    
    public class StartGenerator {
        public void generator() throws Exception{
            List<String> warnings = new ArrayList<String>();
            boolean overwrite = true;
            File configFile = new File("config/generatorConfig.xml"); 
            ConfigurationParser cp = new ConfigurationParser(warnings);
            Configuration config = cp.parseConfiguration(configFile);
            DefaultShellCallback callback = new DefaultShellCallback(overwrite);
            MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
                    callback, warnings);
            myBatisGenerator.generate(null);
        }
        public static void main(String[] args) throws Exception {
            try {
                StartGenerator startService = new StartGenerator();
                startService.generator();
            } catch (Exception e) {
                e.printStackTrace();
            }
    }
    }

     自动生成的文件

     

    2、定义接口和实现类

    package cn.clj.service;
    
    import java.util.List;
    
    import cn.clj.pojo.Items;
    
    public interface ItemsService {
        public List<Items> list() throws Exception;
    }

     注意:这里注入了Mapper接口,并开启了自动扫描注解

    package cn.clj.service;
    
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import cn.clj.dao.ItemsMapper;
    import cn.clj.pojo.Items;
    import cn.clj.pojo.ItemsExample;
    
    @Service
    public class ItemsServiceImpl implements ItemsService{
        @Autowired
        private ItemsMapper itemsMapper;
    
        @Override
        public List<Items> list() throws Exception {
            //selectByExampleWithBLOBs(example)包含文本类型
            ItemsExample example=new ItemsExample();
            //example.createCriteria()可以创建查询条件;如果无需任何查询条件,直接将example实例化即可
            List<Items>  list=itemsMapper.selectByExampleWithBLOBs(example);
            return list;
        }    
    }

    3、创建conroller类

    @Controller
    public class ItemController {
        //注意:这里可以使用Autowired:自动装配(缺点:当一个接口有两个实现类时就无法世识别)
        //Resource:值是取实现类中定义的注解值
        @Autowired
        private ItemsService itemsService;
        //查询所有
        @RequestMapping("/list")
        public ModelAndView itemsList() throws Exception{
            List<Items> list=itemsService.list();
            ModelAndView modelAndView=new ModelAndView();
            modelAndView.addObject("itemList",list);
            modelAndView.setViewName("itemList");
            return modelAndView;
        }
    }

     4、创建itemList.jsp接受参数

    <%@taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
    <body> 
    <form action="${pageContext.request.contextPath }/search.action" method="post">
    查询条件:
    <table width="100%" border=1>
    <tr>
    <!-- 如果controller接受的是vo,那么页面上input框中name属性值要等于vo属性.属性 (..)进行引用-->
    <td>商品名称:<input type="text" name="items.name"/></td>
    <td>商品价格:<input type="text" name="items.price"/></td>
    <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="${itemList}" 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 }/itemEdit.action?id=${item.id}">修改</a></td>
    
    </tr>
    </c:forEach>
    
    </table>
    </form>
    </body>

     5、测试:http://localhost:8080/项目名/list.action

    五、SpringMvc值参数绑定

     1、关于@RequestParam标签

      1) 使用@RequestParam常用于处理简单类型的绑定

     如:jsp传入一个值

    <input type="text" name="item_id"/>

       controller接收

    public String editItem(@RequestParam(value="item_id",required=true) String id) {
        
    }

    注意:

    1.1 ) value:参数名字,即入参的请求参数名字,形参名称为id,但是这里使用value="item_id"限定请求的参数名为item_id,所以页面传递参数的名必须为item_id。如果请求参数中没有item_id将跑出异常:

    HTTP Status 500 - Required Integer parameter 'item_id' is not present

    1.2)这里通过required=true限定item_id参数为必需传递,如果不传递则报400错误,可以使用defaultvalue设置默认值,即使required=true也可以不传item_id参数值

      2、绑定普通类型

      需求1:打开编辑界面,查看商品详情

      环境:引用以上环境,当触发itemList.jsp中的修改按钮,根据超链接跳转,传入参数为商品id

      1)、编写接口和实现类

    public Items findItemsById(Integer id) throws Exception
    package cn.clj.service;
    
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import cn.clj.dao.ItemsMapper;
    import cn.clj.pojo.Items;
    import cn.clj.pojo.ItemsExample;
    
    @Service
    public class ItemsServiceImpl implements ItemsService{
        @Autowired
        private ItemsMapper itemsMapper;
        @Override
        public Items findItemsById(Integer id) throws Exception {
            Items items=itemsMapper.selectByPrimaryKey(id);
            return items;
        }
    }

     2)、编写controller

      参数通过域名封装到请求中,此时可以在方法中定义HttpServletRequest、HttpSession、Model将参数获得

      注意:这里设置返回页面是个字符串

    package cn.clj.controller;
    
    import java.util.Date;
    import java.util.List;
    
    import javax.annotation.Resource;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.servlet.ModelAndView;
    
    import cn.clj.pojo.Items;
    import cn.clj.service.ItemsService;
    import cn.clj.vo.QueryVo;
    
    @Controller
    public class ItemController {
        //注意:这里可以使用Autowired:自动装配(缺点:当一个接口有两个实现类时就无法世识别)
        //Resource:值是取实现类中定义的注解值
        @Autowired
        private ItemsService itemsService;/**
         * springMvc默认支持的参数类型,也就是说在controller方法中可以加入这些,也可以不加
         * HttpServletRequest
         * HttpServletResponse
         * HttpSession
         * Model
         */
        @RequestMapping("/itemEdit")
        public String itemEdit(HttpServletRequest request,Model model) throws Exception{
            String idStr=request.getParameter("id");
            Items items=itemsService.findItemsById(Integer.parseInt(idStr));
            //Model模型:模型中放入了返回给页面的数据
            //Model底层就是用的request域传递数据,但是对request进行了扩展
            model.addAttribute("item",items);
            //如果springMvc方法返回一个简单的string字符串,那么springMvc就会认为这个字符串就是页面的名称
            return "editItem";
        }
    }

     3)、创建editItem.jsp接受参数

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
      
     <body> 
        <!-- 上传图片是需要指定属性 enctype="multipart/form-data" -->
        <!-- <form id="itemForm" action="" method="post" enctype="multipart/form-data"> -->
        <form id="itemForm"    action="${pageContext.request.contextPath }/updateitem.action" method="post">
            <input type="hidden" name="id" value="${item.id }" /> 修改商品信息:
            <table width="100%" border=1>
                <tr>
                    <td>商品名称</td>
                    <td><input type="text" name="name" value="${item.name }" /></td>
                </tr>
                <tr>
                    <td>商品价格</td>
                    <td><input type="text" name="price" value="${item.price }" /></td>
                </tr>
                <tr>
                    <td>商品简介</td>
                    <td><textarea rows="3" cols="30" name="detail">${item.detail }</textarea>
                    </td>
                </tr>
                <tr>
                    <td colspan="2" align="center"><input type="submit" value="提交" />
                    </td>
                </tr>
            </table>
    
        </form>
    </body>

     绑定pojo类型

     需求2、更新数据

     1)、前提有pojo类(其中在修改界面中的接受的Items 的属性必须与pojo类中的属性保持一致)

    package cn.clj.pojo;
    
    import java.util.Date;
    
    public class Items {
        private Integer id;
    
        private String name;
    
        private Float price;
    
        private String pic;
    
        private Date createtime;
    
        private String detail;
    
        //省略set/get方法
    }

     1)、创建接口和实现类

        public void updateItems(Items items) throws Exception;
    @Service
    public class ItemsServiceImpl implements ItemsService{
        @Autowired
        private ItemsMapper itemsMapper;
    
        @Override
        public void updateItems(Items items) throws Exception {
            // TODO Auto-generated method stub
            //此方法包含大对象文本
            itemsMapper.updateByPrimaryKeyWithBLOBs(items);
        }
        
    }

     2)、创建conroller类定义方法

    @Controller
    public class ItemController {
        //注意:这里可以使用Autowired:自动装配(缺点:当一个接口有两个实现类时就无法世识别)
        //Resource:值是取实现类中定义的注解值
        @Autowired
        private ItemsService itemsService;/**
         * 更新数据 
         * @return
         */
        //1.springMvc可以直接接受基本数据类型,包括string,spring Mvc可以帮你自动进行类型转换
        //controller方法接受的参数的变量名称必须要等于页面上input框的name属性值
        //2.springMvc可以直接接受pojo类型,要求页面上input框的name属性名称必须等于pojo的属性名称
        @RequestMapping("/updateitem")
        public String updateitem(Items items) throws Exception{      //方式二
        //public String updateitem(Integer id,String name,Float price,String detail) throws Exception{   //方式一
    //        Items items=new Items();
    //        items.setId(id);
    //        items.setName(name);
    //        items.setPrice(price);
    //        items.setDetail(detail);
            //注意:这里jsp源代码中屏蔽了接受时间的框,是因为String类型可以转换为基本类型,但是string类型不能转换为Date类型
            items.setCreatetime(new Date());//数据库字段定义为非空
            itemsService.updateItems(items);
            return "success";
        }
    }

     3)、创建success.jsp页面

     <body>
       <h3>更新成功</h3>
      </body>

     解决中文乱码问题

     1)针对post请求

      post请求是封装于服务器端,请求参数不会在域名中出现

      在web.xml中配置过滤器,当服务器启动时就对请求中的参数进行字符编码转换

     <!-- 解决post乱码问题 -->
      <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
          <param-name>encoding</param-name>
          <param-value>utf-8</param-value>
        </init-param>
      </filter>
      <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>

     2)针对get请求

      get请求是响应在地址栏中,通过地址栏可以看到请求参数

      将controller类中接受到的包含中文参数进行字符编码转换

    String name=new String(request.getAttribute("参数名").getBytes("iso-8859-1"),"utf-8")); 

     绑定包装类

     需求3:使用包装类接受高级查询条件中所传过来的值

     1) 定义VO

    package cn.clj.vo;
    
    import java.util.Arrays;
    import java.util.List;
    
    import cn.clj.pojo.Items;
    /**
     * 演示高级查询,封装指定pojo类中的指定属性
     * @author 佳先森
     *
     */
    public class QueryVo {
        //商品对象
        private Items items;
      //省略set/get、toString方法
    }

     2) 定义jsp

    <form action="${pageContext.request.contextPath }/search.action" method="post">
    查询条件:
    <table width="100%" border=1>
    <tr>
    <!-- 如果controller接受的是vo,那么页面上input框中name属性值要等于vo属性.属性 (..)进行引用-->
    <td>商品名称:<input type="text" name="items.name"/></td>
    <td>商品价格:<input type="text" name="items.price"/></td>
    <td><input type="submit" value="查询"/></td> </tr> </table>

     3) controller类中定义方法

    @Controller
    public class ItemController {
    //如果controller接受的是vo,那么页面上input框中name属性值要等于vo属性.属性 (..)进行引用
        @RequestMapping("/search")
        public String search(QueryVo vo) throws Exception{
            System.out.println(vo);
            return "";
        }

     自定义参数绑定

     需求:接受参数为时间格式

     分析:为什么输入框为时间格式的conroller接收时会报错呢,是因为spring MVC能够将自动将字符串转换为原始型和包装类型,但是它不能讲时间格式的转换为字符串(时间格式有多种),不然会报错,这里只能为时间格式自定义参数绑定

     1) 创建工具类

    package cn.controller.converter;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import org.springframework.core.convert.converter.Converter;
    
    /**
     * 自定义全局字符串转日期转换器
     * param:s -source:源
     * param:T -target:目标
     * 还需在springMv中配置此工具类
     * @author 佳先森
     *
     */
    public class CustomGlobalStrToDateConverter implements Converter<String,Date>{
    
        @Override
        public Date convert(String source) {
            try {
                Date date=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(source);
                return date;
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            return null;
        }
    
    }

     2) 在SpringMVc上创建自定义转换器,并将它配置到注解驱动上

     <!-- 注解驱动:能够自动配置最新版的处理器映射器和处理器适配器 -->
             <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven> 
    <!-- 配置自定义转换器:用于将字符串转换为日期格式
                 步骤:1.编写工具类  2.将自定义的转换器配置到注解驱动上
             -->
    <bean id="conversionService"
            class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
            <property name="converters">
                <set>
                     <!-- 指定自定义转换器的全路径名名称 -->
                    <bean class="cn.controller.converter.CustomGlobalStrToDateConverter"/>
                </set>
            </property>
    </bean>

     3) jsp界面

      注意引入jstl/fmt标签,这是能够在界面中对时间内容进行格式整理

    <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix="fmt"%>
    <form id="itemForm" action="${pageContext.request.contextPath }/updateitem.action" method="post"> <table width="100%" border=1> <tr> <td>商品生产日期</td> <td><input type="text" name="createtime" value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>" /></td> </tr> </table> </form>

     4) controller接收方法

        @RequestMapping("/updateitem")
        public String updateitem(Items items,Model model) throws Exception{
             itemsService.updateItems(items);
             return "success";
        }

    六、spring MVC与struts 2区别

    1、 springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。

    2、 springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例)struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。

    3、 Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl

    七、spring MVC高级参数绑定

     1、绑定数组

     需求:演示批量删除

     1) 定义jsp

      jsp中包含一个form表单,多个input框前有个checkbox复选框

    <form action="${pageContext.request.contextPath }/delAll.action" method="post">
       查询条件:
    <table width="100%" border=1>
    <tr>
    <!-- 如果controller接受的是vo,那么页面上input框中name属性值要等于vo属性.属性 (..)进行引用-->
    <td>商品名称:<input type="text" name="items.name"/></td>
    <td>商品价格:<input type="text" name="items.price"/></td>
     <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="${itemList}" var="item">
    <tr>
        <!-- 批量删除:name属性名称等于vo中的接受的属性名称 -->
        <td>
            <input type="checkbox"  name="ids" value="${item.id}"/>
        </td>
        <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 }/itemEdit.action?id=${item.id}">修改</a></td>
    </tr>
    </c:forEach>
    </table>
    </form>

     2)定义controller中的方法

     这里是通过复选框将选中的数据进行传送,controller方法中得用数组来接收

      方式一:数组作为参数进行接收:注意这里属性名(ids)要与复选框保持一致

    //如果批量删除,一堆input复选框,那么可以提交数据(只有被选中的时候才可以提交)
        @RequestMapping("/delAll")
        public String delAll(String[] ids) throws Exception{
            System.out.println(ids.toString());
            return "";
        }

       方式二:将数组作为属性封装到VO对象中,将VO对象作为参数进行接收

    public class QueryVo {
        //商品对象
        private Items items;
    
        //批量删除
        private Integer[] ids;
        
           //省略set/get方法
    }
    //如果批量删除,一堆input复选框,那么可以提交数据(只有被选中的时候才可以提交)
        @RequestMapping("/delAll")
        public String delAll(QueryVo vo) throws Exception{
            System.out.println(vo.getItems().getName());
                    System.out.println(queryVo.getItems().getPrice());
            return "";
        }   

     2、绑定集合(将表单的数据绑定到List中)

     需求:对数据进行批量修改

      1) 在pojo类中定义一个集合的属性

    package cn.clj.vo;
    
    import java.util.Arrays;
    import java.util.List;
    
    import cn.clj.pojo.Items;
    /**
     * 演示高级查询,封装指定pojo类中的指定属性
     * @author 佳先森
     *
     */
    public class QueryVo {
        //商品对象
        private Items items;
        //用户对象
        //。。。。
        //批量删除
        private Integer[] ids;
        //批量修改
        private List<Items> itemsList;
        
        
        //省略set/get,toString()方法
        
        
    }

       2)更改jsp

    <form action="${pageContext.request.contextPath }/updateAll.action" method="post">
    查询条件:
    <table width="100%" border=1>
    <tr>
    <!-- 如果controller接受的是vo,那么页面上input框中name属性值要等于vo属性.属性 (..)进行引用-->
    <td>商品名称:<input type="text" name="items.name"/></td>
    <td>商品价格:<input type="text" name="items.price"/></td>
    <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="${itemList}" var="item" varStatus="status">
      <tr>
        <!-- 如果批量修改,可以用List<pojo>来接受,页面上input框的name属性值=vo中的接受的属性名称+[list的下标]+.+list泛型属性的名称 -->
        <td>
            <input type="checkbox"  name="ids" value="${item.id}"/>
            <input type="hidden"  name="itemsList[${status.index}].id" value="${item.id}"/>
        </td>
        <td><input type="text" name="itemsList[${status.index}].name" value="${item.name}"/></td>
        <td><input type="text" name="itemsList[${status.index}].price" value="${item.price}"/></td>
        <td><input type="text" name="itemsList[${status.index}].createtime" value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>"/></td>
        <td><input type="text" name="itemsList[${status.index}].detail" value="${item.detail}"/></td>
       <td><a href="${pageContext.request.contextPath }/itemEdit.action?id=${item.id}">修改</a></td>
      </tr>
    </c:forEach>
    
    </table>
    </form>

     3)在controller类中创建接受方法

        //批量修改
        @RequestMapping("/updateAll")
        public String updateAll(QueryVo vo) throws Exception{
            System.out.println(vo.getItems().getName()); 
    System.out.println(vo.getItems().getPrice());
    return "";
        }

    八、关于spring MVC窄化请求映射

      分析:在团队开发情况下,不同controller中可能出现一个或多个方法RequestMapping值相同,因为配置文件中采用的是包扫描的方法进行映射,就有可能在输入域名的时候跳错controller中的方法。此时,如果为了区分每个conroller中的每个方法,必须配置窄化请求映射,相当于给类起个名字,每当反问域名时,指定跳转方法uri前必须加上这个“类名”,通过此方法对类行进分类管理

      如:

    @Controller
    //窄化请求映射:为防止方法名重名,相当于在url中多加了一层目录,房子重名
    @RequestMapping("/items")
    public class ItemController {
    //批量修改
        @RequestMapping("/updateAll")
        public String updateAll(QueryVo vo) throws Exception{
            System.out.println(vo);
            return "";
        }

     如果以后要跳转到该方法,域名得写成http://localhost:8080/项目名/items/updateAll.action

    九、spring MVC之请求方法限定

     语法为@RequestMapping(value="/XXX",method=RequestMethod.XX),其中XX可以写GET或者POST,如果在方法中限定了请求方法而jsp中表单提交方式不是指定的,会报405错误

    @RequestMapping(value="/list",method=RequestMethod.GET)
        public ModelAndView itemsList() throws Exception{
            List<Items> list=itemsService.list();
            System.out.println("进入了");
            ModelAndView modelAndView=new ModelAndView();
            modelAndView.addObject("itemList",list);
            modelAndView.setViewName("itemList");
            return modelAndView;
        }

    十、controller类方法返回值

       controller方法返回值包含多种,一下介绍几种常用的:

     1、ModelAndView方式

        @RequestMapping(value="/list",method=RequestMethod.GET)
        public ModelAndView itemsList() throws Exception{
            List<Items> list=itemsService.list();
            ModelAndView modelAndView=new ModelAndView();
            modelAndView.addObject("itemList",list);
            modelAndView.setViewName("itemList");
            return modelAndView;
        }

     2、String方式(直接return一个字符串),返回的数据由model完成

     种类一:放回普通字符串(去掉页面扩展名)

    @RequestMapping("/search")
        public String search(QueryVo vo) throws Exception{
            System.out.println(vo);
            return "success";
        }

     种类二:请求转发方式

     注意:这里是请求转发跳转到同一个Controller中的注解值为itemEdit的方法,请求转发能够携带值

        @RequestMapping("/updateitem")
        public String updateitem(Items items,Model model) throws Exception{
             itemsService.updateItems(items);//请求转发:浏览器中的url不发生改变,request域中的数据可以带到转发后的方法中
             model.addAttribute("id",items.getId());//或者:request.setAttribute("id",items.getId())
             //springMvc中请求转发:返回的字符串以forward:开头的都是请求转发
             return "forward:itemEdit.action";
        }

     种类三:重定向方式

      注意:重定向的方式是不能携带值的,如果要传参数,得封装到域名中(如:return "redirect:itemsEdit.action?id="+items.getId())

        @RequestMapping("/updateitem")
        public String updateitem(Items items,Model model) throws Exception{
             itemsService.updateItems(items);
             model.addAttribute("id",items.getId());//在springMvc中凡是以redirect:字符串开头的的都是重定向
             return "redirect:itemsEdit.action";
        }

     种类三:返回值为void

      这里演示的请求请求转发的方式(如果controller方法返回值为void,则不走SpringMvc组件,需要些完整的路径名称))

        @RequestMapping("/updateitem")
         public void updateitem(Items items,HttpServletRequest request,HttpServletResponse response) throws Exception{
            itemsService.updateItems(items);
             request.setAttribute("id",items.getId())
             request.getRequestDispatcher("/jsp/success.jsp").forward(request, response);
    }

    十一、spring MVC之全局异常处理

      需求:当条件查询询信息时出现错误(没有该商品),都会跳转到指定的错误页面

      1、定义异常类

    package cn.clj.vo;
    
    public class CustomerException extends Exception{
        //异常信息
        private String message;
    
        public CustomerException(String message) {
            super();
            this.message = message;
        }
      //省略set/get方法   
    }

      2、定义异常处理工具类

    public class GlobalExceptionResolver implements HandlerExceptionResolver{
    
        @Override
        public ModelAndView resolveException(HttpServletRequest request,
                HttpServletResponse response, Object handler, Exception ex) {
            ex.printStackTrace();
            CustomerException customerException=null;
            if(ex instanceof CustomerException){
                customerException=(CustomerException) ex;
            }else{
                customerException=new CustomerException("系统错误,请联系管理员");
            }
            ModelAndView model=new ModelAndView();
            model.addObject("message",customerException);
            model.setViewName("error");
            return model;
        }
    
    }

      3、创建异常页面error.jsp

    <body>
        您的操作出现错误如下:<br/>
        <h3><font color="red">${message}</font></h3>
    </body>

      4、配置异常处理(在SpingMvc.xml文件中配置处理器)

    <!-- 异常处理器 -->
    <bean id="handlerExceptionResolver" class="cn.clj.vo.CustomerException"/>
    </beans>

      5、利用异常类

       在调用查询方法时,如果查询到的商品不存在,抛出自定义异常类

        @RequestMapping("/itemEdit")
        public String itemEdit(HttpServletRequest request,Model model) throws Exception{
            String idStr=request.getParameter("id");
            Items items=itemsService.findItemsById(Integer.parseInt(idStr));
            if(items==null){
                throw new CustomerException("您查询的信息不存在");
            }
            model.addAttribute("item",items);
            return "editItem";
        }

      6、测试

      当查询一个不存在的商品,如果成功跳转到自定义异常界面,表示配置成功

    十二、spring MVC之上传图片

      分析:企业中像那种高并发项目,都会有不同的服务器接受不同资源,利用nginx实现负载均衡。这里因为只上传图片,服务器只有tomcat,所以只能在tomcat中配置。

      1、配置虚拟存储路径

      此配置就是将上传的图片放置到指定的文件夹下

      做法:进入tomcat/conf/server.xml文件中,加入下面一条命令,表示到域名以pic结尾时,访问的目录为E:壁纸文件夹下

     <Context docBase="E:壁纸" path="/pic" reloadable="false"/>

      2、加入文件上传依赖jar包

      3、在SqlMapConfig.xml中配置文件上传解析器

      <!-- 文件上传 -->
        <bean id="multipartResolver"
            class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <!-- 设置上传文件的最大尺寸为5MB -->
            <property name="maxUploadSize">
                <value>5242880</value>
            </property>
        </bean>

      4、在Controller中创建文件上传处理方法

       文件上传是通过表单提交的,所提交的是一连串字符串,需对字符串进行处理,这里为了防止所存的图片文件重名,采用了随机字符串进行拼接

    //演示上传图片:注意"pictureFile"是与jsp中文件上传属性保持一致
        @RequestMapping("/upload")
        public String upload(MultipartFile pictureFile,Items items,Model model) throws Exception{
            //1.获取图片完整名称
            String fileStr=pictureFile.getOriginalFilename(); 
            //2.使用随机生成的字符串+源图片扩张名组成新的图片名称,防止图片重名
            String newFileName=UUID.randomUUID().toString()+fileStr.substring(fileStr.lastIndexOf("."));
            //3.将图片保存到硬盘
            pictureFile.transferTo(new File("E:\壁纸\"+newFileName));
            //4.将图片名称保存到数据库
            items.setPic(newFileName);
             itemsService.updateItems(items);
            return "success";
        }

      5、创建具有图片上传的form表单的jsp页面

    <form id="itemForm"    action="${pageContext.request.contextPath }/upload.action" method="post" enctype="multipart/form-data">
        <table width="100%" border=1>
        <tr>      <td>商品图片</td>     <td>      <c:if test="${item.pic!=null}">      <img src="/pic/${item.pic}" width=100 height=100/>       <br/>      </c:if>     <input type="file" name="pictureFile"/>   </td>     </tr>     <tr> <td colspan="2" align="center"><input type="submit" value="提交" /> </td>    </tr>
       </table> </form>

    十三、spring MVC之Json

     spring MVC是支持Json格式的,需要配置@RequestBody

     @RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容转换为jsonxml等格式的数据并绑定到controller方法的参数上。

     需求:利用ajax传送json数据,contoller类定义方法进行接受,并进行相应

     1、导入json依赖jar包

      2、必须有注解驱动,基于上面环境已经配置,这里无须再配置

     <!-- 注解驱动:能够自动配置最新版的处理器映射器和处理器适配器 -->
             <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

      3、导入jquery依赖jar包

      4、jsp中调用ajax请求

      这里当触发input按钮,就会调用ajax请求

    <script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.4.4.min.js"></script>
    <script type="text/javascript">
        function sendJson(){
            $.ajax({
                type:"post",
                url:"${pageContext.request.contextPath }/sendJson.action",
            <!--ajax默认以text文本形式传递,如果要传递json的指定为json--> contentType:
    "application/json;charset=utf-8", data:'{"name":"测试商品","price":99.9}', success:function(data){ alert(data); } }); } </script> <input type="button" value="sendJson" onClick="sendJson()"/>

      5、参数接受

    //导入jackson的jar包在controller的方法中可以使用@RequestBody,
        //让springMvc将json格式字符串自动转换我java中pojo
        //注意:页面json中key要等于java中pojo的属性名称
        //controller方法返回pojo类型的对象并且用@ResponseBody注解,springMvc会自动将pojo对象转换为json格式字符串
            @RequestMapping("/sendJson")
            @ResponseBody
            public Items sendJson(@RequestBody Items items) throws Exception{
          //public void sendJson(@RequestBody Items items) throws Exception{
            System.out.println(items.getName()+"	"+items.getPrice());
            //方式一,返回值为void这里无须设置跳转页面,ajax会自动跳转
            //方式二:返回值为Items pojo类,方法中参数必须配置@ResponseBody注解,会给界面返回Item 对象
            return items;
        }

    十四、spring MVC之Restful风格

      1、什么是Restfull风格

      一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

                                                    ------  360百科

      简而言之:Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格,是对http协议的诠释。
      资源定位:互联网所有的事物都是资源,要求url中没有动词,只有名词。没有参数
      Url格式:http://blog.csdn.net/beat_the_world/article/details/45621673
      资源操作:使用put、delete、post、get,使用不同方法对资源进行操作。分别对应添加、删除、修改、查询。一般使用时还是post和get。Put和Delete几乎不用。

      2、怎么使用Restful

       需求:更改访问路径格式,采用Restful风格

       1) 配置restful配置

          此时需要更改web.xml文件中的拦截对象,以前是针对所有的action("*.action"),现在是针对所有对象("/")

      <!-- 开启SpringMVc拦截器-->
      <servlet>
        <servlet-name>SpringMvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 配置SpringMvc核心配置文件所在路径  -->
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:SpringMvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>SpringMvc</servlet-name>
        <!-- 
            *.action:代表拦截后缀名为.action结尾的
            /        :拦截所有但是不包括.jsp
            /*        :拦截所有包括.jsp
         -->
        <url-pattern>/</url-pattern>
      </servlet-mapping>

      2) jsp请求书写规范

      这里是传递了一个id参数,请求域名中去掉了aciton或者特殊符号

    <a href="${pageContext.request.contextPath }/restful/${item.id}">修改</a>

      3) 接受参数

       通过@RequestMapping("/restful/{id}")接收具有restful风格的域名;@PathVariable 接受参数值

          //通过@PathVariable可以接收url中所传过来的参数
            //@RequestMapping("/restful/{id}/{张三}")传多参
            //@RequestMapping("/restful/{id}")中接受参数使用大括号中加上变量名称,@PathVariable中变量名称要和@RequestMapping中变量名称保持一致
            @RequestMapping("/restful/{id}")
            public String restful(@PathVariable("id") Integer id,HttpServletRequest request,Model model) throws Exception{
    //        public String restful(@PathVariable("id") Integer id,@PathVariable("张三") String name,HttpServletRequest request,Model model) throws Exception{
                Items items=itemsService.findItemsById(id);
                model.addAttribute("item",items);
                return "editItem";
            }

    十五、spring MVC之拦截器

     1、怎么定义一个拦截器

      1) 创建一个自定义拦截器类,继承HandlerInterceptor接口

    package cn.clj.interceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    public class Interceptor1 implements HandlerInterceptor{
        //执行实际:Controller以及执行,ModelAndView已经返回
        //使用场景:记录操作日志(如记录用户登录的ip,时间等)
        @Override
        public void afterCompletion(HttpServletRequest arg0,
                HttpServletResponse arg1, Object arg2, Exception arg3)
                throws Exception {
            System.out.println("afterCompletion");
            
        }
        //执行实际:Controller方法已经执行,ModelAndView还没返回
        //使用场景:可以再次方法中设置全局的数据处理业务,这里有个ModelAndView,可以添加全局参数
        @Override
        public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
                Object arg2, ModelAndView arg3) throws Exception {
            // TODO Auto-generated method stub
            System.out.println("postHandle");
        }
        //返回boolean值:如果返回true:放行;false:拦截
        //执行时机:controller方法没有被执行,ModelAndView没有被返回
        //使用场景:权限验证
        @Override
        public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
                Object arg2) throws Exception {
            // TODO Auto-generated method stub
            System.out.println("preHandle");
            return true;
        }
    
    }

      2) 在springMvc.xml配置拦截器(这里是配置全局拦截器)

    <!-- 配置拦截器 -->
    <mvc:interceptors>
            <mvc:interceptor>
            <!--拦截请求的路径要拦截所有必须配置成/**(不能是/*,它只拦截一层目录) --> 
            <mvc:mapping path="/**"/>
             指定拦截器的位置
            <bean class="cn.clj.interceptor.Interceptor1"/>
            </mvc:interceptor>
    </mvc:interceptors>

      3)启动tomcat,就会自动调用拦截器

      2、拦截器应用之登录(身份认证)

       分析:在登录界面中,当用户输入自己信息时,会调用后端方法,拦截器检查session中否存在这个用户,核对数据库是否有这个用户,然后进行处理放心还是拦截

       1) 定义一个登录的拦截器

    package cn.clj.interceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    public class LoginInterceptor implements HandlerInterceptor{
    
        @Override
        public void afterCompletion(HttpServletRequest arg0,
                HttpServletResponse arg1, Object arg2, Exception arg3)
                throws Exception {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
                Object arg2, ModelAndView arg3) throws Exception {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                Object arg2) throws Exception {
            //判断当前访问路径是否为登录的路径,如果是则放行
            if(request.getRequestURI().indexOf("/login")>0){
                return true;
            }
            //判断session中是否有登录信息,如果没有则跳转到登录界面,如果有则放行
            HttpSession session=request.getSession();
            if(session.getAttribute("username")!=null){
                return true;
            }
            request.getRequestDispatcher("/jsp/login.jsp").forward(request, response);
            //其他则拦截
            return false;
        }
    
    }

      2) 定义一个jsp登录界面

       <form action="${pageContext.request.contextPath}/login/submit" method="post">
           <table>
               <tr>
                   <td>用户名:<input type="text" name="username"/></td></br>
                   <td>密    码:<input type="text" name="password"/></td></br>
                   <td><input type="submit" value="登录"/></td>
               </tr>
           </table>
       
       </form>

      3) 定义处理登录的controller类

    package cn.clj.controller;
    
    import java.io.File;
    import java.util.Date;
    import java.util.List;
    import java.util.UUID;
    
    import javax.annotation.Resource;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.multipart.MultipartFile;
    import org.springframework.web.servlet.ModelAndView;
    
    import cn.clj.pojo.Items;
    import cn.clj.service.ItemsService;
    import cn.clj.vo.QueryVo;
    
    @Controller
    @RequestMapping("/login")
    public class LoginController {
        //跳转到登录页面
        @RequestMapping("/login")
        public String login() throws Exception{
            return "login";
        }
        @RequestMapping("/submit")
        public String submit(String username,String password,HttpServletRequest request) throws Exception{
            HttpSession session=request.getSession();
            //判断用户名密码正确性,如果正确则将登录信息放入session中
            //这里简写,真正项目中要去数据库中校验用户名和密码
            if(username!=null){
                session.setAttribute("username", username);
            }
            //跳转到列表页(注意:这里加了斜杠是用了绝对路径,因为
            //两者不属于同一个controller,如果跳转的conrtoller
            //类前加了窄化请求映射,路径名得为redirect:/items/list)
            return "redirect:/list";
        }
    }

      

      

      

      

      

     

  • 相关阅读:
    ArrayList用法
    MessageBox
    将文本文件导入Sql数据库
    在桌面和菜单中添加快捷方式
    泡沫排序
    Making use of localized variables in javascript.
    Remove double empty lines in Visual Studio 2012
    Using Operations Manager Connectors
    Clear SharePoint Designer cache
    Programmatically set navigation settings in SharePoint 2013
  • 原文地址:https://www.cnblogs.com/cailijia52o/p/8732906.html
Copyright © 2011-2022 走看看