一、入门案例
项目结构:
controller包中是控制层代码:
@Controller
public class UserController {
@RequestMapping("/save") //设置当前控制器方法请求访问路径
@ResponseBody //设置返回值为响应内容
public String save(){
System.out.println("save running...");
return "{'module':'springmvc'}";
}
}
config包中是SpringMVC的配置类,扫描SpringMVC容器注入的Bean。
@Configuration
@ComponentScan("controller")
public class SpringMvcConfig {
}
核心是一个Servlet容器配置类,该类可以继承自AbstractDispatcherServletInitializer类:
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//加载SpringMVC容器配置
@Override
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext context=new AnnotationConfigWebApplicationContext();
context.register(SpringMvcConfig.class);
return context;
}
//设置哪些请求归属SpringMVC处理,"/"表示处理所有请求
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
//加载Spring容器配置
@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
为了简便开发,推荐继承自其子类AbstractAnnotationConfigDispatcherServletInitializer:
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
二、详解
1. AbstractAnnotationConfigDispatcherServletInitializer
WebApplicationInitializer是 Spring MVC 提供的一个接口,可确保检测到您的实现并自动用于初始化任何 Servlet 3 容器。AbstractAnnotationConfigDispatcherServletInitializer是WebApplicationInitializer的抽象实现类,该类将自动初始化Servlet容器。
2. RequestMapping
@RequestMapping注解可以添加在方法定义上或者类定义上,如果设置在类定义上表示访问该类下的方法的路径都需要加此前缀。
三、请求与响应
1. 几种请求参数
-
当函数参数名和请求参数名不同时,使用@RequestParam绑定参数
@Controller
public class UserController {
@RequestMapping("/request")
public void request(@RequestParam("name") String UserName){
System.out.println(UserName);
}
} -
当请求参数和实体类的属性一致时,可以为我们构造一个实体类对象:
@Controller
public class UserController {
@RequestMapping("/request")
public void request(User user){
System.out.println(user);
}
}
-
数组类型
@Controller
public class UserController {
@RequestMapping("/request")
public void request(String[] hobbies){
System.out.println(Arrays.toString(hobbies));
}
}
-
集合类型需要加@RequestParam注解
@Controller
public class UserController {
@RequestMapping("/request")
public void request(@RequestParam List<String> hobbies){
System.out.println(hobbies);
}
}
2. JSON数据格式
step1: 导入Jackson坐标:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
step2: 添加@EnableWebMvc开启自动转换json数据的支持
@Configuration
@ComponentScan("controller")
@EnableWebMvc
public class SpringMvcConfig {
}
- 集合
@Controller
public class UserController {
@RequestMapping("/request")
public void request(@RequestBody List<String> hobbies){
System.out.println(hobbies);
}
}
-
实体类对象
{
"name":"张三",
"age":18
}@Controller
public class UserController {
@RequestMapping("/request")
public void request(@RequestBody User user){
System.out.println(user);
}
} -
对象集合
[
{"name":"张三","age":18},
{"name":"李四","age":20}
]@Controller
public class UserController {
@RequestMapping("/request")
public void request(@RequestBody List<User> list){
System.out.println(list);
}
}
3. 响应
@Controller
public class UserController {
@RequestMapping("/jsp")
public String JSPJump(){
return "page.jsp";
}
@RequestMapping("/text")
@ResponseBody
public String ResponseText(){
return "<h1>response text</h1>";
}
@RequestMapping("/jsonPOJO")
@ResponseBody
public User ResponseJsonPOJO(){
User user=new User("张三",18);
return user;
}
@RequestMapping("/jsonList")
@ResponseBody
public List<User> ResponseJsonList(){
List<User> list=new ArrayList<>();
list.add(new User("张三",18));
list.add(new User("李四",20));
return list;
}
}
注:@ResponseBody设置当前控制器返回值作为响应体,由HttpMessageConverter接口完成类型转换
四、REST风格
1. 简介
REST(Representational State Transfer),表现形式状态转换,它是一种软件架构风格,当我们想表示一个网络资源的时候,可以使用两种方式:
- 传统风格资源描述形式
-
http://localhost/user/getById?id=1
查询id为1的用户信息http://localhost/user/saveUser
保存用户信息
- REST风格描述形式
-
http://localhost/user/1
http://localhost/user
但是我们的问题也随之而来了,一个相同的url地址即可以是新增也可以是修改或者查询,那么到底我们该如何区分该请求到底是什么操作呢?
- 按照REST风格访问资源时使用==行为动作==区分对资源进行了何种操作
-
- http://localhost/users 查询全部用户信息 GET(查询)
- http://localhost/users/1 查询指定用户信息 GET(查询)
- http://localhost/users 添加用户信息 POST(新增/保存)
- http://localhost/users 修改用户信息 PUT(修改/更新)
- http://localhost/users/1 删除用户信息 DELETE(删除)
请求的方式比较多,但是比较常用的就4种,分别是GET,POST,PUT,DELETE。
2. 入门
@Controller
public class UserController {
@RequestMapping(value="/users",method = RequestMethod.POST)
public void save(@RequestBody User user){
//代码逻辑
}
@RequestMapping(value="/users/{id}",method = RequestMethod.DELETE)
public void delete(@PathVariable int id){
//代码逻辑
}
@RequestMapping(value="/users",method=RequestMethod.PUT)
public void update(@RequestBody User user){
//代码逻辑
}
@RequestMapping(value="/users/{id}",method=RequestMethod.GET)
public void getById(@PathVariable int id){
//代码逻辑
}
}
-
通过设置RequestMapping的method参数,即可设置请求方式
-
如果访问路径中有参数,使用"/user/{参数名}",接收参数,必须使用@PathVariable绑定。如果函数参数和请求参数不同名,还需要再@PathVariable的参数中注明路径参数名,进行绑定。如下:
@RequestMapping(value="/users/{id}",method = RequestMethod.DELETE)
public void delete(@PathVariable("id") int userId){
//代码逻辑
}
三个注解@RequestBody
、@RequestParam
、@PathVariable
,这三个注解之间的区别和应用分别是什么?
- 区别
-
- @RequestParam用于接收url地址传参或表单传参
- @RequestBody用于接收json数据
- @PathVariable用于接收路径参数,使用{参数名称}描述路径参数
- 应用
-
- 后期开发中,发送请求参数超过1个时,以json格式为主,@RequestBody应用较广
- 如果发送非json格式数据,选用@RequestParam接收请求参数
- 采用RESTful进行开发,当参数数量较少时,例如1个,可以采用@PathVariable接收请求路径变量,通常用于传递id值
3. 简化开发
@Controller
@RequestMapping("/users")
public class UserController {
@PostMapping
public void save(User user){
//代码逻辑
}
@DeleteMapping("/{id}")
public void delete(@PathVariable("id") int userId){
//代码逻辑
}
@PutMapping
public void update(@RequestBody User user){
//代码逻辑
}
@GetMapping("/{id}")
public void getById(int id){
//代码逻辑
}
}
@ResponseBody注解也可以直接放在类定义上,且@RestController等同于@Controller与@ResponseBody两个注解组合功能