SpringMvc介绍
SpringMvc入门程序
Springmv框架讲解
a) 框架结构
b) 组件说明
SSM整合(SpringMvc + Spring + MyBatis)
参数绑定(重点)
a) Springmvc默认支持的类型
b) 简单数据类型
c) Pojo类型
d) Pojo包装类型
e) 自定义转换器
第二天
a) 数组类型的参数绑定
b) List类型的绑定
@RequestMapping注解的使用(重点)
Controller方法返回值(重点)
Springmvc中异常处理
图片上传处理
Json数据交互
Springmvc实现Restful
拦截器
SpringMVC是Spring组织下的一个表现层框架。和Struts2一样。它是Spring框架组织下的一部分。我们可以从Spring的整体结构中看得出来:
{width=”3.5194805336832897in”
height=”2.8379604111986003in”}
接收Web请求中的参数
把处理好的数据返回给页面
1. Struts2太老
Struts2繁多的XML配置、非容器化的设计都已经不符合现代软件系统的需求,特别是分布式和微服务的大型系统平台中更使得Struts2捉襟见肘。
2. Struts2的安全性差
之前的某些版本曾经存在重大安全隐患,并成功被黑客利用,也造成过一些企业的损失,这也加速了Struts2的迅速老去。
所以说SpringMVC是完全对Struts2的更新换代。同时SpringMVC是Spring自家产品,因此它们直接的整合是无缝的,自然通用的,性能兼容性都是最好的。
要想引入SpringMVC做表现层开发,最基本的需要完成两件事:
1. 配置前端控制器。
2. 开发后端控制器。
Jdk:jdk1.7.0_72
Eclipse:mars
Tomcat:apache-tomcat-7.0.53
Springmvc:4.1.3
说明:
作为本课练习对jdk,eclipse版本的要求不严格。
但在实际项目中团队的开发版本是有严格要求的,最新版本不代表是最好的,实际项目都选用最稳定的版本。
{width=”3.090551181102362in”
height=”2.559055118110236in”}
{width=”2.7142858705161856in”
height=”3.9424201662292213in”}
在web工程中拷贝到lib文件夹下的jar包可以自动被导入工程
{width=”2.031496062992126in”
height=”1.3425196850393701in”}
spring原生jar包:
{width=”1.8503937007874016in”
height=”2.7086614173228347in”}
Spring常用依赖jar包:
{width=”1.3031496062992125in”
height=”0.8976377952755905in”}
【web.xml】是整个web请求的入口配置文件
<说明>
·前端控制器:
org.springframework.web.servlet.DispatcherServlet,它是SpringMVC接收web请求的第一入口,也是唯一入口。这是一个servlet对象,因此需要在web.xml中进行配置。
·常用URL样式:
[/*]: SpringMvc禁止使用,不支持。
[*.action]: 以.action为结尾的url地址请求可以进入DispatcherServlet,
放行所有资源文件后缀的url。
[/]: 域名后面所有url地址目录均被DispatcherServlet拦截,
只放行.jsp为结尾的url,其他资源文件后缀的url都不放行(这个明天的RESTful的时候会具体用到,
今天先不讲)
资源文件请求url:
<%=basePath%>css/bootstrap.min.css”
rel=”stylesheet”>
·
此项配置是控制当前servlet是否随tomcat启动而被加载
配置的值必须是整数
值 >=
0:表示当前servlet随着tomcat启动而被加载,值的大小表示加载的顺序,越小越优先
值 <
0:表示当前servlet不会随着tomcat启动而被加载,只有当它被使用的时候才加载。
DispatcherServlet启动后会立刻去找SpringMVC的配置文件,然后根据配置文件中的内容进行加载和扫描
·
在DispatcherServlet的初始化过程中加载SpringMVC的配置文件
·SpringMVC默认配置文件:
如果没有显示的配置SpringMVC的核心配置文件,SpringMVC会去[/WEB-INF/]下找默认的核心配置文件。默认核心配置文件的命名:*servlet-name的值
+
-servlet.xml。*在实际工作中要知道:当发现web.xml没有配置核心配置文件时要知道去[/WEB-INF/]下找它的默认配置文件。
因为各种框架的默认配置文件的位置可能不同,所以企业很少采用默认的配置文件路径,因此我们需要统一规划配置文件的存放位置,通过手动配置完成配置文件的加载。
“1.0” encoding=“UTF-8”?>
xmlns=”http://java.sun.com/xml/ns/javaee”
xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd”
id=“WebApp_ID” version=“2.5”>
springmvc前端控制器 –>
tomcat启动而被加载 –>
url路径可以进入DispatcherServlet –>
新建一个source folder: config
{width=”5.427060367454068in”
height=”1.5833333333333333in”}
{width=”2.2125984251968505in”
height=”1.2125984251968505in”}
在config下创建一个xml文件:
SpringMvc.xml,文件头可以从其他地方直接拷贝过来。
“1.0” encoding=“UTF-8”?>
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: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://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd”>
到此为止SpringMvc基本框架搭建完成,启动tomcat,日志中不报错,就说明环境搭建成功。
下面就是入门程序的开发。
使用SpringMVC实现商品列表的展示。
要展示全部商品列表,所以不需要参数,请求url:
http://localhost:8080/<具体web应用的名字>/list.action
主要关注SpringMvc的入门程序,所以暂不考虑连接数据库等多余功能,在业务处理中只做假的模拟数据返回给页面。
创建jsp页面的目录:
{width=”1.4416666666666667in”
height=”1.0493055555555555in”}
前端页面不是本课内容,参考:
参考资料\参考案例\jsp\itemList.jsp直接拷贝到工程jsp目录中。
问题:放在WebContent目录下和放到WEB-INFO目录下的区别?
WEB-INFO是受tomcat保护目录,它里面的文件只能由servlet去访问,不能通过url地址栏去请求访问。
WebContent下的文件可以直接通过url地址栏去访问,一般的欢迎页和静态资源文件都放在这里。
1. 创建包:
cn.itcast.controller用于存放后端控制器,cn.itcast.pojo用于存放保存返回数据的bean
{width=”2.16875in” height=”1.1944444444444444in”}
2. 创建后端控制器:
<说明>
·@Controller:
用这个注解将一个Java类声明成SpringMVC的后端控制器,可以被扫描。
package cn.itcast.controller;
import org.springframework.stereotype.Controller;
// 定义一个java类,@Controller注解标注在类定义的上方表明这个类需要SpringMVC扫描。
@Controller
public class ItemsController {
}
在SpringMvc.xml中配置组件扫描
<说明>
扫描指定包及子包下的@Controller、@Service、@Repository、@Component等注解修饰的java类。
“1.0” encoding=“UTF-8”?>
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: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://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd”>
注意:
如果想扫描多个包,可以配置多个
注解类型的Controller类中使用@RequestMapping修饰的方法响应url请求。一个url对应一个方法。不可能多个url同时对应一个方法,也不可能多个方法同时响应一个url请求。
<说明>
@RequestMapping(“/具体URL”) 或 @RequestMapping(value=”/具体URL”):
是SpringMVC注解,表示如果请求路径匹配,被注解的方法将被调用。以【/】开头,如果不写【/】也可以,推荐写。
SpringMVC启动加载时会扫描@RequestMapping注解,将注解中的url作为key,方法作为value,形成url到方法的映射关系,放到一个map对象里,具体过程:
{width=”4.846456692913386in”
height=”3.1929133858267718in”}
<说明>
模型对象,是SpringMVC默认支持的一种形参类型,由SpringMVC自动创建,使用时只需定义在方法形参上即可。
作用:可以向Model参数中添加页面需要的变量(属性名)和结果值(属性值),SpringMVC会负责将Model中的变量赋值给request对象,这样JSP就可以用EL表达式从request对象中取得这个变量(属性名)的数据了。(*赋值request对象就是调用了request.setAttribute(属性名,
属性值)方法完成的。*)
package cn.itcast.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import cn.itcast.pojo.Items;
// 定义一个java类,@Controller注解标注在类定义的上方表明这个类需要SpringMVC扫描。
@Controller
public class ItemsController {
// 标注url到请求方法的key/value对应关系
@RequestMapping(“/list”)
public String list(Model model) throws Exception {
//商品列表(临时数据)
List
Items items1 = new Items();
items1.setName(“联想笔记本”);
items1.setPrice(6000f);
items1.setDetail(“ThinkPad T430 联想笔记本电脑!”);
Items items2 = new Items();
items2.setName(“苹果手机”);
items2.setPrice(5000f);
items2.setDetail(“iphone6苹果手机!”);
itemsList.add(items1);
itemsList.add(items2);
// 1. 设置返回给页面的数据
// 第一个参数是属性名称, 第二个参数是属性值
model.addAttribute(“itemsList”, itemsList);
// 2. 指定返回页面的地址
return “/WEB-INF/jsp/itemList.jsp”;
}
}
ModelAndView形参类似Model,但额外提供了一个视图名称,因此上述代码也可以改成如下:
@Controller
public class ItemsController {
// 标注url到请求方法的key/value对应关系
@RequestMapping(“/list”)
public ModelAndView list(ModelAndView modelAndView) throws Exception {
//商品列表(临时数据)
List
。。。。。。
// 1. 设置返回给页面的数据
// 第一个参数是属性名称, 第二个参数是属性值
modelAndView.addObject(“itemsList”, itemsList);
// 2. 指定返回页面的地址
modelAndView.setViewName(“/WEB-INF/jsp/itemList.jsp”);
return modelAndView;
}
}
ModelAndView因为是一个类,所以它既可以通过方法声明(由SpringMVC帮我们构造,如上例),也可以在方法中自己构造,上面的例子也可以写成:
@Controller
public class ItemsController {
// 标注url到请求方法的key/value对应关系
@RequestMapping(“/list”)
public ModelAndView list() throws Exception {
//商品列表(临时数据)
List
。。。。。。
ModelAndView modelAndView = new ModelAndView();
// 1. 设置返回给页面的数据
// 第一个参数是属性名称, 第二个参数是属性值
modelAndView.addObject(“itemsList”, itemsList);
// 2. 指定返回页面的地址
modelAndView.setViewName(“/WEB-INF/jsp/itemList.jsp”);
return modelAndView;
}
}
注意:Model不能在方法中自己构造,因为Model本身是一个接口,所以只能由SpringMVC帮助实例化。
总结:上面三种给页面赋值的方法中推荐使用第一种和第二种,第三种麻烦,所以很少使用。
访问地址: http://localhost:8080/springmvc/list.action
{width=”7.268055555555556in”
height=”0.7631944444444444in”}
上面直接返回jsp视图的物理名称很直接,但是每个方法都返回一长串路径看着有点乱和冗余,每个方法返回的路径中【/WEB-INF/jsp/】和【.jsp】都是重复的。
通过配置视图解析器的前缀和后缀可以简化视图名称。(配置视图解析器的作用)
【SpringMVC.xml】中视图解析器前缀和后缀的配置:
“1.0” encoding=“UTF-8”?>
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: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://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd”>
配置之后,代码简化:(直接把去掉前缀和后缀剩下的部分返回即可)
······
// 2. 指定返回页面的地址
return “itemList”;
······
(只给出了第一中使用Model的简化代码,其他的可以自行完成。)
逻辑视图名:Controller方法中简化后的字符串。
物理视图名 = 前缀 + 逻辑视图名 + 后缀。
SpringMVC能保证每次返回的字符串都会自动走视图解析器,然后按照上面的方式拼接,再进行后续处理。
掌握(重点):后端控制器开发中@Controller、@RequestMapping、Model(ModelAndView)的使用,会在SpringMVC的配置文件中配置注解扫描和视图解析器的前缀和后缀。
了解(非重点):前端控制器在web.xml中的配置方式。
注意:对于配置文件中出现的很长的类名不需要完全记忆,能叫出一个大概的名字即可,或者能说出这个类是干什么的而记不住名字也没关系。
学习框架结构的目的: 开发不用, 但面试时会问到
框架结构详细内容:(面试题)
说明:前端控制器是接收web请求的入口,地位最重要。如果还要做其他具体的工作会使它的负担过于繁重,因此SpringMVC找来了四个帮手,叫做四个组件,来帮助前端控制器承担一些具体的工作,这样前端控制器就只发号司令做为集中控制调度中心,具体的工作交给四个组件来完成。
具体工作分为两部分:
1) 处理器映射器负责找到URL对应的Handler对象
2) 处理器适配器负责执行找到的Handler对象。
1) 视图解析器负责找到要返回的页面
2) 视图对象负责渲染页面,渲染页面需要的数据由前端控制器传给它。
●啥是freemaker?
就是模版, 通过模版和数据生成输出的文本(HTML网页, 电子邮件等).
比如网易首页点击进入的一个html页面,
这些静态的html都是由freemarker生成的, 而struts2只支持jsp.
用户发送请求至前端控制器DispatcherServlet
DispatcherServlet收到请求调用HandlerMapping处理器映射器。
处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet
DispatcherServlet通过HandlerAdapter处理器适配器[[[]{#OLE_LINK29
.anchor}]{#OLE_LINK30 .anchor}]{#OLE_LINK28 .anchor}调用处理器
执行处理器(handler也叫后端控制器–>Service–>DAO)
Handler执行完成返回ModelAndView
HandlerAdapter将handler执行结果ModelAndView返回给DispatcherServlet
DispatcherServlet将ModelAndView传给ViewReslover视图解析器
ViewReslover根据handler中设置的页面信息解析成一个View视图对象并返回它.
DispatcherServlet调用View对象的接口方法对实际的视图文件(如:
jsp文件)进行渲染(即将模型数据填充至视图文件中)
DispatcherServlet响应用户
SpringMVC的整个控制层采用组件式的结构。
SpringMVC的组件有:
·前端控制器DispatcherServlet、
·处理器映射器HandlerMapping、
·处理器适配器HandlerAdapter、
·视图解析器ViewResolver
·处理器Handler(相对于前端控制器的后端控制器)、
·视图对象View。
组件的重要性:
·前端控制器最重要,是整个Spring表现层的中枢;
·除了前端控制器,最重要的是HandlerMapping、HandlerAdapter、ViewResolver,它们称为SpringMVC的三大核心组件,为接收用户请求和返回结果给用户在各自岗位发挥着关键作用;
·Handler是SpringMVC用来包装方法对象的类,保存在HandlerMapping的map中;
·View由ViewResolver生成,负责渲染页面。
DispatcherServlet负责接收用户请求,是整个流程的控制中心,但它几乎不做任何具体的工作,只进行任务调度。具体的工作由具体的组件来完成。这就是组件式结构的优势,专项事情又专门的组件来做,这样能提高专项的处理能力同时集中调度的存在降低了组件之间的耦合性。
在DispatcherServlet的控制下Handler对具体的用户请求进行处理。
由于Handler涉及到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发Handler。
HandlerMapping负责为每个请求找到一个合适的处理器handler,其实简单来说就是维持了一个url到handler的映射Map。springmvc提供了不同的映射器,实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
比如注解方式的映射器会根据核心配置文件中配置的
/>指定的包路径(包括子目录)进行扫描,找@Controller标注的Java类,该类中所有使用@RequestMapping修饰的方法都是一个handler对象,并根据@RequestMapping的值作为key,对应的方法的handler对象作为value,形成一个url到方法的k/v键值对映射。而且这种扫描只要在tomcat启动时做一次,不会影响系统的性能。
{width=”0.8653849518810148in”
height=”0.8653849518810148in”}
{width=”0.7948709536307962in”
height=”0.7948709536307962in”}
{width=”0.7371784776902888in”
height=”0.7371784776902888in”}
适配器的作用:统一调用接口,好扩展。
Springmvc中的处理器适配器:
处理器适配器HandlerAdapter负责执行具体的处理器。
SpringMVC有多个适配器,当HandlerMapping找到了url对应的handler对象后,前端控制器会挑选一个能够执行这个handler的处理器适配器,然后给这个适配器发送指令,同时把这个handler对象传给这个适配器,让它执行handler,最终将handler的返回值和逻辑视图名字符串返回给前端控制器。
视图解析器(ViewResolver)负责解析出视图文件的物理路径,并根据这个路径生成视图View对象。
ViewResolver首先把逻辑视图名解析成实际的页面位置,再生成视图View对象并返回给前端控制器。
View对象负责渲染视图文件,将数据结果通过视图文件展示给用户。前端控制器调用View对象的接口方法render(),参数就是后台返回的数据,在render方法拿数据渲染视图文件生成返回给客户端的结果。
springmvc框架提供了很多的View类型,包括:jstlView、freemarkerView、pdfView等。
视图文件可以是jsp、pdf、freemaker等,最常用的就是jsp。一般情况下需要通过页面jsp标签或页面模版将处理器返回的model数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。
Springmvc三大组件配置在核心配置文件中,springmvc支持组件免配置、显示配置和企业的配置方法
即什么都不配。此时SpringMVC仍然可以正常运行,全凭它自己的DispatcherServlet.properties,会从中找到合适的组件去执行。这个属性文件的位置:
{width=”1.2077919947506561in”
height=”2.9225174978127733in”}
如果没有显示配置三大组件(其中一个或者全部),依靠这个属性文件中的默认配置组件,springmvc也能正确的执行。
a) 处理器映射器
{width=”6.694444444444445in”
height=”0.24753937007874016in”}
a) 处理器适配器
{width=”6.694444444444445in”
height=”0.39721456692913387in”}
a) 视图解析器
{width=”6.6875in” height=”0.13482392825896763in”}
默认的视图解析器只有一个。
每次请求都要去这里去找合适的组件,所以执行效率很低,因此什么都不配置是不可取的。需要我们显示配置来提高执行效率。
{width=”6.944444444444445in”
height=”0.6283573928258968in”}
{width=”6.909722222222222in”
height=”0.5935258092738408in”}
{width=”6.895833333333333in”
height=”0.3638888888888889in”}作用:帮助我们显式配置当前Spring版本的最新的注解形式的处理器映射器和处理器适配器
好处:简化配置,一劳永逸
答:
都需要配置,两个东西的作用完全不一样,不要混淆视听。
注解驱动:作用就是替我们显式的配置当前spring版本下最新版本的注解形式的处理器映射器和处理器
适配器
注解扫描:扫描指定包及子包下的@Controller、@Service、@Repository等注解修饰的java类,其
中@Controller修饰的类注册为SpringMVC的组件,其它注解修饰的类注册为Spring的
组件。
{width=”6.465277777777778in”
height=”1.1644422572178477in”}
前面已经学过,此处只给出配置的例子。
处理器映射器、适配器:提高执行效率
视图解析器(有前缀和后缀):简化编码
掌握(重点):
此处主要是把框架结构图理解成自己的话能够描述出来。
SpringMVC三大组件的最终形态的显示配置方法。
了解:
Springmvc默认组件配置;
单独配置新版的处理器映射器和处理器适配器。
下面是完整的springmvc核心配置文件的配置:SpringMVC.xml
“1.0” encoding=“UTF-8”?>
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: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://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd”>
作用:SpringMVC可以自动去扫描指定包以及子包下的java文件,如果扫描到有@Controller(控制层的类)
@Service(业务层的类) @Repository(数据库访问层的类)这些注解修饰的类,则把这些类注册为
SpringMVC的组件
–>
如果没有显示的配置三大组件,SpringMVC也能正常执行,是因为会默认去找SpringMVC的默认
属性文件DispatcherServlet.properties,从中找到合适的三大组件去执行。但这种方式在么次
请求的时候都会去找一遍,所以效率很低,因此采用默认的三大组件选择是不可取的。
我们应该显示的配置它们,这样可以提高系统的访问效率。
–>
–>
–>
–>
–>
作用:显示的配置了当前Spring版本下最新的注解形式的处理器映射器和处理器适配器。由于它
没有和任何class关联,所以即使Spring版本升级,该项配置也不会发生任何改动,企业中
喜欢采用这种一劳永逸的方法。
–>
作用:利用显示配置视图解析器中的前缀和后缀可以简化Controller方法中的视图信息的设置,只需
在setViewName方法中设置逻辑视图名称(视图文件的名称,比如jsp文件)即可。每次视图解
析器都会自动的进行视图文件物理路径的拼接:前缀 + 逻辑视图名称 + 后缀。从而方便了我们的
编码工作。
–>
{width=”2.35042760279965in”
height=”0.7638888888888888in”}
{width=”1.867361111111111in”
height=”0.7638888888888888in”}
{width=”0.972150043744532in”
height=”0.8125in”}
整合的步骤是固定的, 过程是可以复制的,
人家告诉我们怎么整合就怎么来做就可以了.
具体来说, 第一是你手头有现成的资料照着做即可; 第二如果你没有资料,
怎么办? 这时候如果能记住思路, 我们就可以上网去找资料.
但如果思路记不住就连资料怎么找都不知道了, 所以说思路是很重要的, 要记住.
首先,先划分大层次,整合后分为三层:表现层 业务层
数据访问层,再加上web.xml这是整体的骨架;
其次,再逐层规划每一层具体要干什么。
ssm整合的思路如下:
Spring与MyBatis的整合在MyBatis第二天的时候已经学习过了,这里仍然沿用。SpringMVC与Spring又是一家的,所以它们之间是不需要整合配置的,即所谓的无缝整合,直接就可以用,只不过需要在web.xml中配置它们两个。具体规划如下:
SSM整合分三层:DAO层、Service层、Controller层
代码目录:
·Controller层:
controller:Controller类——用@Controller注解修饰,让SpringMVC来扫描
·Service层:
service:service接口和实现类——用@Service注解修饰,让Spring来扫描
·DAO层:
dao:dao接口文件和映射文件——用Mybatis动态代理包扫描
pojo:java bean
配置目录:
·config:
SpringMVC.xml——注解扫描(Controller层的组件扫描)、注解驱动、视图解析器(可能带有前缀和后缀)
ApplicationContext-service.xml——注解扫描(service层的组件扫描)、事务管理
ApplicationContext-dao.xml——数据源、连接池、会话工厂、MyBatis动态代理包扫描
(以上两个配置文件可以配置在一个文件中,这里为了体现分层的思路所以分开配置。)
MyBatisConfig.xml——空配置(预留,好扩展)
web.xml:
Spring监听(管理service层和dao层)
SpringMVC前端控制器(管理Controller层)
前端:
Jsp视图——在【/WEB-INF/】创建jsp目录,存放jsp页面
静态资源文件(js、css。。。)——在【WebContent】创建js、css等存放这些资源文件。
面试题:事务配置在哪一层?为什么?
事务配置在service层,因为service层控制的是业务,在一个service中有可能调用多个DAO中的方法进行一系列的操作,这些操作要么都成功,要么都失败。比如汇款,汇出操作成功了,但是存入给另一个人时发现卡被注销了,这个时候要整个业务回滚,否则钱就会丢失,所以必须在service层做事务控制。
注意:
不要纠结Controller层的类域Service层的类能否放到一个目录下。这个问题没有意义,因为分层的意思就是强制将它们分开,Controller层的目录就放Controller的类,Service层的目录就放Service的类,DAO层的目录就放Dao的类。
配置文件是否合并的问题,这个问题也不要纠结,看个人喜好,如果想让配置文件单一化,就可以把两个ApplicationContext文件合并,但SpringMVC.xml与ApplicationContext不要合并,因为前者是表现层由Spring的子集框架SpringMVC专门负责,后者是业务层以及DAO层由Spring本身自己负责。
Jdk: jdk1.7.0_72
Eclipse: mars
Tomcat: apache-tomcat-7.0.53
Springmvc: 4.1.3
MyBatis: mybatis-3.2.7
MySql: 5.1.28
SM整合包: 1.2.2
使用【资料\参考案例\sql】下的创建库建表脚本【springmvc.sql】创建我们使用的数据库环境。
{width=”2.7777777777777777in”
height=”1.9404374453193352in”}
{width=”3.1023622047244093in”
height=”2.5669291338582676in”}
{width=”1.9427580927384076in”
height=”2.582147856517935in”}
{width=”3.1319444444444446in”
height=”2.333996062992126in”}
{width=”2.5972222222222223in”
height=”2.3313167104111985in”}
将【资料\jar\ssm整合后jar全集】下的jar包拷贝到WebContent/WEB-INF/lib下,
会自动关联到工程中
根据思路创建工程目录:
{width=”1.8789271653543307in” height=”2.6875in”}
{width=”2.1805555555555554in”
height=”1.510158573928259in”}
修改配置文件符合当前的开发环境和目录结构。
a. 数据库名
b. Pojo包名
c. Mybatis映射文件的包名
d. Mybatis映射接口的包名(与c相等)
e. 需要生成代码的数据库表
注意:
a. 执行前要把原先旧的代码全部删除。
b. 执行完生成程序后第一次刷新的时候表现出来的包名不对,再刷新一次就好了。这是eclipse的一个bug。
将生成的代码拷贝到我们的工程中去。
{width=”2.0294356955380577in”
height=”2.673611111111111in”}
{width=”4.013888888888889in”
height=”0.6504451006124234in”}
整理mybatis的配置文件:
a. MyBatisConfig.xml:清空
b. ApplicationContext.xml:保留其中的属性文件、数据源(连接池)、会话工厂、动态代理包扫描的配置,其他的都删除。根据上面的思路它应该属于dao层的spring配置文件,改名为ApplicationContext-dao.xml
c. 其他配置文件保持不变。
修改后的配置文件:
【MyBatisConfig.xml】
“1.0” encoding=“UTF-8”?>
PUBLIC “-//mybatis.org//DTD Config 3.0//EN”
“http://mybatis.org/dtd/mybatis-3-config.dtd“>
【ApplicationContext-dao.xml】
“1.0” encoding=“UTF-8”?>
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”>
创建【ApplicationContext-service.xml】,@Service注解组件的扫描和事务管理
【ApplicationContext-service.xml】
“1.0” encoding=“UTF-8”?>
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”>
class=“org.springframework.jdbc.datasource.DataSourceTransactionManager”>
pointcut=“execution(* cn.itcast.service.*.*(..))” />
创建【SpringMvc.xml】,配置@Controller注解组件扫描,注解驱动,视图解析器
配置文件:
【SpringMvc.xml】
“1.0” encoding=“UTF-8”?>
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: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://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd”>
配置spring的容器监听、springmvc前端控制器以及它可接收的url地址。
配置文件:
【web.xml】
“1.0” encoding=“UTF-8”?>
springmvc的前端控制器–>
springmvc核心配置文件的位置 –>
tomcat启动时就加载当前的servlet –>
springmvc前端控制器能够接收的url结尾格式 –>
本节的重点是要掌握整合的思路,有了思路就可以寻着线索进行整合了,不用死记具体的过程。
{width=”1.8907611548556431in” height=”4.4375in”}
使用SSM从数据库查询数据, 实现真正的商品列表的展示.
沿用SpringMvc入门程序.
在此基础上完成service层的代码, 定义service接口和实现类,
并用@autowired自动注入DAO接口对象.
完善controller层代码, 用@autowired自动注入service接口对象.
定义ItemsService.java接口
定义ItemsServiceImpl.java实现类,实现这个接口
代码:
【ItemsService.java】
package cn.itcast.service;
import java.util.List;
import cn.itcast.pojo.Items;
public interface ItemsService {
public List
}
【ItemsServiceImpl.java】
package cn.itcast.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import cn.itcast.dao.ItemsMapper;
import cn.itcast.pojo.Items;
@Service
public class ItemsServiceImpl implements ItemsService {
@Autowired
ItemsMapper itemsMapper;
@Override
public List
// 通过自动生成的接口方法查询商品列表
List
return list;
}
}
注意:selectByExample(null)只检索除了大对象数据类型之外的字段,但items表中有一个detail字段的类型是text,为了把它也检索出来可以使用selectByExampleWithBLOBs(null)这个方法。
package cn.itcast.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import cn.itcast.dao.ItemsMapper;
import cn.itcast.pojo.Items;
public class ItemsServiceImpl implements ItemsService {
@Autowired
ItemsMapper itemsMapper;
@Override
public List
/*
* 注意:
* selectByExample只检索除了大对象数据类型之外的项目
* selectByExampleWithBLOBs检索包含大对象数据类型的项目
*/
// 通过自动生成的接口方法查询商品列表
List
return list;
}
}
把入门程序中的【ItemsController.java】拷贝过来
修改里面的【lsit()】方法,调用service接口的方法完成查询。
代码:
【ItemsController.java】
package cn.itcast.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import cn.itcast.pojo.Items;
import cn.itcast.service.ItemsService;
@Controller
public class ItemsController {
@Autowired
private ItemsService itemsService;
@RequestMapping(“/list”)
public ModelAndView list() throws Exception {
List
// 1. 设置返回页面需要的数据 2. 指定返回页面的地址
ModelAndView modelAndView = new ModelAndView();
// 1. 设置返回页面需要的数据
modelAndView.addObject(“itemList”, itemsList);
// 2. 指定返回页面的地址
modelAndView.setViewName(“itemList”);
return modelAndView;
}
}
从【资料\参考案例\jsp】中导入【itemList.jsp】到工程的jsp目录下
访问地址: http://localhost:8080/springmvc/list.action
{width=”7.268055555555556in”
height=”0.9291666666666667in”}
数据库:
{width=”7.268055555555556in”
height=”0.6513888888888889in”}
到本节为止,一个完整的ssm整合就完成了。我们从最初的springmvc入门程序,到认识三大核心组件,到最后ssm整合形成完整的web系统,这就是一个web系统的学习进化过程。
掌握(重点):
整合的分层思路以及各层代码的编写
了解:
SSM开发环境搭建,这个环境搭建不是大家掌握的重点,只是作为了解,基本会搭即可。
Springmvc作为表现层框架,是后端程序的入口,它负责接收页面HTTP请求(POST/GET)过来的参数,参数可以是【url后面拼接的】,也可以是【页面控件的值】,也可以是【hidden变量的值】,也可以是【ajax提交的js对象】,也可以是【ajax提交的json字符串】等等。这也体现了本课开始时说的SpringMVC的第一个作用:“接收请求中的参数”。
接收的参数具体有哪些类型呢?
Model(ModelAndView)
Java简单类型:int,long,double,String,Long,Double,Boolean,Integer等
POJO类型
POJO的包装类型-QueryVo
前面我们做完了商品列表画面的展示,下面继续做修改页面和保存修改。
【修改页面】:根据id查询这条数据的详细信息,然后显示在修改页面
【保存修改】:在修改页面修改信息,然后点【保存】,把信息存到数据库,保存成功迁移到success页面。
下面主要通过简单示例演示各种类型参数的传递,这里的重点是参数如何接收,并不是页面功能的实现,因此有些功能不真正实现,只做到参数正常接收即可。
·用默认支持的参数类型定义的方法接收显示【修改页面】的查询参数;(实现)
·用Java简单类型参数定义的方法接收更新商品信息功能的更新参数;(实现)
·用POJO类型参数定义的方法改进上面的更新功能;(实现)
·用POJO的包装POJO的参数类型定义的方法接收查询条件参数;(不实现)
·针对日期类型,利用自定义转换器Converter实现字符串到日期类型转换,进一步丰富【保存修改】功能;(实现)
所谓默认支持的参数类型就是传不传它们都会存在的参数,想用时就在Controller方法中定义即可,用哪个定义哪个,不用不定义。
默认参数有:
HttpServletRequest:通过request对象获取请求信息
HttpServletResponse:通过response处理响应信息
HttpSession:通过session对象得到session中存放的对象
Model(ModelAndView):通过数据模型参数返回需要传递给页面的数据。
{width=”7.268055555555556in”
height=”0.1763888888888889in”}
<说明>
·HttpServletRequest:
可以接收页面传递过来的参数。
·Model:前面讲过,略
/**
* 演示默认支持的类型参数:HttpServletRequest、HttpServletResponse、HttpSession、Model
* 默认支持的参数类型就是传不传它们都存在的参数,想用时就在Controller方法中定义即可,
* 用哪个就定义哪个,不用就不定义。
*/
@RequestMapping(“/toEdit”)
public String itemEdit(HttpServletRequest request, Model model) throws Exception {
// 取得页面传过来的主键id
Integer id = Integer.valueOf(request.getParameter(“id”));
Items itemsResult = itemsService.getItemsDetailById(id);
// 设置返回给页面的数据
model.addAttribute(“item”, itemsResult);
// 返回页面的逻辑视图名
return “editItem”;
}
public Items findItemsById(Integer id) throws Exception;
public Items findItemsById(Integer id) throws Exception {
Items items = itemsMapper.selectByPrimaryKey(id);
return items;
}
默认参数类型有一个缺点:用request.getParameter来取值可能需要额外的类型转换,从String转成其他类型。
Springmvc可不可以直接接收这些类型的参数呢?答案是可以的,即直接接收简单类型的参数。Springmvc不仅可以直接接收多个简单类型参数,还可以自动进行简单的类型转换。
页面提交的控件name属性值必须等于Controller方法的形参名。
从【资料\参考案例\jsp】中导入【editItem.jsp】到工程的jsp目录下。
【ItemsController.java】新定义一个方法
/**
* 演示接收简单类型:String, Integer, Double, Boolean等
* 要求:页面上input框的name属性值必须等于controller方法中接收时的参数的变量名称
*/
@RequestMapping(“/itemUpdate”)
public String itemUpdate(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);
itemsService.updateItems(items);
return “success”;
}
public void updateItems(Items items) throws Exception;
public void updateItems(Items items) throws Exception {
itemsMapper.updateByPrimaryKeySelective(items);
}
从【资料\参考案例\jsp】中导入【success.jsp】到工程的jsp目录下。
进入修改页面修改信息并保存。
web页面默认的编码是ISO8859-1,但这个编码不支持汉字,所以汉字参数传递过来会出现乱码。
post请求乱码的解决方法:在web.xml中加一个过滤器解决。
“1.0” encoding=“UTF-8”?>
xmlns=”http://java.sun.com/xml/ns/javaee”
xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd”
id=“WebApp_ID” version=“2.5”>
。。。。
。。。。
对于get请求中文参数乱码,只在Tomcat7中存在,T8和T9已经解决了这个问题。Tomcat7解决方法有两个:
{width=”7.268055555555556in”
height=”0.5506944444444445in”}
{width=”7.268055555555556in” height=”0.56875in”}
如果Controller方法形参不符合传参规范,可以使用@RequestParam注解进一步限定请求参数到方法形参的映射关系。
属性:
·value:指明请求的参数名称,参数名和形成名一致时,value属性可以省略。
·required:boolean类型,声明此请求参数是否必须有,true的时候如果没有,则报错。
·defaultValue:字符类型,如果请求参数没有提供,可以指定一个默认字符串,Spring会自动将字符串转化为形参的目标类型(当然这种类型转化必须是简单类型转化)。
/**
* 演示接收简单类型:String, Integer, Double, Boolean等
* 使用@RequestParam注解限定请求参数到方法形参的映射关系
*/
@RequestMapping(“/updateitem”)
public String updateItemsById(
@RequestParam(required=true) Integer id,
@RequestParam String name,
@RequestParam(defaultValue=”100”) Float price,
@RequestParam(value=”detail”) String itemDetail) throws Exception {
Items items = new Items();
items.setId(id);
items.setName(name);
items.setPrice(price);
items.setDetail(itemDetail);
itemsService.updateItemById(items);
return “common/success”;
}
实现对修改保存的改进,适应参数个数的变化,几十上百个参数时候是绝对不可能用简单类型传递参数的。
页面提交的控件name属性值必须等于Controller方法形参对象中的属性名。
【ItemsController.java】新定义一个保存更新的方法,将旧的注释掉
/**
* 演示接收简单类型:String, Integer, Double, Boolean等
* 要求:页面上input框的name属性值必须等于controller方法中接收时的参数的变量名称
*/
// @RequestMapping(“/itemUpdate”)
// public String itemUpdate(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);
// items.setCreatetime(new Date());
// itemsService.updateItems(items);
// return “success”;
// }
/**
* 演示接收POJO类型的参数
* 要求:页面上input框的name属性值必须等于pojo中的属性名称
*
* @return
* @throws Exception
*/
@RequestMapping(“/itemUpdate”)
public String itemUpdate(Items items)
throws Exception {
itemsService.updateItems(items);
return “success”;
}
我们要想在列表页面加一个综合查询功能,查询条件可能有商品信息、用户信息、订单信息,因此我们需要一个QueryVo来包装这些查询信息。那如何传递包装的参数呢?
页面提交控件的name属性值必须等于Controller方法形参对象中的属性.属性.属性….。
package cn.itcast.pojo;
public class QueryVo {
// 用户对象
// ……
// 订单对象
// ……
// 商品对象
private Items items;
public Items getItems() {
return items;
}
public void setItems(Items items) {
this.items = items;
}
}
<%@ page language=“java” contentType=“text/html; charset=UTF-8”
pageEncoding=“UTF-8”%>
<%@ taglib uri=”http://java.sun.com/jsp/jstl/core” prefix=“c” %>
<%@ taglib uri=”http://java.sun.com/jsp/jstl/fmt” prefix=“fmt”%>
“Content-Type” content=“text/html; charset=UTF-8”>
/**
* 演示接收POJO的包装类型 - QueryVo
* 要求: 页面上input框的name属性值必须等于POJO中属性.属性.属性…..
*
* @param vo
* @return
* @throws Exception
*/
@RequestMapping(“/search”)
public String searchItems(QueryVo vo) throws Exception {
System.out.println(vo);
return “success”;
}
当前端参数传递过来时SpringMVC会根据方法形参的类型定义进行类型转换,但是如果转换的类型比较复杂SpringMVC并没有针对复杂类型转换的处理对象时,就需要自定义转换器来处理,否则会报错。
比如:前台传递的是一个时间格式的字符串,后台数据库存储的是一个日期类型的数据,如果我们自己不做任何处理直接传递的话,会报错(400错误),需要我们自定义日期格式字符串到Date的转化方式。
将【editItem.jsp】中的【商品生产日期】项目的注释打开
自定义转换器Converter
Converter的包名可以随意,我们这里定义一个全局的String到Date的转换器。
都要继承【Converter】接口,【S - source源的类型】,【T -
target目标的类型】,我们这里的S是String,T是Date。
{width=”2.5078740157480315in”
height=”1.2244094488188977in”}
package cn.itcast.controller.converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
/**
* S - source源的类型
* T - target目标的类型
*/
public class CustomGlobalStrToDateConverter implements Converter
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;
}
}
【SpringMVC.xml】
“1.0” encoding=“UTF-8”?>
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: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://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd”>
class=“org.springframework.format.support.FormattingConversionServiceFactoryBean”>
这种方式放到工程里不好用,就是用来理解Converter具体作用在处理器适配器上。
“1.0”*encoding=“UTF-8”*?>
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”>
class=“org.springframework.format.support.FormattingConversionServiceFactoryBean”>
–>
jsp前缀 –>
jsp后缀 –>
注意:此方法需要独立配置处理器映射器、适配器,不再使用
5. 【ItemsController.java】
/**
* 演示接收POJO类型的参数
* 要求:页面上input框的name属性值必须等于pojo中的属性名称
*/
@RequestMapping(“/itemUpdate”)
public String itemUpdate(Items items)
throws Exception {
itemsService.updateItems(items);
return “success”;
}
再次启动运行。
由上例可知自定义转换器的作用:特定类型之间的复杂转化。凡是符合自定义的源类型和目标类型的参数都会被转换器处理。比如:上例中String到Date的转换。
再比如:实现输入一个字符串转换成一个自定义的业务对象。(这种时候,这个字符串应该是有一定格式的,根据格式进行内容的分离,然后创建出对应的业务对象)
{width=”4.600767716535433in”
height=”3.8333333333333335in”}
如果仅仅是日期类型的转化可以不用自定义转换器,还有一种更简单的做法:直接在pojo对应的日期属性变量上面加注解
@DateTimeFormat(pattern=”yyyy-MM-dd
HH:mm:ss”),因此SpringMVC.xml恢复原来的配置
【SpringMVC.xml】
“1.0” encoding=“UTF-8”?>
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: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://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd”>
【Items.java】在pojo中对应的日期属性变量上使用注解@DateTimeFormat
public class Items {
。。。。。。
@DateTimeFormat(pattern=”yyyy-MM-dd HH:mm:ss”)
private Date createtime;
。。。。。。
}
启动测试,这样也是可以进行String到Date的类型转换的。
注意格式:【yyyy-MM-dd HH:mm:ss】
SpringMVC负责接收HTTP请求的参数,各种类型参数要遵守各自的规范,具体如下:
默认支持的参数类型:HttpServletRequest,HttpServletResponse,HttpSession,Model(ModelAndView)。用哪个就在方法的形参中定义哪个,不用的不定义。
简单类型:String,long,double,boolean,Integer等
要求:页面提交的控件name属性值必须等于Controller方法的形参名。
适合单个或少数参数的请求。
也可以用@RequestParam注解来接收参数,解决名称对不上或者对参数做进一步的限定。
要求:页面提交的控件name属性值必须等于Controller方法形参对象中的属性名。
适合多参数、不固定参数个数的请求。
要求:
页面提交控件的name属性值必须等于Controller方法形参对象中的属性.属性.属性….。适合综合查询条件参数的传递。
作用:特定类型之间的复杂转化。
日期转化用@DateTimeFormat更方便。
以根据id查询商品详细信息的请求为例:(Chrome中的请求信息截图)
{width=”7.1744083552056in”
height=”3.138888888888889in”}
GET请求的参数是以k1=v1&k2=v2&k3=v3&……这样的样式拼接在url的后面用问号?分开。
以更新商品信息的请求为例:(Chrome中的请求信息截图)
{width=”7.268055555555556in”
height=”4.163194444444445in”}
POST请求的参数也是以k1=v1&k2=v2&k3=v3&……这样的样式拼接的,只不过是包装在Form表单中传递,在url的后面看不到。
大家不要被HTTP请求的形式给蒙蔽了,参数样式的实质都相同。它们都是一样的HTTP请求参数,即都是k1=v1&k2=v2&k3=v3&……的形式连接成一个字符串整体提交给后台,其中汉字由浏览器转码。
所以在SpringMVC端接收GET/POST请求参数的方法和规则都是相同的。
springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。
Struts2是类级别的拦截,一个Action类对应一个request上下文;
SpringMVC是方法级别的拦截,一个Controller类的方法对应一个request上下文。
Struts2是基于类开发,传递参数是通过Action类的属性,只能设计为多例。
Springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(默认是单例)。
Struts接收的请求参数存放于Action的属性中,是诸多方法共享的,程序可读性差。Struts采用值栈存储请求和响应的数据,通过OGNL存取数据;值栈存储方式太过原始。
Springmvc通过参数解析器是将request请求内容解析并给方法形参赋值,即请求参数是方法之间独立的。Springmvc对数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques对象传输到页面。