【SSM】学习笔记(二)——SpringMVC入门

原视频链接:https://www.bilibili.com/video/BV1Fi4y1S7ix/?p=43&spm_id_from=pageDriver&vd_source=8ae265768486246506e74053a00b60db P43~P74

目录

一、SpringMVC简介

SpringMVC是一种基于Java实现MVC模型的轻量级Web框架,有使用简单,开发便捷(相比于Servlet)的优点,同时灵活性强

回顾使用Servlet开发表现层的流程

image

Web程序通过浏览器访问页面,前端页面使用异步提交的方式发送请求到后端服务器。后端服务器采用表现层、业务层、数据层的三层式架构进行开发。页面发送的请求由表现层接收,获取到用户的请求参数后,将请求传送到业务层,再由业务层访问数据层,得到用户想要的数据后,将数据返回给表现层。表现层拿到数据以后,将数据转换为json格式发送给前端页面,前端页面接收数据后解析数据,组织成用户浏览的最终页面信息交给浏览器

1.1、SpringMVC入门案例

①:使用SpringMVC技术需要先导入SpringMVC坐标与Servlet坐标

<dependency>
  <groupId>javax.servlet</groupId>
  <artifatId>javax.servlet-api</artifactId>
  <version>3.1.0</version>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifatId>spring-webmvc</artifactId>
  <version>5.2.10.RELEASE</version>
</dependency>

②:创建SpringMVC控制器类(等同于Servlet功能)

//2.1使用Controller定义bean
@Controller
public class UserController {
    //2.2设置当前操作的访问路径
    @RequestMapping("/save")
    //2.3设置当前操作的返回值类型
    @ResponseBody
    public String save(){
        System.out.println("user save ...");
        return "{'info':'springmvc'}";
    }
}

③:初始化SpringMVC环境(同Spring环境),设定SpringMVC加载对于的bean

@Configuration
@ComponentScan("com.itheima.controller")
public class SpringMvcConfig {
}

④:初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术处理的请求

//4.1AbstractDispatcherServletInitializer类是SpringMVC提供的快速初始化web3.0容器的抽象类
//AbstractDispatcherServletInitializer提供了三个接口方法供用户实现
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
    //创建Servlet容器时,加载springMVC对应的bean并放入webApplicationContext对象中
    //而WebApplicationContext的作用范围为ServletContext范围,即整个web容器范围
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }

    //设定SpringMVC对应的请求映射路径,设置为/表示拦截所有请求,任意请求都将转入到SpringMVC进行处理
    protected String[] getServletMappings() {
        retrun new String[]{"/"};
    }

    //如果创建Servlet容器时加载非SpringMVC对应的bean,使用当前方法进行,使用方法同createServlertApplicationContext()
    protected WebApplicationContext createRootApplicationContext() {
        retrun null;
    }
}

在案例中有几个新的注解:

@Controller
类型:类注解
位置:SpringMVC控制器类定义上方
作用:设定SpringMVC的核心控制器bean

@Controller
public class UserController{
}

@RequestMapping
类型:方法注解
位置:SpringMVC控制器方法定义上方
作用:设置当前控制器方法请求访问路径

@RequestMapping("请求访问路径")
public void save(){
    System.out.println("user save ...");
}

@ResponseBody
类型:方法注解
位置:SpringMVC控制器方法定义上方
作用:设置当前控制器方法响应内容为当前返回值,无需解析

@RequestMapping("/save")
@ResponseBody
public String save(){
    System.out.println("user save ...");
    return "{'info':'springmvc'}";
}

SpringMVC入门案例工作流程分析
image

SpringMVC入门程序开发总结(1+N)

  • 一次性工作

    • 创建工程,设置服务器,加载工程
    • 导入坐标
    • 创建web容器启动类,加载SpringMVC配置,并设置SpringMVC请求拦截路径
    • SpringMVC核心配置类(设置配置类,扫描controller包,加载Controller控制器bean)
  • 多次工作

    • 定义处理请求的控制类
    • 定义处理请求的控制方法,并配置映射路径(@RequestMapping)与返回json数据(@ResponseBody)

1.2、bean加载控制

在Spring程序开发中,常有的几个包config、controler、service、dao。

SpringMVC相关bean(表现层bean)
Spring控制的bean

  • 业务bean(Service)
  • 功能bean(DataSource等)

SpringMVC加载的bean对应的包均在controler包内,扫描上层包时一定会加载controler包中的bean。因为功能不同,如何避免Spring错误的加载到SpringMVC的bean?

方式一:Spring加载的bean设定扫描范围为上层包,排除掉controller包内的bean

@ComponentScan
类型:类注解

@Configuration
@ComponentScan(value = "com.itheim",
    excludeFilters = @ComponentScan.Filter()
        type = FilterType.ANNOTATION,
        classes = Controller.class
    )
)
public class SpringConfig{
}

属性:
excludeFilters:排除扫描路径中加载的bean,需要指定类别(type)与具体项(classes)
includeFilters:加载指定的bean,需要指定类别(type)与具体项(classes)

方式二:SPring加载的bean设定扫描范围为精准范围,例如service包、dao包等
方式三:不区分Spring与SpringMVC的环境,加载到同一个环境中

bean加载格式

public class ServletContainersInitConfig extends AbstractDsipatcherServletInitializer {
    protected WebApplicationContext createServletApplicationContext() {
       AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationCOntext();
       ctx.register(SpringMvcConfig.class);
       return ctx;
    }
    protected WebApplicationContext createRootApplicationContext() {
       AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationCOntext();
       ctx.register(SpringConfig.class);
       return ctx;
    }
    protected String[] getServletMappings() {
       return new String[]{"/"};
    }
}

而Spring其实还为我们准备更加简便的配置方式

public class ServletContainersInitConfig extends AbstractAnnotationConfigOispatcherServletInitializer {
    protected Class<?>[] getRootConfigCLasses() {
        return new Class[]{SpringConfig.class};
    }
    protected Class<?>[] getServletConfigClasses () {
        return new Class[]{SpringMvcConfig.class};
    }
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

1.3、PostMan简介

为了后面学习方便,将学习一款模拟前端发送请求的插件

image

Postman是一款功能强大的网页测试与发送网页HTTP请求的Chrome插件,常用于进行接口测试。
特征:简单、实用、美观、大方
官网:https://www.postman.com/downloads/

Postman基本使用

注册登录

image

创建工作空间/进入工作空间

image

image

发送请求/测试结果

image

记得开启服务器

地址备份的功能 快捷键:"Ctrl + S"

image

创建好后点右边的Send就能重复使用了,不同的项目也可以在这里配置方便测试。

image

GET请求参数

image

POST请求参数

image

1.4、SpringMVC解决Post请求中文乱码问题

为web容器添加过滤器并指定字符集,Spring-web包中提供了专用 的字符过滤器

public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherSerletInitializer {
    //配字符编码过滤器
    protected Fillter[] getServletFillters() {
        CharacterEncodingFIlter filter = new CharacterEncodingFilter();
        filter.setEncoding("utf-8")
        return new Filter[]{filter};
    }
}

二、请求与响应

2.1、请求映射路径

团队多人开发,每人设置不同的请求路径,冲突问题常常需要设置模块名作为请求路径前缀。比如当项目中出现了两个save请求路径,员工A开发的是book模块,路径就变成"/book/save";员工B开发的是user模块,路径就变成"/user/save"。

之前学的@RequestMapping这个注解它能够设置当前控制器方法请求访问路径,如果设置在类上则统一设置当前控制器方法请求路径前缀。

示例

@Controller
@RequestMapping("/user")
public class UserCOntroller {
    @RequestMapping("/save")
    @ResponseBody
    public String save(){
        System.out.println("user save ...");
        retrun "{'modeule':'user save'}";
    }
}

2.2、请求参数传递

普通参数:url地址传参,地址参数名与形参变量名相同,定义形参即可接收参数

@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name,int age){
    System.out.println("普通参数传递 name ==>"+name);
    System.out.println("普通参数传递 age ==>"+age);
    return "{'modoule':'common param'}";
}

请求参数名与形参名不同时,使用@RequestParam绑定参数关系

@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParam(@RequestParam("name") String userName){
    System.out.println("普通参数传递 name ==>"+name);
    return "{'modoule':'common param different name'}";
}

@RequestParam,形参注解,绑定请求参数与处理器方法形参间的关系,参数required表示是否为必传参数,defaultValue表示参数默认值

POJO类型参数:只有普通类型参数时,保证参数名与实体类属性名一致

public class User{
    private String name;
    private int age;
}
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
    System.out.println("pojo参数传递 user ==> "+user);
    return "{'module':'pojo parm'}";
}

同时有引用属性与普通属性时,接收参数与上面一样,Postman发送请求要改一下

image

引用类型的参数,格式:对象名.属性名传递

数组类型参数

image

请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型参即可收参数

@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
    System.out.println("数组参数传递 likes ==> "+Arrays.toString(likes));
    retrun "{'module':'array param'}";
}

集合类型参数
集合保存普通参数:请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系

@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
    System.out.println("集合参数传递 likes ==>"+ likes);
    return "{'module':'list param'}";
}

日期型参数
日期类型数据基于系统不同格式也不尽相同
2088-8-182088/08/1808/18/2088
接收形参时,根据不同的日期格式设置不同的接收方式

@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
                                  @DateTimeFormat(pattern = "yyyy-MM-dd") Date date1,
                                  @DateTimeFormat(pattern = "yyyy/MM/dd" HH:mm:ss) Date date2){
    System.out.println("参数传递 date ==>"+date);
    System.out.println("参数传递 date(yyyy-MM-dd) ==>"+date1);
    System.out.println("参数传递 date(yyyy/MM/dd HH:mm:ss) ==>"+date2);
    return "{'module':'data param'}"
}

image

@DateTimeFormat
类型:形参注解
位置:SpringMVC控制器方法形参前面
作用:设定日期时间型数据格式
属性:pattern:日期时间格式字符串

@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date){
   System.out.println("参数传递 date ==>"+date);
   return "{'module':'data param'}";
}

json数据参数
①:添加json数据转换相关坐标

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.9.0</version>
</dependency>

②:设置发送json数据(请求body中添加json数据)
image

③:开启自动转换json数据的支持

@configuration
@ComponentScan("com.itheima.controller")
@EnableWebMvc
public class SpringMvcConfig {
}

@EnableWebMvc注解功能强大,该注解整合了多个功能,此处仅使用其中一部分功能,即json数据进行自动类型转换

④:设置接收json数据

@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson("@RequestBody List<String> likes"){
    System.out.println("list common(json)参数传递 list ==> "+likes);
    return "{'module':'list common for json param'}";
}

@EnableWebMvc
类型:配置类注解
位置:SpringMVC配置类定义上方
作用:开启SpringMVC多项辅助功能

@configuration
@ComponentScan("com.itheima.controller")
@EnableWebMvc
public class SpringMvcConfig {
}

@RequestBody
类型:形参注解
位置:SpringMVC控制器方法形参定义前面
作用:将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次

@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson("@RequestBody List<String> likes"){
    System.out.println("list common(json)参数传递 list ==> "+likes);
    return "{'module':'list common for json param'}";
}

POJO参数:json数据与形参对象名称相同,定义POJO类型形参即可接收参数

image

@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User uesr){
    System.out.println("pojo(json)参数传递 user ==>"+user);
    return "{'module':'pojo for json param'}";
}

POJO集合参数:json数组数据与集合泛型属性名相同,定义List类型形参即可接收参数

image

@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
    System.out.println("list pojo(json)参数传递 list ==>"+list);
    return "{'module':'list pojo for json param'}";
}

@RequestBody与@RequestParam区别
@RequestParam用于接收url地址传参,表单传参【application/x-www-form-rulencoded】
@RequestBody用于接收json数据【application/json】

@RequestBody与@RequestParam应用
后期开发中,发送json格式数据为主,@RequestBody应用较广
如果发送非json格式数据,选用@RequestParam接收请求参数

类型转换器

  • Converter接口
public interface Converter<S, T>{
    @Nullable
    T convert(S var1);
}
  • 请求参数年龄数据(String->Integer)
  • 日期格式转换(String->Date)

@EnableWebMvc功能之一:根据类型匹配对应的类型转换器

2.3、响应

所谓响应就是将处理完的结果反馈给用户

响应页面(了解即可)

@RequestMapping("/toPage")
public String toPage(){
    return "page.jsp";
}

响应文本数据(了解即可)

@RequestMapping("toText")
@ResponseBody
public String toText(){
    return "response text";
}

响应json数据(对象转json)

@RequestMapping("/toJsonPOJO")
@ResponseBody
public User toJsonPOJO(){
    User user = new User();
    user.setName("鸡")
    user.setAge(41);
    return user;
}

响应json数据(对象集合转json数组)

@RequestMapping("/toJsonList")
@ResponseBOdy
public List<User> toJsonList(){
    User user1 = new User();
    user1.setName("鸡");
    user1.setAge(18);
    User user2 = new User();
    user2.setName("蛋");
    user2.setAge(25);
    List<User> userList = new ArrayList<User>();
    userList.add(user1);
    userList.add(user2);
    return userList
}

@ResponseBody
类型:方法注解
位置:SpringMVC控制器方法定义上方
作用:设置当前控制器返回值作为响应体

@RequestMapping("/save")
@ResponseBody
public String save(){
    System.out.println("save ...");
    return "{'info':'springmvc'}";
}

类型转换使用的是Http专用的接口,HttpMessageConverter接口

image

它与Converter接口一样都是用来做类型转换的,只不过转换的类型不一样。

三、REST风格

3.1、REST风格简介

REST(Representational State Transfer),表现形式状态转换。单从字面上非常难理解,它在开发中的作用是访问网络资源的格式。

传统风格资源描述形式

image

REST风格描述形式

image

两者功能一样,但REST风格具有隐藏资源的访问行为,无法通过地址得知对资源是何种操作,以及书写简单的优点。

按照REST风格访问资源时使用行为动作区分对资源进行了何种操作

image

根据REST风格对资源进行访问称为RESTful

上述行为是约定方式,约定不是规范,可以打破,所以称REST风格,而不是REST规范。描述模块的名称通常使用复数,也就是加s的格式描述,表示此类资源,而非单个资源,例如:users、books、accounts...

3.2、RESTful入门案例

①:设置http请求动作(动词)

@RequestMapping(value = "/user", method = RequestMethod.POST)
@ResponseBody
public String save(@RequestBody User user){
    System.out.println("user save..." + user);
    return "{'module':'user save'}";
}

@RequestMapping(value = "/users" ,method = RequestMethod.PUT
@ResponseBody
public String update(@RequestBody User user){
    System.out.println("user update..."+user);
    return "{'module':'user update'}";
}

②:设定请求参数(路径变化)

@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id){
    System.out.println("user delete..." + id);
    return "{'module':'user delete'}";
}

@RequestMapping
类型:方法注解
位置:SpringMVC控制器方法定义上方
作用:设置当前控制器方法请求访问路径

@RequestMapping(value = "/users",method = RequestMethod.POST)
@ResponseBody
public String save(@RequestBody User user){
    System.out.println("user save..." + user);
    return "{'module':'user save'{}";
}

@PathVariable
类型:形参注解
位置:SpringMVC控制器方法形参定义前面
作用:绑定路径参数与处理器方法形参间的关系,要求路径参数与形参名一一对应

@RequestMapping(value = "/users/{id}" ,method = ReuqestMethod.DELETE)
@ResponseBody
public String dalete(@PathVariable Integer id){
    System.out.println("user delete..." + id);
    retrun "{'module' :'user delete'}";
}

3.3、RESTful快速开发

在入门案例中存在一些可优化的地方,所以有人就提出了RESTful快速开发

image

@RestController
类型:类注解
位置:基于SpringMVC的RESTful开发控制器类定义上方
作用:设置当前控制器类为RESTful风格,等同于@Controller与@ResponseBody两个注解组合功能

@RestController
public class BookController{

}

@GetMapping @PostMapping @PutMapping @DeleteMapping
类型:方法注解
位置:基于SpringMVC的RESTful开发控制器方法定义上方
作用:设置当前控制器方法请求访问路径与请求动作,每种对应一个请求动作,例如@GetMapping对应GET请求

@GetMapping("/{id}")
public String getById(@PathVariable Integer id){
    System.out.println("book getById..."+id);
    return "{'module':'book getById'}";
}

属性:value(默认):请求访问路径

posted @ 2022-10-25 16:34  卡卡鸡  阅读(121)  评论(0)    收藏  举报