SSM 学习第五天

SpringMVC

入门案例

  • 导入 maven 依赖
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
    </dependency>

    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.10.RELEASE</version>
    </dependency>
  • 创建 Spring 控制类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package com.ljguo.controller;

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;

    @Controller
    @RequestMapping("/user")
    public class UserController {
    @RequestMapping("/save")
    @ResponseBody
    public String save(){
    System.out.println("user save ...");
    return "{'info': 'spring-mvc-user'}";
    }
    }
  1. @Controller 让其加载到 Spring 容器中
  2. @RequestMapping 用于映射访问的 url 路径
  3. @ResponseBody 用于将方法返回值写到响应体中
  • 创建 SpringMVC 配置类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    package com.ljguo.config;

    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;

    @ComponentScan("com.ljguo.controller")
    @EnableWebMvc
    public class SpringMvcConfig {
    }
  1. @ComponentScan
  • 初始化 Servlet 容器, 加载 SpringMVC 环境, 设置 SpringMVC 技术处理的请求
    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
    public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
    return new Class[]{SpringConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
    return new Class[]{SpringMvcConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
    return new String[]{"/"};
    }

    // 乱码处理
    @Override
    protected Filter[] getServletFilters() {
    CharacterEncodingFilter filter = new CharacterEncodingFilter();
    filter.setEncoding("utf-8");
    return new Filter[]{filter};
    }
    }
  1. 继承 AbstractAnnotationConfigDispatcherServletInitializer, 重写三个方法并配置
  2. getServletFilters 方法用于解决中文乱码

各种参数的传递

  • 普通参数

    1
    2
    3
    4
    5
    @RequestMapping("/save")
    @ResponseBody
    public String save(String username, String password){
    return username + ": " + password;
    }

    前端传输

    1
    2
    username
    password
  • pojo 参数

    1
    2
    3
    4
    5
    @RequestMapping("/pojo")
    @ResponseBody
    public String pojoParam(User user) {
    return user.toString();
    }
  • 嵌套 pojo 参数

    1
    2
    3
    4
    username
    password
    address.province
    address.city
  • 数组

    1
    2
    3
    4
    5
    @RequestMapping("/array")
    @ResponseBody
    public String arrayParam(String[] likes) {
    return Arrays.toString(likes);
    }

    前端传输

    1
    2
    3
    4
    likes
    likes
    likes
    ...
  • 集合

    1
    2
    3
    4
    5
    @RequestMapping("/list")
    @ResponseBody
    public String listParam(@RequestParam List<String> likes) {
    return likes.toString();
    }

    前端传输

    1
    2
    3
    4
    likes
    likes
    likes
    ...

    记得加上 @RequestParam 在参数上

  • Date 时间类型

    1
    2
    3
    4
    5
    @RequestMapping("/date")
    @ResponseBody
    public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd") Date date) {
    return date.toString();
    }

    前端传输

    1
    2
    2022/10/20
    2022-10-20

    注意默认时间格式是 yyyy/MM/dd, 如需其它格式, 需要使用 @DateTimeFormat 注解中的 pattern 指定格式

  • json
    这里需要在 SpringMVC 的配置类中加入 @EnableWebMvc 注解, 用于开启由 json 数据转化为我们的对象的功能

    1
    2
    3
    4
    5
    6
    @RequestMapping("/list")
    @ResponseBody
    public String listParam(@RequestBody List<User> users) {
    System.out.println(users);
    return likes.toString();
    }

响应

  • 页面跳转
    1
    2
    3
    4
    @RequestMapping("/jumpPage")
    public String jumpPage() {
    return "/index.jsp";
    }
    注意不要加 @ResponseBody 注解, 因为这个注解是将返回值写入响应体中, 便无法做到页面跳转
  • 纯文字
    1
    2
    3
    4
    5
    @RequestMapping("/toText")
    @ResponseBody
    public String toText() {
    return "hello world!";
    }
  • json 数据
    1
    2
    3
    4
    5
    6
    @RequestMapping("/toJson")
    @ResponseBody
    public User toJson() {
    User user = new User("ljguo","20001020",new Address("sichuan","nanchong"));
    return user;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @RequestMapping("/userList")
    @ResponseBody
    public List<User> userList() {
    User user = new User("ljguo","20001020",new Address("sichuan","nanchong"));
    User user1 = new User("ljguo1","20001020",new Address("sichuan","nanchong"));
    User user2 = new User("ljguo2","20001020",new Address("sichuan","nanchong"));
    List<User> userList = new ArrayList<>();
    userList.add(user);
    userList.add(user1);
    userList.add(user2);
    return userList;
    }
    这里的原理是 SpringMVC 依赖 @ResponseBody 注解并使用 Jackson 类帮我们实现了对象转化为 json 数据并传递到响应体

REST 风格

REST: Representational State Transfer 表现形式状态转换

传统风格

1
2
http://localhost/user/getById?id=1
http://localhost/user/addUser

REST

1
2
http://localhost/user/1
http://localhost/user

优点

  • 隐藏访问行为, 无法通过地址来得知行为
  • 书写简化

需要使用不同的请求方式

1
2
3
4
5
http://localhost/users      查全部信息(GET)
http://localhost/users/1 查指定信息(GET)
http://localhost/users 添加(POST)
http://localhost/users 修改(PUT)
http://localhost/users/1 删除(DELETE)

入门案例

1
2
3
4
5
6
@RequestMapping(value = "/{id}",method = RequestMethod.GET)
@ResponseBody
public String save(@PathVariable int id){
System.out.println("user save ..." + id);
return "{'info': 'spring-mvc-user'}";
}
  1. value = "/{id}" 对应 @PathVariable int id 实现对路径参数的解析
  2. method = RequestMethod.GET 设置请求方式
  • @RequestParam 用于接收表单数据
  • @RequestBody 用于接收 json 数据
  • @PathVariable 用于接收路径参数

简化

1
2
@Controller
@ResponseBody

替换为

1
@RestController
1
@RequestMapping(value = "/{id}", method = RequestMethod.GET)

替换为

1
@GetMapping("/{id}")

SpringMVC 资源放行

  • 配置一个资源放行类, 继承 WebMvcConfigurationSupport 类, 重写 addResourceHandlers() 方法
    1
    2
    3
    4
    5
    6
    7
    8
    @Configuration
    public class SpringSupport extends WebMvcConfigurationSupport {
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
    // 放行, 即访问这些路径时, 不走 SpringMVC, 而是走 tomcat
    registry.addResourceHandler("/**").addResourceLocations("/");
    }
    }