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 mvc和Struts2都属于表现层的框架,它是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>

    &lt;dependency&gt;<br/>
        &lt;!--使用Junit4,采用注解形式 --&gt;<br/>
        &lt;groupId&gt;junit&lt;/groupId&gt;<br/>
        &lt;artifactId&gt;junit&lt;/artifactId&gt;<br/>
        &lt;version&gt;4.11&lt;/version&gt;<br/>
        &lt;scope&gt;test&lt;/scope&gt;<br/>
    &lt;/dependency&gt;<br/>
    &lt;!--数据库驱动 --&gt;<br/>
    &lt;dependency&gt;<br/>
        &lt;groupId&gt;mysql&lt;/groupId&gt;<br/>
        &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;<br/>
        &lt;version&gt;5.1.38&lt;/version&gt;<br/>
        &lt;!--配置maven工作范围:因为驱动只有真正工作时才会启动 --&gt;<br/>
        &lt;scope&gt;runtime&lt;/scope&gt;<br/>
    &lt;/dependency&gt;<br/>
    &lt;dependency&gt;<br/>
        &lt;groupId&gt;c3p0&lt;/groupId&gt;<br/>
        &lt;artifactId&gt;c3p0&lt;/artifactId&gt;<br/>
        &lt;version&gt;0.9.1.2&lt;/version&gt;<br/>
    &lt;/dependency&gt;<br/>
    &lt;dependency&gt;<br/>
        &lt;groupId&gt;javax.servlet&lt;/groupId&gt;<br/>
        &lt;artifactId&gt;jstl&lt;/artifactId&gt;<br/>
        &lt;version&gt;1.2&lt;/version&gt;<br/>
        &lt;scope&gt;provided&lt;/scope&gt;<br/>
    &lt;/dependency&gt;

&lt;!–spring依赖 –&gt;

    &lt;!--1.spring核心依赖 --&gt;<br/>
    &lt;dependency&gt;<br/>
        &lt;groupId&gt;org.springframework&lt;/groupId&gt;<br/>
        &lt;artifactId&gt;spring-core&lt;/artifactId&gt;<br/>
        &lt;version&gt;4.1.7.RELEASE&lt;/version&gt;<br/>
    &lt;/dependency&gt;<br/>
    &lt;dependency&gt;<br/>
        &lt;groupId&gt;org.springframework&lt;/groupId&gt;<br/>
        &lt;artifactId&gt;spring-beans&lt;/artifactId&gt;<br/>
        &lt;version&gt;4.1.7.RELEASE&lt;/version&gt;<br/>
    &lt;/dependency&gt;<br/>
    &lt;dependency&gt;<br/>
        &lt;groupId&gt;org.springframework&lt;/groupId&gt;<br/>
        &lt;artifactId&gt;spring-context&lt;/artifactId&gt;<br/>
        &lt;version&gt;4.1.7.RELEASE&lt;/version&gt;<br/>
    &lt;/dependency&gt;<br/>
    &lt;!--2.spring Dao层依赖 --&gt;<br/>
    &lt;dependency&gt;<br/>
        &lt;groupId&gt;org.springframework&lt;/groupId&gt;<br/>
        &lt;artifactId&gt;spring-jdbc&lt;/artifactId&gt;<br/>
        &lt;version&gt;4.1.7.RELEASE&lt;/version&gt;<br/>
    &lt;/dependency&gt;<br/>
    &lt;dependency&gt;<br/>
        &lt;groupId&gt;org.springframework&lt;/groupId&gt;<br/>
        &lt;artifactId&gt;spring-tx&lt;/artifactId&gt;<br/>
        &lt;version&gt;4.1.7.RELEASE&lt;/version&gt;<br/>
    &lt;/dependency&gt;<br/>
    &lt;!--3.spring web相关依赖:用于当启动服务器时加载配置文件 --&gt;<br/>
    &lt;dependency&gt;<br/>
        &lt;groupId&gt;org.springframework&lt;/groupId&gt;<br/>
        &lt;artifactId&gt;spring-web&lt;/artifactId&gt;<br/>
        &lt;version&gt;4.1.7.RELEASE&lt;/version&gt;<br/>
    &lt;/dependency&gt;<br/>
    &lt;!--用于springMVC需要 --&gt;<br/>
    &lt;dependency&gt;<br/>
        &lt;groupId&gt;org.springframework&lt;/groupId&gt;<br/>
        &lt;artifactId&gt;spring-webmvc&lt;/artifactId&gt;<br/>
        &lt;version&gt;4.1.7.RELEASE&lt;/version&gt;<br/>
    &lt;/dependency&gt;<br/>
    &lt;!--4.spring test测试相关依赖 --&gt;<br/>
    &lt;dependency&gt;<br/>
        &lt;groupId&gt;org.springframework&lt;/groupId&gt;<br/>
        &lt;artifactId&gt;spring-test&lt;/artifactId&gt;<br/>
        &lt;version&gt;4.1.7.RELEASE&lt;/version&gt;<br/>
    &lt;/dependency&gt;<br/>
&lt;/dependencies&gt;</pre>

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

3、创建spring MVC核心配置文件,文件名就叫SpringMvc.xml

  导入相应地约束

&lt;?xml version=“1.0” encoding=“UTF-8”?&gt;
&lt;beans xmlns=“http://www.springframework.org/schema/beans&#34;

xmlns:xsi=&#34;http://www.w3.org/2001/XMLSchema-instance&#34;<br/>
xmlns:p=&#34;http://www.springframework.org/schema/p&#34;<br/>
xmlns:context=&#34;http://www.springframework.org/schema/context&#34;<br/>
xmlns:dubbo=&#34;http://code.alibabatech.com/schema/dubbo&#34;<br/>
xmlns:mvc=&#34;http://www.springframework.org/schema/mvc&#34;<br/>
xsi:schemaLocation=&#34;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd<br/>
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd<br/>
    http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd<br/>
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd&#34;&gt;<br/>

&lt;/beans&gt;

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到请求方法的映射<br/>
//url中输入一个地址,例如:localhost:8888/SpringMvc/list.action<br/>
//用以替代了struts中采用的配置文件进行匹配来调用那个方法从而识别跳转那个页面<br/>

@RequestMapping(”/list“)
public ModelAndView itemsList()throws Exception{

   List&lt;Items&gt; itemList = new ArrayList&lt;Items&gt;();

//商品列表

    Items items_1 = new Items();<br/>
    items_1.setName(&#34;联想笔记本_3&#34;);<br/>
    items_1.setPrice(6000f);<br/>
    items_1.setDetail(&#34;ThinkPad T430 联想笔记本电脑!&#34;);

Items items_2 = new Items();

    items_2.setName(&#34;苹果手机&#34;);<br/>
    items_2.setPrice(5000f);<br/>
    items_2.setDetail(&#34;iphone6苹果手机!&#34;);

itemList.add(items_1);

    itemList.add(items_2);<br/>
    //模型视图<br/>
    //model模型:模型对象中存放了返回给页面的数据<br/>
    //view视图:视图对象中指定给返回的页面的位置<br/>
    //创建modelandView对象<br/>
    ModelAndView modelAndView = new ModelAndView();<br/>
    //添加model(将返回给页面的数据放入模型和视图对象中)<br/>
    modelAndView.addObject(&#34;itemList&#34;, itemList);<br/>
    //添加视图(指定给 返回页面的位置)<br/>
    modelAndView.setViewName(&#34;jsp/itemList.jsp&#34;);<br/>
    return modelAndView;<br/>
}<br/>

}

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

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

&lt;?xml version=”1.0“ encoding=”UTF-8“?&gt;
&lt;beans xmlns=”http://www.springframework.org/schema/beans&#34;

   xmlns:mvc=&#34;http://www.springframework.org/schema/mvc&#34;<br/>
   xmlns:xsi=&#34;http://www.w3.org/2001/XMLSchema-instance&#34;<br/>
   xmlns:context=&#34;http://www.springframework.org/schema/context&#34;<br/>
   xsi:schemaLocation=&#34;http://www.springframework.org/schema/beans<br/>
        http://www.springframework.org/schema/beans/spring-beans-4.1.xsd<br/>
        http://www.springframework.org/schema/context<br/>
        http://www.springframework.org/schema/context/spring-context-4.1.xsd<br/>
        http://www.springframework.org/schema/mvc<br/>
        http://www.springframework.org/schema/mvc/spring-mvc.xsd&#34;&gt;<br/>
    &lt;context:component-scan base-package=&#34;com.clj.controller&#34;/&gt;<br/>
    &lt;mvc:annotation-driven&gt;&lt;/mvc:annotation-driven&gt;<br/>

&lt;/beans&gt;

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

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

&lt;!– springMvc前端控制器 –&gt;
&lt;servlet&gt;

 &lt;servlet-name&gt;springMvc&lt;/servlet-name&gt;<br/>
 &lt;!--路径:spring-webmvc-4.1.3.RELEASE.jar\org.springframework.web.servlet  --&gt;<br/>
 &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;<br/>
 &lt;!-- 如果没有指定springMvc核心配置文件那么默认会去找/WEB_INF/+&lt;servlet-name&gt;的内容+  -servlet.xml配置文件 --&gt;<br/>
 &lt;!-- 指定springMvc核心配置文件位置 --&gt;<br/>
 &lt;init-param&gt;<br/>
    &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;<br/>
    &lt;param-value&gt;classpath:SpringMvc.xml&lt;/param-value&gt;<br/>
 &lt;/init-param&gt;<br/>
 &lt;!-- tomcat启动时就加载这个servlet --&gt;<br/>
 &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br/>

&lt;/servlet&gt;
&lt;servlet-mapping&gt;

 &lt;servlet-name&gt;springMvc&lt;/servlet-name&gt;<br/>
 &lt;url-pattern&gt;*.action&lt;/url-pattern&gt;<br/>

&lt;/servlet-mapping&gt;

  DispatcherServlet的路径为:

 

8、配置jsp

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

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

&lt;%@taglib uri=“http://java.sun.com/jstl/core_rt&#34; prefix=”c“%&gt;
&lt;body&gt;
&lt;form action=”${pageContext.request.contextPath }/search.action“ method=”post“&gt;
查询条件:
&lt;table width=”100%“ border=1&gt;
&lt;tr&gt;
&lt;!– 如果controller接受的是vo,那么页面上input框中name属性值要等于vo属性.属性 (..)进行引用–&gt;
&lt;td&gt;商品名称:&lt;input type=”text“ name=”items.name“/&gt;&lt;/td&gt;
&lt;td&gt;商品价格:&lt;input type=”text“ name=”items.price“/&gt;&lt;/td&gt;
&lt;td&gt;&lt;input type=”submit“ value=”查询“/&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
商品列表:
&lt;table width=”100%“ border=1&gt;
&lt;tr&gt;

&lt;td&gt;商品名称&lt;/td&gt;<br/>
&lt;td&gt;商品价格&lt;/td&gt;<br/>
&lt;td&gt;生产日期&lt;/td&gt;<br/>
&lt;td&gt;商品描述&lt;/td&gt;<br/>
&lt;td&gt;操作&lt;/td&gt;<br/>

&lt;/tr&gt;
&lt;c:forEach items=”${itemList}“ var=”item“&gt;
&lt;tr&gt;

&lt;td&gt;${item.name}&lt;/td&gt;<br/>
&lt;td&gt;${item.price}&lt;/td&gt;<br/>
&lt;td&gt;&lt;fmt:formatDate value=&#34;${item.createtime}&#34; pattern=&#34;yyyy-MM-dd HH:mm:ss&#34;/&gt;&lt;/td&gt;<br/>
&lt;td&gt;${item.detail}&lt;/td&gt;

&lt;td&gt;&lt;a href=”\({pageContext.request.contextPath }/itemEdit.action?id=\){item.id}“&gt;修改&lt;/a&gt;&lt;/td&gt; &lt;/tr&gt;
&lt;/c:forEach&gt; &lt;/table&gt;
&lt;/form&gt;

9、测试

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

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

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

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

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

 &lt;!– 配置最新版的注解的处理器映射器 –&gt;

     &lt;bean class=&#34;org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping&#34;/&gt;<br/>
     &lt;!-- 配置最新版的注解的处理器适配器 --&gt;<br/>
     &lt;bean class=&#34;org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter&#34;/&gt;</pre>

  方式二:自动配置

&lt;mvc:annotation-driven conversion-service=”conversionService“&gt;&lt;/mvc:annotation-driven&gt;

  全部代码如下

        &lt;!– 配置@Controller注解扫描 –&gt;

    &lt;context:component-scan base-package=&#34;cn.clj.controller&#34;/&gt;

&lt;!– 如果没有显示配置处理器映射器和处理器适配器那个springMvc会默认的dispatcherServlet.properties中查找

    对应的处理器映射器和处理器适配器去使用,每个请求都要扫描一次的默认配置文件,效率非常低,会降低访问速度,所以显示的配置处理器映射器和处理器适配器<br/>
     --&gt;<br/>
     &lt;!-- 注解形式的处理器适配器<br/>
     &lt;bean class=&#34;org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter&#34;/&gt; --&gt;<br/>
     &lt;!-- 注解形式的处理器映射器<br/>
     &lt;bean class=&#34;org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver&#34;/&gt;--&gt;<br/>
     &lt;!-- 配置最新版的注解的处理器映射器,以上已经过时<br/>
     &lt;bean class=&#34;org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping&#34;/&gt;--&gt;<br/>
     &lt;!-- 配置最新版的注解的处理器适配器<br/>
     &lt;bean class=&#34;org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter&#34;/&gt;--&gt;<br/>
     &lt;!-- 注解驱动:能够自动配置最新版的处理器映射器和处理器适配器 --&gt;<br/>
     &lt;mvc:annotation-driven conversion-service=&#34;conversionService&#34;&gt;&lt;/mvc:annotation-driven&gt;

&lt;/beans&gt;

三、关于视图解析器

1.分析情形

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

2、配置视图解析器

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

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

      &lt;!– 配置视图解析器 –&gt;

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

      &lt;/bean&gt;

2)更改conroller类中的写法

        //添加视图(指定给 返回页面的位置)

   // modelAndView.setViewName(&#34;jsp/itemList.jsp&#34;);<br/>
    modelAndView.setViewName(&#34;itemList&#34;);<br/>
    return modelAndView;</pre>

四、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扫描

&lt;?xml version=”1.0“ encoding=”UTF-8“?&gt;
&lt;beans xmlns=”http://www.springframework.org/schema/beans&#34;

xmlns:context=&#34;http://www.springframework.org/schema/context&#34;<br/>
xmlns:p=&#34;http://www.springframework.org/schema/p&#34;<br/>
xmlns:aop=&#34;http://www.springframework.org/schema/aop&#34;<br/>
xmlns:tx=&#34;http://www.springframework.org/schema/tx&#34;<br/>
xmlns:xsi=&#34;http://www.w3.org/2001/XMLSchema-instance&#34;<br/>
xsi:schemaLocation=&#34;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd<br/>
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd<br/>
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<br/>
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd&#34;&gt;

&lt;!– 加载配置文件 –&gt;

&lt;context:property-placeholder location=&#34;classpath:db.properties&#34;/&gt;<br/>
&lt;!-- 数据库连接池 --&gt;<br/>
&lt;bean id=&#34;dataSource&#34; class=&#34;org.apache.commons.dbcp.BasicDataSource&#34;<br/>
    destroy-method=&#34;close&#34;&gt;<br/>
    &lt;property name=&#34;driverClassName&#34; value=&#34;${jdbc.driver}&#34;/&gt;<br/>
    &lt;property name=&#34;url&#34; value=&#34;${jdbc.url}&#34;/&gt;<br/>
    &lt;property name=&#34;username&#34; value=&#34;${jdbc.username}&#34;/&gt;<br/>
    &lt;property name=&#34;password&#34; value=&#34;${jdbc.password}&#34;/&gt;<br/>
    &lt;property name=&#34;maxActive&#34; value=&#34;10&#34;/&gt;<br/>
    &lt;property name=&#34;maxIdle&#34; value=&#34;5&#34;/&gt;<br/>
&lt;/bean&gt;<br/>
&lt;!-- mapper配置 --&gt;<br/>
&lt;!-- 让spring管理sqlsessionfactory 使用mybatis和spring整合包中的 --&gt;<br/>
&lt;bean id=&#34;sqlSessionFactory&#34; class=&#34;org.mybatis.spring.SqlSessionFactoryBean&#34;&gt;<br/>
    &lt;!-- 数据库连接池 --&gt;<br/>
    &lt;property name=&#34;dataSource&#34; ref=&#34;dataSource&#34;/&gt;<br/>
    &lt;!-- 加载mybatis的全局配置文件 --&gt;<br/>
    &lt;property name=&#34;configLocation&#34; value=&#34;classpath:SqlMapConfig.xml&#34;/&gt;<br/>
&lt;/bean&gt;<br/>
&lt;!-- 配置Mapper扫描器 --&gt;<br/>
&lt;bean class=&#34;org.mybatis.spring.mapper.MapperScannerConfigurer&#34;&gt;<br/>
    &lt;property name=&#34;basePackage&#34; value=&#34;cn.clj.dao&#34;/&gt;<br/>
&lt;/bean&gt;

&lt;/beans&gt;

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

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

&lt;?xml version=“1.0” encoding=“UTF-8”?&gt;
&lt;beans xmlns=“http://www.springframework.org/schema/beans&#34;

xmlns:context=&#34;http://www.springframework.org/schema/context&#34;<br/>
xmlns:p=&#34;http://www.springframework.org/schema/p&#34;<br/>
xmlns:aop=&#34;http://www.springframework.org/schema/aop&#34;<br/>
xmlns:tx=&#34;http://www.springframework.org/schema/tx&#34;<br/>
xmlns:xsi=&#34;http://www.w3.org/2001/XMLSchema-instance&#34;<br/>
xsi:schemaLocation=&#34;http://www.springframework.org/schema/beans<br/>
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd<br/>
http://www.springframework.org/schema/context<br/>
http://www.springframework.org/schema/context/spring-context-4.0.xsd<br/>
http://www.springframework.org/schema/aop<br/>
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd<br/>
http://www.springframework.org/schema/tx<br/>
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd<br/>
http://www.springframework.org/schema/util<br/>
http://www.springframework.org/schema/util/spring-util-4.0.xsd&#34;&gt;<br/>
&lt;!-- @service扫描 --&gt;<br/>
&lt;context:component-scan base-package=&#34;cn.clj.service&#34;&gt;&lt;/context:component-scan&gt;

&lt;/beans&gt;

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

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

&lt;?xml version=”1.0“ encoding=”UTF-8“?&gt;
&lt;beans xmlns=”http://www.springframework.org/schema/beans&#34;

xmlns:context=&#34;http://www.springframework.org/schema/context&#34; xmlns:p=&#34;http://www.springframework.org/schema/p&#34;<br/>
xmlns:aop=&#34;http://www.springframework.org/schema/aop&#34; xmlns:tx=&#34;http://www.springframework.org/schema/tx&#34;<br/>
xmlns:xsi=&#34;http://www.w3.org/2001/XMLSchema-instance&#34;<br/>
xsi:schemaLocation=&#34;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd<br/>
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd<br/>
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd<br/>

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&#34;&gt;

&lt;!– 事务管理器 –&gt;

&lt;bean id=&#34;transactionManager&#34;<br/>
    class=&#34;org.springframework.jdbc.datasource.DataSourceTransactionManager&#34;&gt;<br/>
    &lt;!-- 数据源 --&gt;<br/>
    &lt;property name=&#34;dataSource&#34; ref=&#34;dataSource&#34; /&gt;<br/>
&lt;/bean&gt;

&lt;!– 通知 –&gt;

&lt;tx:advice id=&#34;txAdvice&#34; transaction-manager=&#34;transactionManager&#34;&gt;<br/>
    &lt;tx:attributes&gt;<br/>
        &lt;!-- 传播行为 --&gt;<br/>
        &lt;tx:method name=&#34;save*&#34; propagation=&#34;REQUIRED&#34; /&gt;<br/>
        &lt;tx:method name=&#34;insert*&#34; propagation=&#34;REQUIRED&#34; /&gt;<br/>
        &lt;tx:method name=&#34;delete*&#34; propagation=&#34;REQUIRED&#34; /&gt;<br/>
        &lt;tx:method name=&#34;update*&#34; propagation=&#34;REQUIRED&#34; /&gt;<br/>
        &lt;tx:method name=&#34;find*&#34; propagation=&#34;SUPPORTS&#34; read-only=&#34;true&#34; /&gt;<br/>
        &lt;tx:method name=&#34;get*&#34; propagation=&#34;SUPPORTS&#34; read-only=&#34;true&#34; /&gt;<br/>
    &lt;/tx:attributes&gt;<br/>
&lt;/tx:advice&gt;

&lt;!– 切面 –&gt;

&lt;aop:config&gt;<br/>
    &lt;aop:advisor advice-ref=&#34;txAdvice&#34;<br/>
        pointcut=&#34;execution(* cn.clj.service.*.*(..))&#34; /&gt;<br/>
&lt;/aop:config&gt;

&lt;/beans&gt;

9)创建SpringMvc核心配置文件之SpringMvc.xml

&lt;?xml version=“1.0” encoding=“UTF-8”?&gt;
&lt;beans xmlns=“http://www.springframework.org/schema/beans&#34;

xmlns:xsi=&#34;http://www.w3.org/2001/XMLSchema-instance&#34;<br/>
xmlns:p=&#34;http://www.springframework.org/schema/p&#34;<br/>
xmlns:context=&#34;http://www.springframework.org/schema/context&#34;<br/>
xmlns:dubbo=&#34;http://code.alibabatech.com/schema/dubbo&#34;<br/>
xmlns:mvc=&#34;http://www.springframework.org/schema/mvc&#34;<br/>
xsi:schemaLocation=&#34;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd<br/>
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd<br/>
    http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd<br/>
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd&#34;&gt;<br/>
    &lt;!-- 配置@Controller注解扫描 --&gt;<br/>
    &lt;context:component-scan base-package=&#34;cn.clj.controller&#34;/&gt;

&lt;!– 注解驱动:能够自动配置最新版的处理器映射器和处理器适配器 –&gt;

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

&lt;/beans&gt;

10)配置服务器启动扫描

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

  &lt;!– 开启spring各核心配置文件扫描 –&gt;
&lt;context-param&gt;

&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;<br/>
&lt;param-value&gt;classpath:applicationContext-*.xml&lt;/param-value&gt;<br/>

&lt;/context-param&gt;
&lt;listener&gt;

&lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;<br/>

&lt;/listener&gt;
&lt;!– 开启SpringMVc拦截器–&gt;
&lt;servlet&gt;

&lt;servlet-name&gt;SpringMvc&lt;/servlet-name&gt;<br/>
&lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;<br/>
&lt;!-- 配置SpringMvc核心配置文件所在路径  --&gt;<br/>
&lt;init-param&gt;<br/>
  &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;<br/>
  &lt;param-value&gt;classpath:SpringMvc.xml&lt;/param-value&gt;<br/>
&lt;/init-param&gt;<br/>
&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br/>

&lt;/servlet&gt;
&lt;servlet-mapping&gt;

&lt;servlet-name&gt;SpringMvc&lt;/servlet-name&gt;<br/>
&lt;url-pattern&gt;*.action&lt;/url-pattern&gt;<br/>

&lt;/servlet-mapping&gt;

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

2、整合开发

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

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

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

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

&lt;?xml version=”1.0“ encoding=”UTF-8“?&gt;
&lt;!DOCTYPE generatorConfiguration
PUBLIC ”-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN“
http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd&#34;&gt; &lt;generatorConfiguration&gt;

&lt;context id=&#34;testTables&#34; targetRuntime=&#34;MyBatis3&#34;&gt;<br/>
    &lt;commentGenerator&gt;<br/>
        &lt;!-- 是否去除自动生成的注释 true:是 : false:否 --&gt;<br/>
        &lt;property name=&#34;suppressAllComments&#34; value=&#34;true&#34; /&gt;<br/>
    &lt;/commentGenerator&gt;<br/>
    &lt;!--数据库连接的信息:驱动类、连接地址、用户名、密码 --&gt;<br/>
    &lt;jdbcConnection driverClass=&#34;com.mysql.jdbc.Driver&#34;<br/>
        connectionURL=&#34;jdbc:mysql://192.168.174.132:3306/SSM&#34; userId=&#34;root&#34;<br/>
        password=&#34;root&#34;&gt;<br/>
    &lt;/jdbcConnection&gt;<br/>
    &lt;!-- &lt;jdbcConnection driverClass=&#34;oracle.jdbc.OracleDriver&#34;<br/>
        connectionURL=&#34;jdbc:oracle:thin:@127.0.0.1:1521:yycg&#34;<br/>
        userId=&#34;yycg&#34;<br/>
        password=&#34;yycg&#34;&gt;<br/>
    &lt;/jdbcConnection&gt; --&gt;

&lt;!– 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和

        NUMERIC 类型解析为java.math.BigDecimal --&gt;<br/>
    &lt;javaTypeResolver&gt;<br/>
        &lt;property name=&#34;forceBigDecimals&#34; value=&#34;false&#34; /&gt;<br/>
    &lt;/javaTypeResolver&gt;

&lt;!– targetProject:生成PO类的位置 –&gt;

    &lt;javaModelGenerator targetPackage=&#34;cn.clj.pojo&#34;<br/>
        targetProject=&#34;.\src&#34;&gt;<br/>
        &lt;!-- enableSubPackages:是否让schema作为包的后缀 --&gt;<br/>
        &lt;property name=&#34;enableSubPackages&#34; value=&#34;false&#34; /&gt;<br/>
        &lt;!-- 从数据库返回的值被清理前后的空格 --&gt;<br/>
        &lt;property name=&#34;trimStrings&#34; value=&#34;true&#34; /&gt;<br/>
    &lt;/javaModelGenerator&gt;<br/>
    &lt;!-- targetProject:mapper映射文件生成的位置 --&gt;<br/>
    &lt;sqlMapGenerator targetPackage=&#34;cn.clj.dao&#34;<br/>
        targetProject=&#34;.\src&#34;&gt;<br/>
        &lt;!-- enableSubPackages:是否让schema作为包的后缀 --&gt;<br/>
        &lt;property name=&#34;enableSubPackages&#34; value=&#34;false&#34; /&gt;<br/>
    &lt;/sqlMapGenerator&gt;<br/>
    &lt;!-- targetPackage:mapper接口生成的位置 --&gt;<br/>
    &lt;javaClientGenerator type=&#34;XMLMAPPER&#34;<br/>
        targetPackage=&#34;cn.clj.dao&#34;<br/>
        targetProject=&#34;.\src&#34;&gt;<br/>
        &lt;!-- enableSubPackages:是否让schema作为包的后缀 --&gt;<br/>
        &lt;property name=&#34;enableSubPackages&#34; value=&#34;false&#34; /&gt;<br/>
    &lt;/javaClientGenerator&gt;<br/>
    &lt;!-- 指定数据库表 --&gt;<br/>
    &lt;table tableName=&#34;items&#34;&gt;&lt;/table&gt;<br/>
    &lt;table tableName=&#34;user&#34;&gt;&lt;/table&gt;<br/>
    &lt;!-- &lt;table schema=&#34;&#34; tableName=&#34;sys_user&#34;&gt;&lt;/table&gt;<br/>
    &lt;table schema=&#34;&#34; tableName=&#34;sys_role&#34;&gt;&lt;/table&gt;<br/>
    &lt;table schema=&#34;&#34; tableName=&#34;sys_permission&#34;&gt;&lt;/table&gt;<br/>
    &lt;table schema=&#34;&#34; tableName=&#34;sys_user_role&#34;&gt;&lt;/table&gt;<br/>
    &lt;table schema=&#34;&#34; tableName=&#34;sys_role_permission&#34;&gt;&lt;/table&gt; --&gt;

&lt;!– 有些表的字段需要指定java类型

     &lt;table schema=&#34;&#34; tableName=&#34;&#34;&gt;<br/>
        &lt;columnOverride column=&#34;&#34; javaType=&#34;&#34; /&gt;<br/>
    &lt;/table&gt; --&gt;<br/>
&lt;/context&gt;<br/>

&lt;/generatorConfiguration&gt;

  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{<br/>
    List&lt;String&gt; warnings = new ArrayList&lt;String&gt;();<br/>
    boolean overwrite = true;<br/>
    File configFile = new File(&#34;config/generatorConfig.xml&#34;);<br/>
    ConfigurationParser cp = new ConfigurationParser(warnings);<br/>
    Configuration config = cp.parseConfiguration(configFile);<br/>
    DefaultShellCallback callback = new DefaultShellCallback(overwrite);<br/>
    MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,<br/>
            callback, warnings);<br/>
    myBatisGenerator.generate(null);<br/>
}<br/>
public static void main(String[] args) throws Exception {<br/>
    try {<br/>
        StartGenerator startService = new StartGenerator();<br/>
        startService.generator();<br/>
    } catch (Exception e) {<br/>
        e.printStackTrace();<br/>
    }<br/>

}
}

 自动生成的文件

 

2、定义接口和实现类

package cn.clj.service;
import java.util.List;
import cn.clj.pojo.Items;
public interface ItemsService {

public List&lt;Items&gt; list() throws Exception;<br/>

}

注意:这里注入了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<br/>
private ItemsMapper itemsMapper;

@Override

public List&lt;Items&gt; list() throws Exception {<br/>
    //selectByExampleWithBLOBs(example)包含文本类型<br/>
    ItemsExample example=new ItemsExample();<br/>
    //example.createCriteria()可以创建查询条件;如果无需任何查询条件,直接将example实例化即可<br/>
    List&lt;Items&gt;  list=itemsMapper.selectByExampleWithBLOBs(example);<br/>
    return list;<br/>
}<br/>

}

3、创建conroller类

@Controller
public class ItemController {

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

}

4、创建itemList.jsp接受参数

&lt;%@taglib uri=“http://java.sun.com/jstl/core_rt&#34; prefix=”c“%&gt;
&lt;body&gt;
&lt;form action=”${pageContext.request.contextPath }/search.action“ method=”post“&gt;
查询条件:
&lt;table width=”100%“ border=1&gt;
&lt;tr&gt;
&lt;!– 如果controller接受的是vo,那么页面上input框中name属性值要等于vo属性.属性 (..)进行引用–&gt;
&lt;td&gt;商品名称:&lt;input type=”text“ name=”items.name“/&gt;&lt;/td&gt;
&lt;td&gt;商品价格:&lt;input type=”text“ name=”items.price“/&gt;&lt;/td&gt;
&lt;td&gt;&lt;input type=”submit“ value=”查询“/&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
商品列表:
&lt;table width=”100%“ border=1&gt;
&lt;tr&gt;

&lt;td&gt;商品名称&lt;/td&gt;<br/>
&lt;td&gt;商品价格&lt;/td&gt;<br/>
&lt;td&gt;生产日期&lt;/td&gt;<br/>
&lt;td&gt;商品描述&lt;/td&gt;<br/>
&lt;td&gt;操作&lt;/td&gt;<br/>

&lt;/tr&gt;
&lt;c:forEach items=”${itemList}“ var=”item“&gt;
&lt;tr&gt;

&lt;td&gt;${item.name}&lt;/td&gt;<br/>
&lt;td&gt;${item.price}&lt;/td&gt;<br/>
&lt;td&gt;&lt;fmt:formatDate value=&#34;${item.createtime}&#34; pattern=&#34;yyyy-MM-dd HH:mm:ss&#34;/&gt;&lt;/td&gt;<br/>
&lt;td&gt;${item.detail}&lt;/td&gt;

&lt;td&gt;&lt;a href=”\({pageContext.request.contextPath }/itemEdit.action?id=\){item.id}“&gt;修改&lt;/a&gt;&lt;/td&gt; &lt;/tr&gt;
&lt;/c:forEach&gt; &lt;/table&gt;
&lt;/form&gt;
&lt;/body&gt;

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

五、SpringMvc值参数绑定

1、关于@RequestParam标签

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

 如:jsp传入一个值

&lt;input type=”text“ name=”item_id“/&gt;

   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<br/>
private ItemsMapper itemsMapper;<br/>
@Override<br/>
public Items findItemsById(Integer id) throws Exception {<br/>
    Items items=itemsMapper.selectByPrimaryKey(id);<br/>
    return items;<br/>
}<br/>

}

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:自动装配(缺点:当一个接口有两个实现类时就无法世识别)<br/>
//Resource:值是取实现类中定义的注解值<br/>
@Autowired<br/>
private ItemsService itemsService;/**<br/>
 * springMvc默认支持的参数类型,也就是说在controller方法中可以加入这些,也可以不加<br/>
 * HttpServletRequest<br/>
 * HttpServletResponse<br/>
 * HttpSession<br/>
 * Model<br/>
 */<br/>
@RequestMapping(&#34;/itemEdit&#34;)<br/>
public String itemEdit(HttpServletRequest request,Model model) throws Exception{<br/>
    String idStr=request.getParameter(&#34;id&#34;);<br/>
    Items items=itemsService.findItemsById(Integer.parseInt(idStr));<br/>
    //Model模型:模型中放入了返回给页面的数据<br/>
    //Model底层就是用的request域传递数据,但是对request进行了扩展<br/>
    model.addAttribute(&#34;item&#34;,items);<br/>
    //如果springMvc方法返回一个简单的string字符串,那么springMvc就会认为这个字符串就是页面的名称<br/>
    return &#34;editItem&#34;;<br/>
}<br/>

}

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

&lt;%@ taglib uri=”http://java.sun.com/jsp/jstl/core&#34; prefix=“c”%&gt;
&lt;body&gt;

&lt;!-- 上传图片是需要指定属性 enctype=&#34;multipart/form-data&#34; --&gt;<br/>
&lt;!-- &lt;form id=&#34;itemForm&#34; action=&#34;&#34; method=&#34;post&#34; enctype=&#34;multipart/form-data&#34;&gt; --&gt;<br/>
&lt;form id=&#34;itemForm&#34;    action=&#34;${pageContext.request.contextPath }/updateitem.action&#34; method=&#34;post&#34;&gt;<br/>
    &lt;input type=&#34;hidden&#34; name=&#34;id&#34; value=&#34;${item.id }&#34; /&gt; 修改商品信息:<br/>
    &lt;table width=&#34;100%&#34; border=1&gt;<br/>
        &lt;tr&gt;<br/>
            &lt;td&gt;商品名称&lt;/td&gt;<br/>
            &lt;td&gt;&lt;input type=&#34;text&#34; name=&#34;name&#34; value=&#34;${item.name }&#34; /&gt;&lt;/td&gt;<br/>
        &lt;/tr&gt;<br/>
        &lt;tr&gt;<br/>
            &lt;td&gt;商品价格&lt;/td&gt;<br/>
            &lt;td&gt;&lt;input type=&#34;text&#34; name=&#34;price&#34; value=&#34;${item.price }&#34; /&gt;&lt;/td&gt;<br/>
        &lt;/tr&gt;<br/>
        &lt;tr&gt;<br/>
            &lt;td&gt;商品简介&lt;/td&gt;<br/>
            &lt;td&gt;&lt;textarea rows=&#34;3&#34; cols=&#34;30&#34; name=&#34;detail&#34;&gt;${item.detail }&lt;/textarea&gt;<br/>
            &lt;/td&gt;<br/>
        &lt;/tr&gt;<br/>
        &lt;tr&gt;<br/>
            &lt;td colspan=&#34;2&#34; align=&#34;center&#34;&gt;&lt;input type=&#34;submit&#34; value=&#34;提交&#34; /&gt;<br/>
            &lt;/td&gt;<br/>
        &lt;/tr&gt;<br/>
    &lt;/table&gt;

&lt;/form&gt;
&lt;/body&gt;

绑定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<br/>
private ItemsMapper itemsMapper;

@Override

public void updateItems(Items items) throws Exception {<br/>
    // TODO Auto-generated method stub<br/>
    //此方法包含大对象文本<br/>
    itemsMapper.updateByPrimaryKeyWithBLOBs(items);<br/>
}

}

2)、创建conroller类定义方法

@Controller
public class ItemController {

//注意:这里可以使用Autowired:自动装配(缺点:当一个接口有两个实现类时就无法世识别)<br/>
//Resource:值是取实现类中定义的注解值<br/>
@Autowired<br/>
private ItemsService itemsService;/**<br/>
 * 更新数据<br/>
 * @return<br/>
 */<br/>
//1.springMvc可以直接接受基本数据类型,包括string,spring Mvc可以帮你自动进行类型转换<br/>
//controller方法接受的参数的变量名称必须要等于页面上input框的name属性值<br/>
//2.springMvc可以直接接受pojo类型,要求页面上input框的name属性名称必须等于pojo的属性名称<br/>
@RequestMapping(&#34;/updateitem&#34;)<br/>
public String updateitem(Items items) throws Exception{      //方式二<br/>
//public String updateitem(Integer id,String name,Float price,String detail) throws Exception{   //方式一<br/>

// Items items=new Items();
// items.setId(id);
// items.setName(name);
// items.setPrice(price);
// items.setDetail(detail);

    //注意:这里jsp源代码中屏蔽了接受时间的框,是因为String类型可以转换为基本类型,但是string类型不能转换为Date类型<br/>
    items.setCreatetime(new Date());//数据库字段定义为非空<br/>
    itemsService.updateItems(items);<br/>
    return &#34;success&#34;;<br/>
}<br/>

}

3)、创建success.jsp页面

 &lt;body&gt;
&lt;h3&gt;更新成功&lt;/h3&gt;
&lt;/body&gt;

解决中文乱码问题

1)针对post请求

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

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

 &lt;!– 解决post乱码问题 –&gt;
&lt;filter&gt;

&lt;filter-name&gt;CharacterEncodingFilter&lt;/filter-name&gt;<br/>
&lt;filter-class&gt;org.springframework.web.filter.CharacterEncodingFilter&lt;/filter-class&gt;<br/>
&lt;init-param&gt;<br/>
  &lt;param-name&gt;encoding&lt;/param-name&gt;<br/>
  &lt;param-value&gt;utf-8&lt;/param-value&gt;<br/>
&lt;/init-param&gt;<br/>

&lt;/filter&gt;
&lt;filter-mapping&gt;

&lt;filter-name&gt;CharacterEncodingFilter&lt;/filter-name&gt;<br/>
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br/>

&lt;/filter-mapping&gt;

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

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

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&lt;String,Date&gt;{ @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上创建自定义转换器,并将它配置到注解驱动上

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

    3) jsp界面

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

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

    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复选框

    &lt;form action=“\({pageContext.request.contextPath }/delAll.action&#34; method=&#34;post&#34;&gt;<br/>
    查询条件:<br/>
    &lt;table width=&#34;100%&#34; border=1&gt;<br/>
    &lt;tr&gt;<br/>
    &lt;!-- 如果controller接受的是vo,那么页面上input框中name属性值要等于vo属性.属性 (..)进行引用--&gt;<br/>
    &lt;td&gt;商品名称:&lt;input type=&#34;text&#34; name=&#34;items.name&#34;/&gt;&lt;/td&gt;<br/>
    &lt;td&gt;商品价格:&lt;input type=&#34;text&#34; name=&#34;items.price&#34;/&gt;&lt;/td&gt;<br/>
    &lt;td&gt;&lt;input type=&#34;submit&#34; value=&#34;批量删除&#34;/&gt;&lt;/td&gt;<br/>
    &lt;/tr&gt;<br/>
    &lt;/table&gt;<br/>
    商品列表:<br/>
    &lt;table width=&#34;100%&#34; border=1&gt;<br/>
    &lt;tr&gt;<br/>
    &lt;td&gt;商品名称&lt;/td&gt;<br/>
    &lt;td&gt;商品价格&lt;/td&gt;<br/>
    &lt;td&gt;生产日期&lt;/td&gt;<br/>
    &lt;td&gt;商品描述&lt;/td&gt;<br/>
    &lt;td&gt;操作&lt;/td&gt;<br/>
    &lt;/tr&gt;<br/>
    &lt;c:forEach items=&#34;\){itemList}” var=“item”&gt;
    &lt;tr&gt;
    &lt;!– 批量删除:name属性名称等于vo中的接受的属性名称 –&gt;
    &lt;td&gt;
    &lt;input type=“checkbox” name=“ids” value=“\({item.id}&#34;/&gt;<br/> &lt;/td&gt;<br/> &lt;td&gt;\){item.name}&lt;/td&gt;
    &lt;td&gt;\({item.price}&lt;/td&gt;<br/> &lt;td&gt;fmt:formatDate value=&#34;\){item.createtime}” pattern=“yyyy-MM-dd HH:mm:ss”/&gt;&lt;/td&gt;
    &lt;td&gt;\({item.detail}&lt;/td&gt;<br/> &lt;td&gt;&lt;a href=&#34;\){pageContext.request.contextPath }/itemEdit.action?id=${item.id}“&gt;修改&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;/c:forEach&gt;
    &lt;/table&gt;
    &lt;/form&gt;

    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&lt;Items&gt; itemsList; //省略set/get,toString()方法 }
  • 2)更改jsp

    &lt;form action=”\({pageContext.request.contextPath }/updateAll.action&#34; method=&#34;post&#34;&gt;<br/>
    查询条件:<br/>
    &lt;table width=&#34;100%&#34; border=1&gt;<br/>
    &lt;tr&gt;<br/>
    &lt;!-- 如果controller接受的是vo,那么页面上input框中name属性值要等于vo属性.属性 (..)进行引用--&gt;<br/>
    &lt;td&gt;商品名称:&lt;input type=&#34;text&#34; name=&#34;items.name&#34;/&gt;&lt;/td&gt;<br/>
    &lt;td&gt;商品价格:&lt;input type=&#34;text&#34; name=&#34;items.price&#34;/&gt;&lt;/td&gt;<br/>
    &lt;td&gt;&lt;input type=&#34;submit&#34; value=&#34;批量修改&#34;/&gt;&lt;/td&gt;<br/>
    &lt;/tr&gt;<br/>
    &lt;/table&gt;<br/>
    商品列表:<br/>
    &lt;table width=&#34;100%&#34; border=1&gt;<br/>
    &lt;tr&gt;<br/>
    &lt;td&gt;商品名称&lt;/td&gt;<br/>
    &lt;td&gt;商品价格&lt;/td&gt;<br/>
    &lt;td&gt;生产日期&lt;/td&gt;<br/>
    &lt;td&gt;商品描述&lt;/td&gt;<br/>
    &lt;td&gt;操作&lt;/td&gt;<br/>
    &lt;/tr&gt;<br/>
    &lt;c:forEach items=&#34;\){itemList}“ var=”item“ varStatus=”status“&gt;
    &lt;tr&gt;
    &lt;!– 如果批量修改,可以用List&lt;pojo&gt;来接受,页面上input框的name属性值=vo中的接受的属性名称+[list的下标]+.+list泛型属性的名称 –&gt;
    &lt;td&gt;
    &lt;input type=”checkbox“ name=”ids“ value=”\({item.id}&#34;/&gt;<br/> &lt;input type=&#34;hidden&#34; name=&#34;itemsList[\){status.index}].id“ value=”\({item.id}&#34;/&gt;<br/> &lt;/td&gt;<br/> &lt;td&gt;&lt;input type=&#34;text&#34; name=&#34;itemsList[\){status.index}].name“ value=”\({item.name}&#34;/&gt;&lt;/td&gt;<br/> &lt;td&gt;&lt;input type=&#34;text&#34; name=&#34;itemsList[\){status.index}].price“ value=”\({item.price}&#34;/&gt;&lt;/td&gt;<br/> &lt;td&gt;&lt;input type=&#34;text&#34; name=&#34;itemsList[\){status.index}].createtime“ value=”&lt;fmt:formatDate value=“\({item.createtime}&#34; pattern=&#34;yyyy-MM-dd HH:mm:ss&#34;/&gt;&#34;/&gt;&lt;/td&gt;<br/> &lt;td&gt;&lt;input type=&#34;text&#34; name=&#34;itemsList[\){status.index}].detail” value=“\({item.detail}&#34;/&gt;&lt;/td&gt;<br/> &lt;td&gt;&lt;a href=&#34;\){pageContext.request.contextPath }/itemEdit.action?id=\({item.id}&#34;&gt;修改&lt;/a&gt;&lt;/td&gt;<br/> &lt;/tr&gt;<br/> &lt;/c:forEach&gt; &lt;/table&gt;<br/> &lt;/form&gt;</pre> <p>3)在controller类中创建接受方法</p> <pre> //批量修改<br/> @RequestMapping(&#34;/updateAll&#34;)<br/> public String updateAll(QueryVo vo) throws Exception{<br/> System.out.println(vo.getItems().getName()); <br/> System.<strong><em>out</em></strong>.println(vo.getItems().getPrice());<br/> return &#34;&#34;;</pre><pre> }</pre> <h2>八、关于spring MVC窄化请求映射</h2> <p>  分析:在团队开发情况下,不同controller中可能出现一个或多个方法RequestMapping值相同,因为配置文件中采用的是包扫描的方法进行映射,就有可能在输入域名的时候跳错controller中的方法。此时,如果为了区分每个conroller中的每个方法,必须配置窄化请求映射,相当于给类起个名字,每当反问域名时,指定跳转方法uri前必须加上这个“类名”,通过此方法对类行进分类管理</p> <p>  如:</p> <pre>@Controller<br/> //窄化请求映射:为防止方法名重名,相当于在url中多加了一层目录,房子重名<br/> @RequestMapping(&#34;/items&#34;)<br/> public class ItemController {<br/> //批量修改<br/> @RequestMapping(&#34;/updateAll&#34;)<br/> public String updateAll(QueryVo vo) throws Exception{<br/> System.out.println(vo);<br/> return &#34;&#34;;<br/> }</pre> <p> 如果以后要跳转到该方法,域名得写成http://localhost:8080/项目名/<strong>items</strong>/updateAll.action</p> <h2>九、spring MVC之请求方法限定</h2> <p>语法为@RequestMapping(value=&#34;/XXX&#34;,<strong>method=</strong><strong>RequestMethod.XX</strong>),其中XX可以写GET或者POST,如果在方法中限定了请求方法而jsp中表单提交方式不是指定的,会报405错误</p> <pre>@RequestMapping(value=&#34;/list&#34;,<strong>method=</strong><strong>RequestMethod.GET</strong>)<br/> public ModelAndView itemsList() throws Exception{<br/> List&lt;Items&gt; list=itemsService.list();<br/> System.out.println(&#34;进入了&#34;);<br/> ModelAndView modelAndView=new ModelAndView();<br/> modelAndView.addObject(&#34;itemList&#34;,list);<br/> modelAndView.setViewName(&#34;itemList&#34;);<br/> return modelAndView;<br/> }</pre> <h2>十、controller类方法返回值</h2> <p>   controller方法返回值包含多种,一下介绍几种常用的:</p> <h3> 1、ModelAndView方式</h3> <pre> @RequestMapping(value=&#34;/list&#34;,method=RequestMethod.GET)<br/> public ModelAndView itemsList() throws Exception{<br/> List&lt;Items&gt; list=itemsService.list();<br/> ModelAndView modelAndView=new ModelAndView();<br/> modelAndView.addObject(&#34;itemList&#34;,list);<br/> modelAndView.setViewName(&#34;itemList&#34;);<br/> return modelAndView;<br/> }</pre> <h3> 2、String方式(直接return一个字符串),返回的数据由model完成</h3> <p> 种类一:放回普通字符串(去掉页面扩展名)</p> <pre>@RequestMapping(&#34;/search&#34;)<br/> public String search(QueryVo vo) throws Exception{<br/> System.out.println(vo);<br/> return &#34;success&#34;;<br/> }</pre> <p> 种类二:请求转发方式</p> <p> 注意:这里是请求转发跳转到同一个Controller中的注解值为itemEdit的方法,请求转发能够携带值</p> <pre> @RequestMapping(&#34;/updateitem&#34;)<br/> public String updateitem(Items items,Model model) throws Exception{<br/> itemsService.updateItems(items);//请求转发:浏览器中的url不发生改变,request域中的数据可以带到转发后的方法中<br/> model.addAttribute(&#34;id&#34;,items.getId());//或者:request.setAttribute(&#34;id&#34;,items.getId())<br/> //springMvc中请求转发:返回的字符串以forward:开头的都是请求转发<br/> return &#34;forward:itemEdit.action&#34;;<br/> }</pre> <p> 种类三:重定向方式</p> <p>  注意:重定向的方式是不能携带值的,如果要传参数,得封装到域名中(如:return &#34;redirect:itemsEdit.action?id=&#34;+items.getId())</p> <pre> @RequestMapping(&#34;/updateitem&#34;)<br/> public String updateitem(Items items,Model model) throws Exception{<br/> itemsService.updateItems(items);<br/> model.addAttribute(&#34;id&#34;,items.getId());//在springMvc中凡是以redirect:字符串开头的的都是重定向<br/> return &#34;redirect:itemsEdit.action&#34;;<br/> }</pre> <p> 种类三:返回值为void</p> <p>  这里演示的请求请求转发的方式(如果controller方法返回值为void,则不走SpringMvc组件,需要些完整的路径名称))</p> <pre> @RequestMapping(&#34;/updateitem&#34;)<br/> public void updateitem(Items items,HttpServletRequest request,HttpServletResponse response) throws Exception{<br/> itemsService.updateItems(items);<br/> request.setAttribute(&#34;id&#34;,items.getId())<br/> request.getRequestDispatcher(&#34;/jsp/success.jsp&#34;).forward(request, response);<br/> }</pre> <h2>十一、spring MVC之全局异常处理</h2> <p>  需求:当条件查询询信息时出现错误(没有该商品),都会跳转到指定的错误页面</p> <h3>  1、定义异常类</h3> <pre>package cn.clj.vo; public class CustomerException extends Exception{<br/> //异常信息<br/> private String message; public CustomerException(String message) {<br/> super();<br/> this.message = message;<br/> }<br/> //省略set/get方法<br/> }</pre> <h3>  2、定义异常处理工具类</h3> <pre>public class GlobalExceptionResolver implements HandlerExceptionResolver{ @Override<br/> public ModelAndView resolveException(HttpServletRequest request,<br/> HttpServletResponse response, Object handler, Exception ex) {<br/> ex.printStackTrace();<br/> CustomerException customerException=null;<br/> if(ex instanceof CustomerException){<br/> customerException=(CustomerException) ex;<br/> }else{<br/> customerException=new CustomerException(&#34;系统错误,请联系管理员&#34;);<br/> }<br/> ModelAndView model=new ModelAndView();<br/> model.addObject(&#34;message&#34;,customerException);<br/> model.setViewName(&#34;error&#34;);<br/> return model;<br/> } }</pre> <h3>  3、创建异常页面error.jsp</h3> <pre>&lt;body&gt;<br/> 您的操作出现错误如下:&lt;br/&gt;<br/> &lt;h3&gt;&lt;font color=&#34;red&#34;&gt;\){message}&lt;/font&gt;&lt;/h3&gt;
    &lt;/body&gt;

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

    &lt;!– 异常处理器 –&gt;
    &lt;bean id=”handlerExceptionResolver“ class=”cn.clj.vo.CustomerException“/&gt;
    &lt;/beans&gt;

      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:\壁纸文件夹下

     &lt;Context docBase=”E:\壁纸“ path=”/pic“ reloadable=”false“/&gt;

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

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

      &lt;!– 文件上传 –&gt;
    &lt;bean id=”multipartResolver“
    class=”org.springframework.web.multipart.commons.CommonsMultipartResolver“&gt;
    &lt;!– 设置上传文件的最大尺寸为5MB –&gt;
    &lt;property name=”maxUploadSize“&gt;
    &lt;value&gt;5242880&lt;/value&gt;
    &lt;/property&gt;
    &lt;/bean&gt;

      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页面

    &lt;form id=”itemForm“    action=”\({pageContext.request.contextPath }/upload.action&#34; method=&#34;post&#34; enctype=&#34;multipart/form-data&#34;&gt;<br/>
        &lt;table width=&#34;100%&#34; border=1&gt;<br/>    &lt;tr&gt;<br/>
          &lt;td&gt;商品图片&lt;/td&gt;<br/>
          &lt;td&gt;<br/>
            &lt;c:if test=&#34;\){item.pic!=null}“&gt;
         &lt;img src=”/pic/\({item.pic}&#34; width=100 height=100/&gt;<br/>       &lt;br/&gt;<br/>      &lt;/c:if&gt;<br/>     &lt;input type=&#34;file&#34; name=&#34;pictureFile&#34;/&gt;<br/>   &lt;/td&gt;<br/>     &lt;/tr&gt;<br/>     &lt;tr&gt;<br/> &lt;td colspan=&#34;2&#34; align=&#34;center&#34;&gt;&lt;input type=&#34;submit&#34; value=&#34;提交&#34; /&gt;<br/> &lt;/td&gt;<br/>    &lt;/tr&gt;<br/>   &lt;/table&gt;<br/> &lt;/form&gt;</pre> <h2>十三、spring MVC之Json</h2> <p> spring MVC是支持Json格式的,需要配置@RequestBody</p> <p> @RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容转换为json、xml等格式的数据并绑定到controller方法的参数上。</p> <p> 需求:利用ajax传送json数据,contoller类定义方法进行接受,并进行相应</p> <h3> 1、导入json依赖jar包</h3> <p><img referrerpolicy="no-referrer" src="https://images2018.cnblogs.com/blog/1226944/201804/1226944-20180408230711722-1492624572.png"/></p> <h3>  2、必须有注解驱动,基于上面环境已经配置,这里无须再配置</h3> <pre> &lt;!-- 注解驱动:能够自动配置最新版的处理器映射器和处理器适配器 --&gt;<br/> &lt;mvc:annotation-driven conversion-service=&#34;conversionService&#34;&gt;&lt;/mvc:annotation-driven&gt;</pre> <h3>  3、导入jquery依赖jar包</h3> <h3>  4、jsp中调用ajax请求</h3> <p>  这里当触发input按钮,就会调用ajax请求</p> <pre>&lt;script type=&#34;text/javascript&#34; src=&#34;\){pageContext.request.contextPath }/js/jquery-1.4.4.min.js“&gt;&lt;/script&gt;
    &lt;script type=”text/javascript“&gt;
    function sendJson(){
    \(.ajax({<br/> type:&#34;post&#34;,<br/> url:&#34;\){pageContext.request.contextPath }/sendJson.action”,
            &lt;!–ajax默认以text文本形式传递,如果要传递json的指定为json–&gt;
    contentType:“application/json;charset=utf-8”,
    data:‘{“name”:“测试商品”,“price”:99.9}’,
    success:function(data){
    alert(data);
    }
    }); }
    &lt;/script&gt;
    &lt;input type=“button” value=“sendJson” onClick=“sendJson()”/&gt;

      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()+“\t”+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”),现在是针对所有对象(“/”)

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

      2) jsp请求书写规范

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

    &lt;a href=“\({pageContext.request.contextPath }/restful/\){item.id}”&gt;修改&lt;/a&gt;

      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配置拦截器(这里是配置全局拦截器)

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

      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”)&gt;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登录界面

       &lt;form action=“${pageContext.request.contextPath}/login/submit” method=“post”&gt;
    &lt;table&gt;
    &lt;tr&gt;
    &lt;td&gt;用户名:&lt;input type=“text” name=“username”/&gt;&lt;/td&gt;&lt;/br&gt;
    &lt;td&gt;密 码:&lt;input type=“text” name=“password”/&gt;&lt;/td&gt;&lt;/br&gt;
    &lt;td&gt;&lt;input type=“submit” value=“登录”/&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;/table&gt; &lt;/form&gt;

      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”;
    }
    }