1.
@RequestMapping
- 用来映射请求的URL
- 该注解可以添加到类上,也可以添加到方法上
@RequestMapping
(
"/springMVC"
)
//
该@RequestMapping中的
url
相对于当前项目的
根目录
@Controller
//标识当前类是一个控制器(处理器)
public
class
HelloSpringMVC {
/**
* 方法的返回值会通过在SpringMVC的配置文件中配置的视图解析器InternalResourceViewResolver
* 解析为实际的物理视图,然后进行自动转发
*
* 物理视图 = prefix + returnValue + suffix
* 即:/WEB
-
INF/views/success.jsp
*
*
* 如果类上添加了@RequestMapping
*
-
该@RequestMapping中的
url
相对于类上的@RequestMapping中的
url
* 如果类上添加了@RequestMapping
*
-
该@RequestMapping中的
url
相对于当前项目的根目录
*/
@RequestMapping
(
"/hello"
)
public
String helloSpringMVC(){
System.
out
.println(
"你的请求我已经收到"
);
return
"success"
;
}
}
- @RequestMapping中的属性
/**
*
@RequestMapping中的属性
*
★1.value属性
(值是String类型的
数组
):
*
-
用来设置要
映射的请求地址
*
★ 2.method属性
(值是RequestMethod类型的
数组
):
*
-
用来设置要
处理的请求的请求方式
*
-
注意:如果没有指定该属性,那么只要URL匹配,什么请求方式我都可以处理
* 3.
params
属性(值是String类型的数组):
*
-
用来设置要映射的请求URL中包含或者不包含哪些请求参数
* 4.headers属性(值是String类型的数组):
*
-
用来设置要映射的请求URL中包含哪些请求头的信息
*/
@RequestMapping
(value={
"/testValue"
,
"/testValue2"
})
public
String testValue(){
System.
out
.println(
"测试@RequestMapping中的value属性"
);
return
SUCCESS
;
}
@RequestMapping
(value=
"/testMethod"
,method=RequestMethod.
POST
)
public
String testMethod(){
System.
out
.println(
"测试@RequestMapping中的method的属性"
);
return
SUCCESS
;
}
@RequestMapping
(value=
"/testParams"
,params={
"username=admin"
,
"age!=18"
})
public
String testParams(){
System.
out
.println(
"测试@RequestMapping中的params的属性"
);
return
SUCCESS
;
}
@RequestMapping
(value=
"/testHeaders"
,headers=
"Accept-Language=zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4"
)
public
String testHeaders(){
System.
out
.println(
"测试@RequestMapping中的headers的属性"
);
return
SUCCESS
;
}
- Ant风格的URL
/**
* Ant风格的URL
* ?:匹配 一个字符
* *:匹配多个字符
* **:匹配多层路径
*/
@RequestMapping
(
"/testAnt/*/ant"
)
public
String testAnt(){
System.
out
.println(
"测试Ant风格的请求地址"
);
return
SUCCESS
;
}
2.
@PathVariable
- 用来将REST风格的URL中的请求参数绑定到Handler(处理器)方法的入参中
- 该注解中的属性
- value属性:用来@RequestMapping中的URL中的占位符
- REST风格的规定
- GET请求
- 用来获取资源
- POST请求
- 用来添加资源
- PUT请求
- 用来修改资源
- DELETE请求
- 用来删除资源
- 但是form表单只支持GET和POST请求,如果要发送PUT和DELETE请求需要在web.xml中配置HiddenHttpMethodFilter这个过滤器将POST请求转换为PUT请求和DELETE请求
- GET请求
<!-- 注册HiddenHttpMethodFilter
目的是为了将POST请求转换为PUT请求和DELETE请求
-->
<
filter
>
<
filter-name
>
HiddenHttpMethodFilter
</
filter-name
>
<
filter-class
>
org.springframework.web.filter.HiddenHttpMethodFilter
</
filter-class
>
</
filter
>
<
filter-mapping
>
<
filter-name
>
HiddenHttpMethodFilter
</
filter-name
>
<
url-pattern
>
/*
</
url-pattern
>
</
filter-mapping
>
- 要想将POST请求转换为PUT和DELETE请求,前端表单中还需要传一个请求参数,参数名是_method,参数值是PUT或者DELETE
- 前端发送REST风格请求的超链接和表单
<
a
href
=
"
${pageContext.request.contextPath }
/springMVC/testRest/10"
>
testRest_Get
</
a
><
br
>
<
form
action
=
"
${pageContext.request.contextPath }
/springMVC/testRest"
method
=
"post"
>
<
input
type
=
"submit"
value
=
"REST_POST"
>
</
form
>
<
form
action
=
"
${pageContext.request.contextPath }
/springMVC/testRest/100"
method
=
"post"
>
<!-- 通过设置一个隐藏域将HiddenHttpMethodFilter需要的_method的值传过去 -->
<
input
type
=
"hidden"
name
=
"_method"
value
=
"PUT"
>
<
input
type
=
"submit"
value
=
"REST_PUT"
>
</
form
>
<
form
action
=
"
${pageContext.request.contextPath }
/springMVC/testRest/250"
method
=
"post"
>
<!-- 通过设置一个隐藏域将HiddenHttpMethodFilter需要的_method的值传过去 -->
<
input
type
=
"hidden"
name
=
"_method"
value
=
"delete"
>
<
input
type
=
"submit"
value
=
"REST_DELETE"
>
</
form
>
针对上述Rest风格的URL,可以利用
拼接进行转发
- Handler中的处理请求的方法
/**
* 传统的URL REST风格的URL
* getUser?userId=1 获取 getUser/1 GET请求 获取
* saveUser 添加 saveUser POST请求 添加
* updateUser?userId=1 更新 updateUser/1 PUT请求 更新
* deleteUser?userId=1 删除 deleteUser/1 DELETE请求 删除
*/
//测试REST风格的GET请求
@RequestMapping
(value=
"/testRest/{id}"
,method=RequestMethod.
GET
)
public
String testREST_Get(
@PathVariable
(
"id"
) Integer
id
){
System.
out
.println(
"你要获取的用户的id是:"
+
id
);
return
SUCCESS
;
}
//测试REST风格的POST请求
@RequestMapping
(value=
"/testRest"
,method=RequestMethod.
POST
)
public
String testREST_Post(){
System.
out
.println(
"你正在向数据库中插入用户"
);
return
SUCCESS
;
}
//测试REST风格的PUT请求
@RequestMapping
(value=
"/testRest/{id}"
,method=RequestMethod.
PUT
)
public
String testREST_Post(
@PathVariable
(
"id"
) Integer
id
){
System.
out
.println(
"你要更新的用户的id是:"
+
id
);
return
SUCCESS
;
}
//测试REST风格的DELETE请求
@RequestMapping
(value=
"/testRest/{id}"
,method=RequestMethod.
DELETE
)
public
String testREST_Delete(
@PathVariable
(
"id"
) Integer
id
){
System.
out
.println(
"你要删除的用户的id是:"
+
id
);
return
SUCCESS
;
}
3.
@RequestParam
- 用来将传统方式的URL中的请求参数或者表单中的请求参数绑定到方法的入参中
- 该注解只能添加到方法的入参前面
- 该注解中的三个属性
- value:用来设置要映射的请求参数的参数名
- required:用来设置该参数是否是必须的,默认是true,是必须的
- defaultValue:用来设置参数的默认值
- 另外:@RequestHeader和@CookieValue也有以上三个属性
/**
* ★@RequestParam的使用
*
-
用来将传统的请求地址中的请求参数或者是表单中的请求参数绑定的方法的入参中
*
-
该注解只能添加到方法入参的前面
* 属性:
*
-
value:用来设置请求参数的参数名
*
-
注意:如果Handler中的方法的入参的参数名与请求参数的参数名一致,@RequestParam注解可以省略,但是建议加上
*
-
required:用来设置该请求参数是否是必须的。默认是true,是必须的
*
-
defaultValue:用设置一个默认值
*
*
@RequestHeader的使用
*
-
用来
将请求头中的信息绑定到方法的入参中
*
-
该注解
只能添加到方法入参的前面
*
@CookieValue的使用
*
-
用来
将请求头中的Cookie对应的值绑定到方法的入参中
*
-
该注解
只能添加到方法入参的前面
*
-
@RequestHeader和@CookieValue中的属性与@RequestParam中的属性一样
*/
@RequestMapping
(
"/testRequestParam"
)
public
String testRequestParam(
@RequestParam
(
"username"
) String
u
,
@RequestParam
(value=
"age"
,required=
false
,defaultValue=
"0"
)
int
age
){
System.
out
.println(
"测试@RequestParam注解"
);
System.
out
.println(
"用户名是:"
+
u
);
System.
out
.println(
"年龄是:"
+
age
);
return
SUCCESS
;
}
@RequestMapping
(
"/testRequestHeader"
)
public
String testRequestHeader(
@RequestHeader
(
"Referer"
) String
referer
){
System.
out
.println(
"测试@RequestHeader注解"
);
System.
out
.println(
"你从这儿来:"
+
referer
);
return
SUCCESS
;
}
@RequestMapping
(
"/testCookieValue"
)
public
String testCookieValue(
@CookieValue
(
"JSESSIONID"
) String
sessionId
){
System.
out
.println(
"测试@CookieValue注解"
);
System.
out
.println(
"Cookie对象的值或者说是Session对象的ID值是:"
+
sessionId
);
return
SUCCESS
;
}
- 将表单中的数据自动封装到POJO对象中然后绑定到方法的入参中
- 前端表单中的name属性值必须要与POJO类中的属性名要保持一致,而且支持级联属性
- 类
public
class
Employee {
private
Integer
id
;
private
String
lastName
;
private
String
email
;
private
Department
dept
;
}
public
class
Department {
private
Integer
id
;
private
String
name
;
}
- 前端表单
<
form
action
=
"
${pageContext.request.contextPath }
/testPOJO"
method
=
"post"
>
工号:
<
input
type
=
"text"
name
=
"id"
><
br
>
姓名:
<
input
type
=
"text"
name
=
"lastName"
><
br
>
邮箱:
<
input
type
=
"text"
name
=
"email"
><
br
>
部门编号:
<
input
type
=
"text"
name
=
"dept.id"
><
br
>
部门名称:
<
input
type
=
"text"
name
=
"dept.name"
><
br
>
<
input
type
=
"submit"
value
=
"Test_POJO"
>
</
form
>
- Handler中的测试方法
/**
* ★Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值。支持级联属性
*
@return
*/
@RequestMapping
(
"/testPOJO"
)
public
String testPOJO(Employee
employee
){
System.
out
.println(
"员工的信息是:"
+
employee
);
return
SUCCESS
;
}
- Handler中的方法中的入参支持的原生的ServletAPI
/**
* Handler的方法中可以支持一下参数作为方法的入参
* HttpServletRequest
HttpServletResponse
HttpSession
java.security.Principal
Locale
InputStream
OutputStream
Reader
Writer
*
*/
@RequestMapping
(
"/testServletAPI"
)
public
String testServletAPI(HttpServletRequest
request
, HttpServletResponse
response
){
System.
out
.println(
request
);
System.
out
.println(
response
);
return
SUCCESS
;
}
实验证明:
@RequestMapping
(
"/testServletAPI"
)
public
String testServletAPI(HttpServletRequest
request
, HttpServletResponse
response
) {
System.
out
.println(
request
);
System.
out
.println(
response
);
String
username
=
request
.getParameter(
"username"
);
System.
out
.println(
username
);
return
"success"
;
}
通过这种方式也是可以得到表单所提交的数据
4.处理模型数据
- 将Handler的方法的返回值设置为ModelAndView类型
- 1)创建ModelAndView对象
- 2)设置数据模型
- 3)设置视图
/**
* 通过ModelAndView对象来处理模型数据
*
-
SpringMVC会将ModelAndView对象中的模型数据放到
request域中
,然后转发到对应的
jsp
页面
*
@return
*/
@RequestMapping
(
"/testModelAndView"
)
public
ModelAndView testModelAndView(){
//1.创建ModelAndView对象
ModelAndView
mv
=
new
ModelAndView();
//2.设置模型数据
mv
.addObject(
"time"
,
new
Date());
//3.设置视图
mv
.setViewName(
"success"
);
return
mv
;
}
获取
<h1>request域中的时间是:${requestScope.time }</h1>
- 通过在Handler的方法的入参中传入Map、Model、ModelMap
/**
*
不管是使用ModelAndView对象还是在方法的入参中传入Map、ModelMap或者Model,
*
SpringMVC都会转换为一个ModelAndView对象
,然后在视图解析器InternalResourceViewResolver
* 解析的InternalResourceView中
将模型数据放到了request域中,然后进行请求的转发,转发
jsp
视图页面
*
@param
map
*
@return
*/
@RequestMapping
(
"/testMap"
)
public
String testMap(
Map<String , Object>
map
){
//map的实现类是BindingAwareModelMap
System.
out
.println(
map
.getClass());
//向map中添加模型数据
map
.put(
"time"
,
new
Date());
return
SUCCESS
;
}
5.
@SessionAttributes
- 用来将模型数据放到session域中
- 该注解只能添加到类上
- 该注解中的属性:
- value:通过指定key将模型数据放到session域中
- type:通过指定数据的类型将模型数据放到session域中
/*
* @SessionAttributes的使用
* -用来将模型数据放到session域中
* -该注解只能添加到类上
* 该注解中的属性:
* -value:通过指定key将模型数据放到session域中
* -type:通过指定数据的类型将模型数据放到session域中
*/
@SessionAttributes
(value=
"user"
,types=String.
class
)
@Controller
public
class
SpringMVCHandler {
@RequestMapping
(
"/testSessionAttributes"
)
public
String testSessionAttributes(Map<String , Object>
map
){
//向map中添加一个Employee模型数据
map
.put(
"school"
,
"尚硅谷"
);
return
SUCCESS
;
}
}
6.
@ModelAttribute(☆☆
☆☆
☆
)
- 添加了该注解的方法会在所有的目标方法执行之前调用
- 该注解可以添加到方法上,也可以添加到方法的入参前面
/**
* ★@ModelAttribute的使用
*
-
添加了该注解的方法会在所有的目标方法执行之前调用
*
-
该注解可以添加到方法上,也可以添加到方法入参的前面
*
* 使用了@ModelAttribute注解之后的运行流程:
*
1.
通过添加了@ModelAttribute注解的
方法
获取的User对象会被放到一个叫implicitModel的Map中
*
2.
SpringMVC从implicitModel中取出User对象,然后将表单中提交的修改之后的属性设置到User对象中
*
3.
SpringMVC从implicitModel中取出User对象,然后传入到目标方法中
*
*/
@ModelAttribute
public
void
getUser(
@RequestParam
(value=
"id"
,required=
false
) Integer
id
,Map<String , Object>
map
){
System.
out
.println(
"我在目标方法执行之前调用……"
);
if
(
id
!=
null
){
//根据用户的id从数据库中获取User对象(假设以下new的就是从数据库中查询出来的)
//将user放到map中
map
.put(
"u"
,
user
);
}
}
//也可以通过以下方式获取User对象
// @ModelAttribute
// public User getUser(@RequestParam(value="id",required=false) Integer id){
// User user = null;
// if(id != null){
// //根据用户的id从数据库中获取User对象(假设以下new的就是从数据库中查询出来的)
// }
// return user;
// }
/**
* 目标方法入参User对象获取的流程:
* 1.先确定从Map中取User对象的key
*
-
如果
入参前面
添加了@ModelAttribute注解,那么
key就是@ModelAttribute注解中指定的value属性值
*
-
如果
入参前面
没有添加了@ModelAttribute注解,
k
ey就是参数的类型的首字母小写
入参前面指的是下面下划线部分()中参数前面是否加
@ModelAttribute注解。
* 2.确定了key之后怎么获取User对象
*
-
1)以1中的key从implicitModel中去查找
*
-
2) 如果在implicitModel中找不到,获取去session域中查询(
前提是对应的类上添加了@SessionAttributes
){
这个前提是必须类(这里指的是user)必须实现序列化
}
*
-
如果找到了对应的key,没有找到对应的值,则会抛出以下异常:
* Session attribute 'user' required
-
not found in session
*
-
如果找到了对应的key以及值则将User对象传到方法的入参中
* 3.如果通过1和2都得不到User对象,那么SprigMVC将创建一个新的User对象,然后将表单中的属性设置到User对象中
*
*/
@RequestMapping
(
"/testModelAttribute"
)
public
String
testModelAttribute(@ModelAttribute("u") User
user
)
{
System.
out
.println(
"更新后的User对象的信息是:"
+
user
);
return
SUCCESS
;
}
@ModelAttribute最好单独写一个,不要和
@RequestMapping一起写,因为
@RequestMapping里边有value值必须得写地址传入。