一、SpringMVC概述
SpringMVC通过一套MVC注解,让POJO成为处理请求的控制器,而无需实现任何接口。
支持REST风格的URL请求
采用了松耦合可插拔组件结构,比其他MVC框架更加具有扩展性和灵活性
二、入门步骤
1)引入jar包
2)配置springmvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.2.xsd"> <!-- 使用注解开发,不用配置controller,需要配置一个组件扫描器,自动扫描的包 --> <context:component-scan base-package="com.ual.demo"/> <!-- 视图解析器:如何把handler方法返回的值解析为实际的物理视图 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 配置从项目根目录到指定目录一端路径 ,建议指定浅一点的目录--> <property name="prefix" value="/WEB-INF/views/"></property> <!-- 文件的后缀名 --> <property name="suffix" value=".jsp"></property> </bean> </beans>
3)配置web.xm
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--配置DispatcherServlet--> <servlet> <servlet-name>SpringDispathcerServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--配置DispatcherServlet的一个初始化参数:配置springMVC配置文件的位置和名称--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <!--服务器一启动,就创建servlet--> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>SpringDispathcerServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
4)配置控制器
package com.ual.demo; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class hellowordHandlers { /** * 使用@RequestMapping注解来映射请求的url * 返回值会通过视图解析器解析为实际的物理视图,对于InternalResourceViewResolver,视图解析器会做如下的解析: *通过 prefix+returnVal+后缀这样的方式得到实际的物理视图,然后做转发操作 * /WEB-INF/views/success.jsp * */ @RequestMapping("/helloword") public String hello(){ System.out.println("hello world"); return "success"; } }
三、@RequestMapping映射请求
1)在控制器的类定义以及方法定义处都可以标注
1.在类定义处:提供初步的请求映射信息,相对于WEB应用的根目录
2.方法处:提供进一步的细分映射信息。相对于类定义处的URL。若类定义处未标明@RequestMapping,则方法处标记的URL相对于WEB应用根目录
若类与方法都有,则页面中的链接应该是类上的URL+方法上的URL,即方法上的URL是相对于类上的URL的
2)@RequestMapping除了可以使用请求URL映射请求外,还可以使用请求方法,请求参数,以及请求头的映射条件。
@RequestMapping的value,method,params及heads分别表示请求URL,请求方法,请求参数及请求头,他们之间是与的关系,联合使用多个条件可以让请求映射更加精确化。
3)params和headers支持简单的表达式
param1:表示请求必须包含名未param1的请求参数
!param1:表示请求不能包含名未param1的请求参数
param1!=value1:表示请求包含名为param1的请求参数,但其值不能为value1
{“param1=value1”,“param2”}请求必须包含名为param1和param2的两个参数,且param1参数的值必须是value1(放在数组里面)
headers与params用法类似,里面写请求头键值对相关
4)支持Ant风格通配符
?:匹配文件名中一个字符
*:匹配文件名中任意字符
**.**:匹配多层路径
5)@PathVariable
@PathVariable可以用来映射URL中的占位符到目标方法的参数中
带占位符的URL是Spring3.0新增的功能,该功能在SpringMVC向REST目标发展中具有里程碑的意义。
通过@PathVariable可以将URL中占位符参数绑定到控制器处理方法的参数里,URL中的{xxx}占位符可以通过@PathVariable(“xxx”)绑定到操作方法的入参中。
四、REST
即Representational State Transfer(资源)表现层状态转化。是目前最流行的一种互联网软件架构。
资源(Resource):网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本,一张图片,一首歌,一种服务,总之就是一个具体的存在。可以用一个(URI)统一资源定位符指向它,每种资源对应一个特定的URI。要获取一个资源,访问它的URI就可以,因此,URI即为每一个资源的独一无二的识别符。
表现层(Representation):把资源具体呈现出来的形式,叫做它的表现层,比如文本可以用txt格式表现,也可以用HTML,XML,JSON表现
状态转换;每发出一个请求,就代表客户端和服务器的一次交互过程。HTTP协议,是一个无状态的协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器发生“状态转换”,而这种状态转换时建立在表现层之上,所以就是“表现层状态转换”。具体就是说,HTTP协议里面,四个表示操作方式的动词:GET,POST,PUT,DELETE。他们分别对应四个基本操作,GET用来获取资源,POST用来新建资源,PUT用来更新资源,DELETE用来删除资源。
示例:
/order/1 HTTP GET:得到id=1的order
/order/1 HTTP DELETE:删除id=1的order
/order/1 HTTP PUT:更新id=1的order
/order/ HTTP POST:新增order
1)添加过滤器
HIddenHttpMethodFIlter:浏览器form表单只支持GET与POST请求,而DELETE,PUT等method并不支持,Spring3.0添加了一个过滤器,可以将这些转为标准的http方法,使得支持DELETE,PUT
在web.xml中配置:
jsp页面 isErrorPage设置为true
REST风格URL:如何发送PUT 请求和DELETE请求?
1.需要配置HIddenHttpMethodFilter
2.需要发送POST请求
3.需要在发送POST请求时,携带一个隐藏域 name=“_method” 值为DELETE或PUT
在SpringMVC的目标方法里,如何得到id?
使用@PathVariable注解映射到一个值
五、映射请求参数&请求参数
1)@RequestParam
使用@RequestParam绑定请求参数值
这种方式,如果请求的时候没有携带参数,就无法跳转页面。这时候可以在对应参数@RequestParam注解里写上required=false(非必需),其默认是true。
总结:@RequestParam
1.value即为请求参数的参数名
2.required该参数是否必须,默认为true
3.defaultValue 请求参数的默认值
2)@RequestHeader
使用@RequestHeader绑定请求报头的属性值
输出:
3)CookieValue
使用@CookieValue绑定请求中的cookie值
4)使用POJO对象绑定请求参数
SpringMVC会按请求参数名和POJO属性名进行自动匹配,自动为该对象填充属性值,支持级联属性。
user类中有一个dog引用类型,dog中有三个属性
5)使用servlet原生API作为入参
六、处理模型数据
SpringMVC提供了一下几种途径输出模型数据
ModelAndView:处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据。
Map及Model:入参为org.springframework.ui.Model,org.springframework.ui.ModelMap或java.ui.Map时,处理方法返回时,Map中的数据会自动添加到模型中。
上面两个方式是把模型数据放在了请求域里。
@SessionAttribute:将模型中的某个属性暂存到HttpSession中,以便多个请求之间可以共享这个属性。
@ModelAttribute:方法入参标注该注解后,入参的对象就会放到数据模型中 。
1)ModelAndView
控制器处理方法的返回值为ModelAndView,则其既包含视图信息,也包含模型数据信息。
目标方法的返回值可以是ModelAndView类型
其中可以包含视图和模型信息
SpringMVC会把ModelAndView的model中的数据放到request域对象中。
去出值:
2)Map及Model
SpringMVC在内部使用了一个org.springframework.ui.Model接口存储模型数据
具体步骤:springMVC在调用方法前会创建一个隐含的模型对象作为模型数据存储容器。如果方法的入参为Map或Model类型,springMVC会将隐含的模型传递给这些入参。在具体方法内,开发者可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据。
目标方法可以添加map类型的参数,这个参数还可以是ModelAndMap或Model类型。
success中取出:
3)@SessionAttributes(模型数据放入session域) 注意:这个注解只能放在类的上面
若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个@SessionAttributes,springMVC将在模型中对应的属性暂存到HttpSession中。
@SessionAttributes除了可以通过属性名指定需要放到会话中的属性外(实际上使用了注解里的value属性值),还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(实际上使用了注解里的type属性值)。
取出数据:
4)@ModelAttribute
有@ModelAttribute标记的方法,会在每个目标方法执行之前被springMVC调用。
运行流程:模拟从数据库中取出对象,而不是自己新建,从表单获取部分字段进行对象属性的修改,而未获取的字段保留数据库取出时的值
1.执行@ModelAttribute标注的方法,从数据库中取出对象,把对象放入到了map中,键为user
2.springMVC从map中取出user对象,并把表单的请求参数赋给该user对象的对应属性(自动帮我们做了)
3.springMVC把上述对象传入目标方法的参数
注意:@ModelAttribute修饰的方法中,放入到map时的键需要和目标方法入参类型的第一个字母小写的字符串一致。
密码还是1234,名字改为了tom
若不是首字母小写,则在目标方法入参中也要写上@ModelAttribute
在这种方式下,目标方法会在请求域中找键值为abc的对象,如果有,则将abc对应的对象传递给方法入参。
当@ModelAttribute修饰有返回值的方法: