SpringMVC 学习笔记
SpringMVC
ServletAPI
SpringMVC 支持使用原始 ServletAPI 对象作为控制器方法的参数,支持原始 ServletAPI 对象有:
- HttpServletRequest
- HttpServletResponse
- HttpSession
- java.security.Principal
- Locale
- InputStream
- OutputStream
- Reader
- Writer
我们可以直接把这些对象写在控制的方法参数中使用
1 |
|
常用注解
@RequestParam
- 把请求中指定名称的参数给控制器中的形参赋值。
- 属性:
- value: 请求参数中的名称。
- required: 请求参数中是否必须提供此参数。默认值:true。表示必须提供,如果不提供将报错。
1
2
3
4
5
6@RequestMapping("/useRequestParam")
public String useRequestParam(@RequestParam("name") String username,
@RequestParam(value="age",required=false) Integer age){
System.out.println(username+","+age);
return "success";
}@RequestBody
- 用于获取请求体内容。直接使用得到是 key=value&key=value... 结构的数据。
- get 请求方式不适用。
- 属性:
- required: 是否必须有请求体。默认值是:true。当取值为 true 时,get 请求方式会报错。如果取值 为 false,get 请求得到是 null。
@PathVaribale
- 用于绑定 url 中的占位符。例如:请求 url 中
/delete/{id}
,这个{id}就是 url 占位符 - url 支持占位符是 spring3.0 之后加入的,是 springmvc 支持 rest 风格 URL 的一个重要标志。
- 属性:
- value: 用于指定 url 中占位符名称。
- required: 是否必须提供占位符。
1
2
3
4
5@RequestMapping("/usePathVariable/{id}")
public String usePathVariable(@PathVariable("id") Integer id){
System.out.println(id);
return "success";
}- 用于绑定 url 中的占位符。例如:请求 url 中
@RequestHeader
- 用于获取请求消息头。
- 在实际开发中一般不怎么用。
- 属性:
- value: 提供消息头名称。
- required: 是否必须有此消息头。
@CookieValue
- 用于把指定 cookie 名称的值传入控制器方法参数。
- 属性:
- value:指定 cookie 的名称。
- required:是否必须有此 cookie。
1
2
3
4
5@RequestMapping("/useCookieValue")
public String useCookieValue(@CookieValue(value="JSESSIONID",required=false) String cookieValue){
System.out.println(cookieValue);
return "success";
}@ModelAttribute
- 用来将请求参数绑定到 Model 对象。
- 需要注意的是,因为模型对象要先于 controller
方法之前创建,所以被 @ModelAttribute 注解的方法会在
Controller 每个方法执行之前都执行。因此一个 Controller 映射多个 URL
时,要谨慎使用。
- 因此可以用作控制登录权限,当然控制登录权限的方法有很多,例如拦截器、过滤器等。
1 |
|
接受请求参数
Spring MVC Controller 接收请求参数的方式有很多种,有的适合 get 请求方式,有的适合 post 请求方式,有的两者都适合。主要有以下几种方式:
通过实体 Bean 接收请求参数
通过处理方法的形参接收请求参数
通过 HttpServletRequest 接收请求参数
通过 @PathVariable 接收 URL 中的请求参数
通过 @RequestParam 接收请求参数
- 和通过实体 Bean 接收请求参数相比会报404错误
通过 @ModelAttribute 接收请求参数
@ModelAttribute
注解用于将多个请求参数封装到一个实体对象中,从而简化数据绑定流程,而且自动暴露为模型数据,在视图页面展示时使用通过实体 Bean 接收请求参数中只是将多个请求参数封装到一个实体对象,并不能暴露为模型数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27// 通过实体Bean接受请求参数
@RequestMapping("/login")
public String login(User user, Model model) {
if ("bianchengbang".equals(user.getName())
&& "123456".equals(user.getPwd())) {
model.addAttribute("message", "登录成功");
return "main"; // 登录成功,跳转到 main.jsp
} else {
model.addAttribute("message", "用户名或密码错误");
return "login";
}
}
// 通过@ModelAttribute接受请求参数
@RequestMapping("/login")
public String login(@ModelAttribute("user") User user, Model model) {
if ("bianchengbang".equals(name)
&& "123456".equals(pwd)) {
model.addAttribute("message", "登录成功");
return "main"; // 登录成功,跳转到 main.jsp
} else {
model.addAttribute("message", "用户名或密码错误");
return "login";
}
}
重定向和转发
重定向(redirect):将用户从当前处理请求定向到另一个视图(例如 JSP)或处理请求,以前的请求(request)中存放的信息全部失效,并进入一个新的 request 作用域。
转发(forward):将用户对当前处理的请求转发给另一个视图或处理请求,以前的 request 中存放的信息不会失效。
转发是服务器行为,重定向是客户端行为。
转发过程
客户浏览器发送 http 请求,Web 服务器接受此请求,调用内部的一个方法在容器内部完成请求处理和转发动作,将目标资源发送给客户;在这里转发的路径必须是同一个 Web 容器下的 URL,其不能转向到其他的 Web 路径上,中间传递的是自己的容器内的 request。
在客户浏览器的地址栏中显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。
重定向过程
客户浏览器发送 http 请求,Web 服务器接受后发送 302 状态码响应及对应新的 location 给客户浏览器,客户浏览器发现是 302 响应,则自动再发送一个新的 http 请求,请求 URL 是新的 location 地址,服务器根据此请求寻找资源并发送给客户。
在这里 location 可以重定向到任意 URL,既然是浏览器重新发出了请求,那么就没有什么 request 传递的概念了。在客户浏览器的地址栏中显示的是其重定向的路径,客户可以观察到地址的变化。重定向行为是浏览器做了至少两次的访问请求。
特别的
在 Spring MVC 框架中,不管是重定向或转发,都需要符合视图解析器的配置,如果直接转发到一个不需要 DispatcherServlet 的资源,例如:
1 |
|
则需要使用 mvc:resources 配置:
1 |
|
Model和ModelAndView
Model:每次请求中都存在的默认参数,利用其 addAttribute() 方法即可将服务器的值传递到客户端页面中。
ModelAndView:包含 model 和 view 两部分,使用时需要自己实例化,利用 ModelMap 来传值,也可以设置 view 的名称。
类型转换器
Converter<S, T>将一种数据类型转换成另一种数据类型的接口,源类型可以是任意数据类型。
//TODO
格式化转换器
Formatter<T>将一种数据类型转换成另一种数据类型的接口,源类型必须是 String 类型。
//TODO
HiddentHttpMethodFilter
作用
由于浏览器 form 表单只支持 GET 与 POST 请求,而 DELETE、PUT 等 method 并不支持,Spring3.0 添加了一个过滤器,可以将浏览器请求改为指定的请求方式,发送给我们的控制器方法,使得支持 GET、POST、PUT 与 DELETE 请求。
使用方法
第一步:在 web.xml 中配置该过滤器。
第二步:请求方式必须使用 post 请求。
第三步:按照要求提供_method 请求参数,该参数的取值就是我们需要的请求方式。
举个例子
1 |
|
Post方式
主要通过控制 Content-Type
来控制Post方式,主要包括以下四种方式。
application/x-www-form-urlencoded
以key-value
键值对拼接的形式,如name=abc&phone=123456
Java后端可以通过@RequestParam
获取指定key
对应的参数,或者直接通过对象映射,例如
方法一:
1 |
|
1 |
|
方法二:
1 |
|
若请求格式为http://localhost:8080/api/user?page=1&size=10&_search=1&username=&role=user&status=&createTime=&updateTime=
则 Map 对应存储的 key-value
为:
1 |
|
application/json
以 json 格式,如{"name":"abc","phone":"123456"}
multipart/form-data
multipart/form-data
是基于 post
方法来传递数据的,并且其请求内容格式为Content-Type: multipart/form-data
,用来指定请求内容的数据编码格式。另外,该格式会生成一个
boundary
字符串来分割请求头与请求体的,具体的是以一个boundary=${boundary}
来进行分割,伪码如下:
1 |
|
举个例子:
1 |
|