• 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";
        }
    }

      

      

      

      

      

     

  • 相关阅读:
    15.RDD 创建内幕解析
    14.spark RDD解密
    我的读书笔记-《异类》
    深入解析单例线程安全问题的迷思
    一个关于数学归纳法的悖论问题-续
    一个关于数学归纳法的悖论问题
    简易解说拉格朗日对偶(Lagrange duality)(转载)
    unity3d NavMeshAgent 寻路画线/画路径
    unity3d easytouch计算摇杆旋转角度以及摇杆八方向控制角色
    unity3d 摄像机跟随角色时被物体遮挡解决方案
  • 原文地址:https://www.cnblogs.com/cailijia52o/p/8732906.html
Copyright © 2020-2023  润新知