首页 > 其他分享 >SpringMVC-day01

SpringMVC-day01

时间:2023-03-11 16:45:49浏览次数:38  
标签:RequestMapping return 请求 SpringMVC day01 public String

SpringMVC-day01

SpringMVC,底层是把Servlet、Filter、Listener 再次封装

课程内容

  1. SpringMVC介绍
  2. 请求与响应
  3. RESTful风格请求交互
  4. SSM整合(注解版)
  5. 拦截器

学习目标

  1. 掌握基于SpringMVC获取请求参数与响应json数据操作
  2. 熟练应用基于REST风格的请求路径设置与参数传递
  3. 能够根据实际业务建立前后端开发通信协议并进行实现
  4. 基于SSM整合技术开发任意业务模块功能

01_SpringMVC基本概念

目标

  • 了解SpringMVC框架在三层架构存在的意义

路径

  1. 三层架构
  2. MVC模型
  3. 请求响应模型演化过程
  4. SpringMVC概述

三层架构

表现层:WEB层,用来和客户端(浏览器)进行数据交互的。表现层一般会采用MVC的设计模型

业务层:处理公司具体的业务逻辑的

持久层:用来操作数据库的

MVC架构

MVC(Model View Controller):

  • Model(模型):负责封装应用的状态,并实现应用的功能。通常分为:数据模型、业务逻辑模型
  • View(视图):页面视图,用于展示数据 (因为开发中前后端分离了,这块内容后端技术人员接触少了)
  • Controller(控制器):处理用户交互的调度器,用于根据用户需求处理程序逻辑

请求响应模型演化过程

web阶段:

image-20220503200731403

同步场景下的SpringMVC:

image-20220503200639636

异步场景下的SpringMVC:

image-20220503200941222

SpringMVC概述

SpringMVC是一种基于Java实现的MVC模型的轻量级Web框架

  • 底层基于Spring (IOC和AOP)

  • 封装了web三大组件(Servlet,Filter,Listener)

SpringMVC的优点:

  • 使用简单,开发便捷(相比于Servlet)
  • 灵活性强

02_SpringMVC入门

目标

  • 能够搭建SpringMVC程序并接收请求

路径

  1. SpringMVC开发步骤
  2. SpringMVC入门代码

SpringMVC开发步骤

使用SpringMVC开发的步骤:

  1. 导入坐标(SpringMVC依赖、Servlet依赖)
  2. 创建SpringMVC控制器类(等同于Servlet)
  3. 初始化SpringMVC环境 【没有web.xml文件、没有@WebServlet注解了】
  4. 初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC请求拦截的路径

SpringMVC入门代码

案例工程目录:

image-20220504213014872

代码示例:

  • 导入坐标(SpringMVC依赖、Servlet依赖)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.itheima</groupId>
    <artifactId>springmvc_day01-quickstart</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <!-- 依赖管理 -->
    <dependencies>
        <!-- Servlet依赖 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- SpringMVC依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
    </dependencies>

</project>
  • 创建SpringMVC控制器类(等同于Servlet)
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

//定义表现层控制器bean
@Controller
public class UserController {
    @RequestMapping("/save") //让请求的路径[/save]映射到目标方法上
    @ResponseBody  //设置当前操作返回结果为字符串
    public String save(){
        System.out.println("保存用户...");
        return "success";
    }
}
  • 初始化SpringMVC环境
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

//springmvc配置类,本质上还是一个spring配置类
@Configuration
@ComponentScan("com.itheima.controller") //指定要扫描的包
public class SpringmvcConfig {
}
  • 初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC请求拦截的路径
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;


//web容器配置类
//AbstractDispatcherServletInitializer类是SpringMVC提供的快速初始化Web3.0容器的抽象类
public class ServletContainerInitConfig extends AbstractDispatcherServletInitializer {

    //加载springmvc配置类,产生springmvc容器(本质还是spring容器)
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        //初始化WebApplicationContext对象
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();

        //加载指定配置类
        ctx.register(SpringmvcConfig.class);

        return ctx;
    }

    //设置由springmvc控制器处理的请求映射路径
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    //加载spring配置类
    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }
}

测试:将项目部署到tomcat,使用浏览器测试请求

@Controller注解

  • 作用:设置SpringMVC的核心控制器bean
@Controller  //指定UserController类为表现层的控制器bean
public class UserController {
}

@RequestMapping注解

  • 作用:让请求的路径映射到控制器类中的方法上
@Controller  
public class UserController {
    @RequestMapping("/save") //让请求的路径[/save]映射到目标方法上
    public String save(){
        return "success";
    }
}

@ResponseBody注解

  • 作用:设置当前控制器方法响应体内容为当前返回值(无需解析)
@Controller  
public class UserController {
    @RequestMapping("/save") 
    @ResponseBody  //设置当前操作返回结果为字符串
    public String save(){
        return "success";
    }
}

03_使用SPI机制创建Servlet

目标

  • 了解Servlet中的SPI机制

路径

  1. SPI介绍
  2. ServletContainerInitializer

SPI介绍

SPI全称:Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件。

Java SPI 基于 “接口编程+策略模式+配置文件(约定)”组合实现的动态加载机制。

Java的SPI机制就是将一些类信息写在约定的文件中,然后由特定的类加载器加载解析文件获取资源。

  • 约定的配置文件

    配置文件必须存放在:META-INF/services目录下
    
  • 特定的类加载器

    java.util.ServiceLoader类 (类加载器)
    
    ServiceLoader.load(Class cls) //示例:ServiceLoader.load(接口.class)
    
    在ServiceLoader.load的时候,根据传入的接口类,遍历META-INF/services目录下的以该接口命名的文件中的所有类,并实例化返回
    

ServletContainerInitializer

ServletContainerInitializer是Servlet3.0新增的一个接口,主要用于在web容器(Tomcat)启动阶段通过编程风格注册Filter、Servlet、Listener,以取代通过web.xml配置注册。这样就利于开发内聚的web应用框架。

  • 简单来讲:就是不需要在web项目工程中使用web.xml文件了

image-20220504223054704

约定文件:

  • 要求:
    1. 必须存放在META-INF/services目录下
    2. 使用接口的全限定名作为配置文件名
#javax.servlet.ServletContainerInitializer接口的实现类
com.itheima.config.MyServletContainerInitializer

实现类:

public class MyServletContainerInitializer implements ServletContainerInitializer {

    @Override
    public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
        System.out.println("start..........................");
        MyServlet myServlet = new MyServlet();
        ctx.addServlet("myServlet", myServlet).addMapping("/myServlet");
    }
}

Servlet类:

public class MyServlet extends HttpServlet {
    @Override
    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("Hello SPI");
    }

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }
}

运行原理:

  1. ServletContainerInitializer接口的实现类通过Java SPI声明自己是ServletContainerInitializer的provider

  2. web容器启动阶段依据java spi获取到所有ServletContainerInitializer的实现类,然后执行其onStartup方法

  3. 在onStartup中通过编码方式将组件Servlet加载到ServletContext

小结

  • 由于Servlet3.0提供了SPI机制,所以web工程可以不用xml和注解配置

04_入门案例的执行过程分析

目标

  • 能够说出SpringMVC执行过程

路径

  1. 简易版SpringMVC执行过程分析
  2. 详解版SpringMVC执行过程分析

所谓的Tomcat就是一个:ServerSocket程序(在学习Java运行ServerSocket程序是通过main方法执行)

Web工程和Java工程的区别:

  1. 打包方式: java工程是jar包,web工程是war包
  2. 运行方式:java工程是直接通过main方法运行,web工程的main方法是在web容器中
    • web工程必须要部署在web容器(如:Tomcat)上才能运行

简易版SpringMVC执行过程分析

image-20220505091647000

SpringMVC加载机制:

  • Tomcat => ServletContainerInitConfig => SpringmvcConfig => UserController
    • Tomcat: web容器
    • ServletContainerInitConfig: web容器配置类(SPI机制)
    • SpringmvcConfig: SpringMVC配置类
    • UserController:表现层的控制器类(等同于Servlet)
  • 执行顺序:
    1. Tomcat根据SPI机制加载ServletContainerInitConfig类
    2. ServletContainerInitConfig类中方法执行
    3. SpringmvcConfig类加载(由ServletContainerInitConfig类中方法运行时加载)
    4. UserController类被SpringmvcConfig类扫描到并加载

详解版SpringMVC执行过程分析

SpringMVC加载机制:Tomcat => ServletContainerInitConfig => SpringmvcConfig => UserController

  • Tomcat
    • tomcat的main方法执行时,根据SPI机制加载ServletContainerInitConfig类
      1. spring-web.jar下有META-INF/services/javax.servlet.ServletContainerInitializer文件
      2. 此文件中配置实现类 org.springframework.web.SpringServletContainerInitializer
      3. SpringServletContainerInitializer类会被Tomcat所加载(SPI机制),此类上的有个注解配置,指定要加载的类型
        • @HandlesTypes({WebApplicationInitializer.class})
      4. WebApplicationInitializer接口的所有实现类都会被加载
        • 入门案例中的ServletContainerInitConfig类就是WebApplicationInitializer接口的实现类
  • ServletContainerInitConfig(web容器配置类)
    • createServletApplicationContext方法运行,加载springmvc配置类
    • getServletMappings方法运行,给DispatcherServlet类设置访问路径为/ (表示拦截所有)
  • SpringmvcConfig(SpringMVC配置类)
    • @ComponentScan("com.itheima.controller")
      • springmvc底层开始扫描:com.itheima.controller包
  • UserController(控制器)[等同于Servlet]
    • @Controller : 表示此bean会添加到springmvc的ioc容器
    • @RequestMapping("/save") : 设置访问路径和目标方法的映射
    • @ResponseBody : 方法的的返回值将会通过响应体返回给前端

05_SpringMVC的请求过程

目标

  • 了解SpringMVC架构的请求过程

路径

  1. SpringMVC的请求过程

SpringMVC的请求过程

请求:

image-20220505150930393

  • 浏览器(前端)
    • 发送请求:http://localhost:8080/save
  • 服务器(后端)
    1. Tomcat接收到请求
    2. 请求交给DispatcherServlet处理
      • DispatcherServlet设置的请求路径为:/(所有请求)
    3. DispatherServlet找到/save对应的控制器方法:UserController类中的save()方法
    4. 执行UserController类中的save()方法,并把save()方法执行后的结果,通过响应体返回给前端

06_RequestMapping注解

目标

  • 能够使用RequestMapping注解建立请求路径和目标方法的映射

路径

  1. RequestMapping注解介绍
  2. RequestMapping注解书写位置
  3. RequestMapping注解常用属性

RequestMapping注解介绍

RequestMapping注解,用于建立请求路径与目标方法的对应关系

image-20220505173321965

RequestMapping注解书写位置

@RequestMapping书写位置:

  • 类上

    窄化路径。访问类中的方法时,必须加上类上定义的请求路径

    @Controller
    @RequestMapping("/user")
    public class UserController {
        @RequestMapping("/save")
        @ResponseBody
        public String save(){
            return "save success";
        }
    }
    
    请求:http://localhost:8080/user/save
    
  • 方法

    建立请求资源路径与方法的直接对应关系

    @Controller
    public class UserController {
        @RequestMapping("/save")
        @ResponseBody
        public String save(){
            return "save success";
        }
    }
    
    请求:http://localhost:8080/save
    

RequestMapping注解常用属性

常用属性:

  • value 或 path:指定访问路径
  • method:限定请求方式(restful风格)
    • 不写,默认什么请求方式都可以
    • 指定了请求方式后,如果不匹配就会响应405状态码
@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping(path = "/save",method = RequestMethod.GET)
    @ResponseBody
    public String save(){
        return "save success";
    }

    @RequestMapping(value = "/save",method = RequestMethod.POST)
    @ResponseBody
    public String saveUser(){
        return "save success";
    }
}
GET请求方式:( 类似Servlet中的doGet方法 )
http://localhost:8080/user/save

POST请求方式:( 类似Servlet中的doPost方法 )
http://localhost:8080/user/save

07_练习:搭建SpringMVC环境

SpringMVC开发步骤:

  1. 导入坐标(SpringMVC依赖、Servlet依赖)
  2. 创建SpringMVC控制器类(等同于Servlet)
  3. 创建SpringMVC配置类(初始化SpringMVC环境)
  4. 创建Web容器配置类
    • 初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC请求拦截的路径

代码示例:

  • SpringMVC控制器类
@Controller
@RequestMapping("/role")
public class RoleController {
    @RequestMapping(value = "/save", method = RequestMethod.GET)
    @ResponseBody
    public String save(){
        System.out.println("RoleController save...");
        return "save success";
    }

    @RequestMapping(path = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public String delete(){
        System.out.println("RoleController delete...");
        return "delete success";
    }
}
  • SpringMVC配置类
@Configuration
@ComponentScan("com.itheima.controller")
public class SpringmvcConfig {
}
  • Web容器配置类
    • 使用AbstractDispatcherServletInitializer的子类简化SpringMVC的容器配置类
      • 子类:AbstractAnnotationConfigDispatcherServletInitializer
//web容器配置类
public class ServletContainerInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    //加载SpringMVC配置
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringmvcConfig.class};
    }

    //设置由springmvc控制器处理的请求映射路径
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};//SpringMVC控制器处理所有的请求
    }

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

08_SpringMVC的请求处理

目标

  • 了解SpringMVC的请求处理方式

路径

  1. SpringMVC的请求处理介绍

SpringMVC的请求处理介绍

SpringMVC主要应用在三层架构中的表现层(web层)。作用就是:

  1. 接收请求

  2. 业务处理(交给业务层)

  3. 响应数据

SpringMVC的请求处理可以分为两大类:

  • 同步请求(前后端不分离)

    • 请求参数通常以url格式为主

      GET :http://localhost:8080/save?username=itheima&password=123
      POST :http//localhost:8080/save
             请求体:username=itheima&password=123
      
    • 特点:同步请求的响应内容会刷新整个网页

    • 响应:跳转页面

  • 异步请求

    • 请求参数通常有:url格式、json格式
    • 特点:请求的响应内容只会让页页局部刷新
    • 响应:字符串数据、json格式数据

SpringMvc对请求和响应进行了封装:

  • 控制器类中的方法可以接收请求参数

  • 请求携带以下类型的数据时SpringMVC会自动接收,并在解析之后传递给方法进行使用

    1. 基本数据类型、String
    2. pojo类型
    3. 数组类型
    4. 集合类型
  • 使用方式:直接在方法上定义形参

    @RequestMapping(value = "/login")
    @ResponseBody
    public String login(String username,String password){
        return "login success";
    }
    
    • 注意:方法上的形参名称必须要和请求参数名称保持一致
    URL格式的GET请求: http://localhost:8080/login?username=itheima&password=123 
    

09_SpringMVC的url格式请求参数

目标

  • 能够使用SpringMVC接收前端发送的url格式请求参数

路径

  1. 获取url格式的请求参数

获取url格式的请求参数

url格式的请求参数类型:

  1. 基本数据类型、String
  2. Pojo类型
  3. 数组类型
  4. 集合类型

代码示例:

  • 控制器类
@Controller
public class UserController {
    //普通参数:请求参数与形参名称对应即可完成参数传递
    @RequestMapping("/commonParam")
    @ResponseBody
    public String commonParam(String name ,int age){
        System.out.println("普通参数传递 name ==> "+name);
        System.out.println("普通参数传递 age ==> "+age);
        return "commonParam";
    }
    
    //POJO参数:请求参数与形参对象中的属性对应即可完成参数传递
    @RequestMapping("/pojoParam")
    @ResponseBody
    public String pojoParam(User user){
        System.out.println("pojo参数传递 user ==> "+user);
        return "pojoParam";
    }

    //嵌套POJO参数:嵌套属性按照层次结构设定名称即可完成参数传递
    @RequestMapping("/pojoContainPojoParam")
    @ResponseBody
    public String pojoContainPojoParam(User user){
        System.out.println("pojo嵌套pojo参数传递 user ==> "+user);
        return "pojoContainPojoParam";
    }

    //数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
    @RequestMapping("/arrayParam")
    @ResponseBody
    public String arrayParam(String[] likes){
        System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
        return "arrayParam";
    }

    //集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
    @RequestMapping("/listParam")
    @ResponseBody
    public String listParam(@RequestParam List<String> likes){
        System.out.println("集合参数传递 likes ==> "+ likes);
        return "listParam";
    }
}
  • Pojo类
public class Address {
    private String province;//省份
    private String city;//城市

    @Override
    public String toString() {
        return "Address{" +
                "province='" + province + '\'' +
                ", city='" + city + '\'' +
                '}';
    }
    public String getProvince() {
        return province;
    }
    public void setProvince(String province) {
        this.province = province;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
}
public class User {
    private String name;
    private Integer age;
    public Address address;

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address=" + address +
                '}';
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
}

使用postman工具,测试请求参数:

  • 基本数据类型、String

    @RequestMapping("/commonParam")
    @ResponseBody
    public String commonParam(String name ,int age){
        System.out.println("普通参数传递 name ==> "+name);
        System.out.println("普通参数传递 age ==> "+age);
        return "commonParam";
    }
    
    • GET请求:url地址传参,请求参数名与方法形参变量名相同(定义形参即可接收参数)

    image-20220505210050402

    • POST请求:form表单参数名与方法的形参变量名相同(定义形参即可接收参数)

    image-20220505205827975

  • Pojo类型

    • 请求参数名与方法形参对象属性名相同(定义POJO类型形参即可接收参数)
    //POJO参数:请求参数与形参对象中的属性对应即可完成参数传递
    @RequestMapping("/pojoParam")
    @ResponseBody
    public String pojoParam(User user){
        System.out.println("pojo参数传递 user ==> "+user);
        return "pojoParam";
    }
    

    image-20220505210926751

    • 嵌套POJO参数:请求参数名与形参对象属性名相同(按照对象层次结构关系即可接收嵌套POJO属性参数)
    //嵌套POJO参数:嵌套属性按照层次结构设定名称即可完成参数传递
    @RequestMapping("/pojoContainPojoParam")
    @ResponseBody
    public String pojoContainPojoParam(User user){
        System.out.println("pojo嵌套pojo参数传递 user ==> "+user);
        return "pojoContainPojoParam";
    }
    

    image-20220505211305672

  • 数组类型

    • 请求参数名与方法形参数组名相同且请求参数为多个(定义数组类型形参即可接收参数)
    //数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
    @RequestMapping("/arrayParam")
    @ResponseBody
    public String arrayParam(String[] likes){
        System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
        return "arrayParam";
    }
    

    image-20220505211630358

  • 集合类型

    • 请求参数名与形参集合对象名相同且请求参数为多个,使用@RequestParam绑定参数关系
    //集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
    @RequestMapping("/listParam")
    @ResponseBody
    public String listParam(@RequestParam List<String> likes){
        System.out.println("集合参数传递 likes ==> "+ likes);
        return "listParam";
    }
    

    image-20220505212218803

小结

在前端发送请求参数时,只要保证请求参数名字和目标方法中接收数据的参数名一致,就可以实现:

  • 请求参数映射到目标方法对应参数列表中

请求参数类型:

  • 基础类型:8种基本类型、包装类、String
    • 请求参数名字 和 方法中参数名 一致
  • pojo类型:实体封装类
    • 请求参数名字 和 实体类中属性名 一致
    • 特殊:嵌套pojo
      • 请求参数名格式: 对象名.成员变量名
  • 数组类型:
    • 请求参数名字 和 数组名 一致(请求参数名字相同,值有多个)
  • 集合类型:
    • 请求参数名字 和 集合对象名 一致(请求参数名字相同,值有多个)
    • 要想要把请求参数映射到集合对象中,要使用:@RequestParam

10_SpringMVC的json格式请求参数

目标

  • 能够使用SpringMVC接收前端发送的json格式请求参数

路径

  1. Json知识介绍
  2. SpringMVC接收json请求参数的步骤
  3. 获取json格式的请求参数

Json知识介绍

json格式数据:

  1. 对象 :
  2. 数组 :[ ]

json格式请求参数常见类型:

  • json对象

    User
    {"name":"zs","age" : 18}
    
  • json数组

    String[] 
    ["a","b","c"]
    
  • json数组(POJO)

    List<User>
    [{"name":"zs","age" : 18},{"name":"ls","age":19}]
    

Java中的json转换工具:

  • FastJson
  • JackSon (SpringMVC底层使用)

SpringMVC接收json请求参数的步骤

开发步骤:

  1. 导入坐标

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.0</version>
    </dependency>
    
  2. 开启json数据自动转换

    //开启json数据类型自动转换
    @EnableWebMvc
    
  3. 接收json数据:使用@RequestBody注解把json数据映射到方法形参上

    public String pojoParamForJson(@RequestBody User user)
    

获取json格式的请求参数

代码示例:

  • SpringMVC配置类
@Configuration
@ComponentScan("com.itheima.controller")
//开启json数据类型自动转换
@EnableWebMvc //@EnableWebMvc注解整合了多个功能,此处仅使用json数据进行自动类型转换
public class SpringmvcConfig {
}
  • SpringMVC控制器类
@Controller
public class UserController {
    //POJO参数:json格式
    //1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
    //2.使用@RequestBody注解将外部传递的json数据映射到形参的实体类对象中,要求属性名称一一对应
    @RequestMapping("/pojoParamForJson")
    @ResponseBody
    public String pojoParamForJson(@RequestBody User user){
        System.out.println("pojo(json)参数传递 user ==> "+user);
        return "pojoParamForJson";
    }

    //集合参数:json格式
    //1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
    //2.使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据
    @RequestMapping("/listParamForJson")
    @ResponseBody
    public String listParamForJson(@RequestBody List<String> likes){
        System.out.println("list common(json)参数传递 list ==> "+likes);
        return "listParamForJson";
    }

    //集合参数:json格式
    //1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
    //2.使用@RequestBody注解将外部传递的json数组数据映射到形参的保存实体类对象的集合对象中,要求属性名称一一对应
    @RequestMapping("/listPojoParamForJson")
    @ResponseBody
    public String listPojoParamForJson(@RequestBody List<User> list){
        System.out.println("list pojo(json)参数传递 list ==> "+list);
        return "listPojoParamForJson";
    }
}

使用postman工具,测试请求参数:

  • POJO参数:json数据与形参对象属性名相同 (定义POJO类型形参即可接收参数)

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

    image-20220505222754958

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

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

    image-20220505223326948

关键API总结

  • url格式请求参数
    • @RequestParam (接收集合类型的参数)
  • json格式请求参数
    • @EnableWebMvc //开启webmvc功能(功能之一: 自动实现json和pojo转换)
    • @RequestBody //在参数前面添加,用于接收json格式参数映射到pojo上

11_SpringMVC请求参数的特殊情况

目标

  • 能够处理请求中存在的特殊情况:中文乱码、参数名不一致、日期格式

路径

  1. 请求参数名称不一致
  2. 编码过滤器
  3. 日期处理

请求参数名称不一致

当请求的参数名和目标方法中的形参名不一致时:控制器中的方法就不能接收请求数据

GET请求:http://localhost:8080/commonParam?name=itheima&age=20
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String username ,int userage){
    System.out.println("普通参数传递 name ==> "+username);
    System.out.println("普通参数传递 age ==> "+userage);
    return "commonParam";
}

解决方案:

  1. 修改名称,保证请求参数名与方法形参名一致
  2. 使用@RequestParam注解,建立请求参数名与形参名称之间的关系
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(@RequestParam("name") String username ,
                          @RequestParam("age") int userage){
    System.out.println("普通参数传递 name ==> "+username);
    System.out.println("普通参数传递 age ==> "+userage);
    return "commonParam";
}

@RequestParam注解属性:

  • value

    • 指定前端的属性名映射到某个参数上
  • required

    • 用于指定此参数是否必传。取值:true/false (默认值 : true)
  • defaultValue

    • 如果前端此参数值没有设置,这里参数会指定一个默认值。

编码过滤器

在之前学习Servlet时,有遇到请求中携带了中文数据,处理方案:

GET请求:  Tomcat8版本开始已解决
POST请求: response.setCharacterEncoding("UTF-8")

而在SpringMVC中已经提供好了编码过滤器,我们直接使用即可。

在ServletContainersInitConfig配置类中进行配置即可

public class ServletContainerInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }

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

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

    //POST请求乱码处理
    @Override
    protected Filter[] getServletFilters() {
        //spring封装的过滤器, 拦截所有的请求,如果是post请求,就将编码修改为指定编码
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("UTF-8");
        return new Filter[]{filter};
    }
}

日期处理

日期类型数据基于系统不同格式也不尽相同

  • 2088-08-18
  • 2088/08/18
  • 08/18/2088

接收形参时,根据不同的日期格式设置不同的接收方式

//@DateTimeFormat注解设置日期类型数据格式,默认格式:yyyy/MM/dd
@RequestMapping("/dateParam")
@ResponseBody
public String dateParam(Date date1, //使用默认格式:yyyy/MM/dd
                        @DateTimeFormat(pattern = "yyyy-MM-dd") Date date2,
                        @DateTimeFormat(pattern = "yyyy/MM/dd HH:mm:ss") Date date3){
    System.out.println("参数传递 date ==> "+date1);
    System.out.println("参数传递 date(yyyy-MM-dd) ==> "+date2);
    System.out.println("参数传递 date(yyyy/MM/dd HH:mm:ss) ==> "+date3);
    return "dateParam";
}
http://localhost:8080/dateParam?date1=2088/08/18&date2=2088-08-18&date3=2088/08/18 12:18:28

需要注意的是:使用@DateTimeFormat时,要配置@EnableWebMvc

12_SpringMVC的响应处理

目标

  • 能够使用SpringMVC给前端响应数据

路径

  1. SpringMVC的响应
  2. SpringMVC给前端响应数据

SpringMVC的响应

SpringMVC对响应的封装可以分为两类:

  1. 响应页面
  2. 响应数据
    • 字符串数据
    • json数据

SpringMVC响应数据时使用@ResponseBody注解:

  • 设置当前方法返回值作为响应体
@RequestMapping("/toText")
@ResponseBody  //设置当前控制器返回值作为响应体
public String toText(){
    System.out.println("返回纯文本数据");
    return "response text";
}


/* 
   只要配置好对应的环境 (导入jackson, 开启@EnableWebMvc)
   SpringMVC会自动将JavaBean返回值转成json格式字符串	
*/
@RequestMapping("/toJsonPOJO")
@ResponseBody //自动把对象类型,转换为json字符串(导入jackson, 开启@EnableWebMvc)
public User toJsonPOJO(){
    System.out.println("返回json对象数据");
    User user = new User("itheima",20);
    return user;//返回值是对象类型(把对象转换为json格式字符串)
}

SpringMVC给前端响应数据

代码示例:

  • 控制器类
@Controller
public class UserController {
    //响应文本数据
    //返回值为String类型,设置返回值为任意字符串信息,即可实现返回指定字符串信息,需要依赖@ResponseBody注解
    @RequestMapping("/toText")
    @ResponseBody
    public String toText(){
        System.out.println("返回纯文本数据");
        return "response text";
    }

    //响应POJO对象
    //返回值为实体类对象,设置返回值为实体类类型,即可实现返回对应对象的json数据,需要依赖@ResponseBody注解和@EnableWebMvc注解
    @RequestMapping("/toJsonPOJO")
    @ResponseBody
    public User toJsonPOJO(){
        System.out.println("返回json对象数据");
        User user = new User("itheima",20);
        return user;//把User对象转换为json格式字符串,再响应给前端
    }

    //响应POJO集合对象
    //返回值为集合对象,设置返回值为集合类型,即可实现返回对应集合的json数组数据,需要依赖@ResponseBody注解和@EnableWebMvc注解
    @RequestMapping("/toJsonList")
    @ResponseBody
    public List<User> toJsonList(){
        System.out.println("返回json集合数据");
        User user1 = new User();
        user1.setName("传智播客");
        user1.setAge(15);
        User user2 = new User();
        user2.setName("黑马程序员");
        user2.setAge(12);

        List<User> userList = new ArrayList<User>();
        userList.add(user1);
        userList.add(user2);
        
        return userList; //把集合对象转换为json格式字符串
    }

    //响应页面/跳转页面
    //返回值为String类型,设置返回值为页面名称,即可实现页面跳转
    @RequestMapping("/toJumpPage")   ////////今天课程内容,无法实现页面跳转
    public String toJumpPage(){
        System.out.println("跳转页面");
        return "index.jsp";
    }
}

使用postman测试:响应处理

  • 响应文本数据:String

    image-20220506105508729

  • 响应Pojo对象:User

    image-20220506105839196

  • 响应集合对象:List

    image-20220506110207004

小结

  • 在Controller中,给前端响应,可以使用:@ResponseBody
    • 把当前方法的返回值,作为响应体,响应给前端
  • 响应的数据是:json格式
    • 把Java对象类型,转换为json字符串
      • 步骤:
        1. 导入坐标:Jackson
        2. 开启json和对象的自动转换: @EnableWebMvc
        3. @ResponseBody: 会自动把Java对象,转换为json字符串

13_SpringMVC的RESTful风格

目标

  • 了解SpringMVC框架在三层架构存在的意义

路径

  1. RESTful介绍
  2. RESTful行为约定方式
  3. RESTful开发入门
  4. 使用组合注解优化RESTful开发

RESTful介绍

REST( Representational State Transfer) 翻译后意思是:表现层的状态转化

  • 一种网络资源的访问风格,定义了网络资源的访问方式

RESTful是按照REST风格访问网络资源。

传统风格访问路径:

http://localhost:80/user/get?id=1
http://localhost/user/delete?id=1

REST风格访问路径:

http://localhost/user/1

可以具有多个含义:
既可以是查询,也可以是删除,也可以是修改,也可以是添加(别人根本就不知道开发者在干嘛)

优点:

  1. 隐藏资源的访问行为,通过地址无法得知做的是何种操作(提高安全性)
  2. 简化书写

RESTful行为约定方式

RESTful使用url定位资源,用HTTP请求方式(GET,POST,PUT,DELETE)描述操作

GET(查询)   :  http://localhost/user     //GET请求方式
POST(保存)  :  http://localhost/user     //POST请求方式
PUT(更新)   :  http://localhost/user     //PUT请求方式
DELETE(删除):  http://localhost/user     //DELETE请求方式

注意:上述行为是约定方式,约定不是硬性规范,可以打破,所以称REST风格,而不是REST规范

RESTful开发入门

代码示例:

  • Pojo类
public class User {
    private Integer id;
    private String name;
    private Integer age;

    public User() {
    }
    public User(Integer id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    } 
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  • 控制器类
@Controller
public class RestfulController {
    //添加用户
    @RequestMapping(value = "/rest",method = RequestMethod.POST)
    @ResponseBody
    public String add(@RequestBody User user){
        System.out.println("add: " + user);
        return "add success";
    }

    //修改用户
    @RequestMapping(value = "/rest",method = RequestMethod.PUT)
    @ResponseBody
    public String update(@RequestBody User user){
        System.out.println("update: "+ user);
        return "update success";
    }

    //删除所有用户
    @RequestMapping(value = "/rest",method = RequestMethod.DELETE)
    @ResponseBody
    public String deleteAll(){
        System.out.println("deleteAll");
        return "delete all success";
    }

    //查询所有用户
    @RequestMapping(value = "/rest",method = RequestMethod.GET)
    @ResponseBody
    public List<User> findAll(){
        System.out.println("findAll");
        User user1 = new User(1,"传智播客",16);
        User user2 = new User(2,"黑马程序员",13);
        List<User> userList = new ArrayList<User>();
        Collections.addAll(userList,user1,user2);
        return userList;
    }

    //根据用户id删除用户
    @RequestMapping(value = "/rest/{id}",method = RequestMethod.DELETE)
    @ResponseBody
    public String deleteById(@PathVariable Integer id){
        System.out.println("deleteById : " + id);
        return "delete success";
    }

    //根据用户id查询用户
    @RequestMapping(value = "/rest/{id}",method = RequestMethod.GET)
    @ResponseBody
    public User findById(@PathVariable Integer id){
        System.out.println("findById : " + id);
        User user = new User(1,"itheima",16);
        return user;
    }

    //分页查询用户
    @RequestMapping(value = "/rest/{page}/{pageSize}",method = RequestMethod.GET)
    @ResponseBody
    public List<User> findByPage(@PathVariable Integer page,
                             @PathVariable Integer pageSize){
        System.out.println("findByPage : " + page + "," + pageSize);
        User user1 = new User(1,"传智播客",16);
        User user2 = new User(2,"黑马程序员",13);
        List<User> userList = new ArrayList<User>();
        Collections.addAll(userList,user1,user2);
        return userList;
    }
}

使用postman测试:RESTful风格请求

  • 添加用户

    image-20220506140937642

  • 查询所有用户

    image-20220506141228217

  • 根据用户id删除用户

    image-20220506141348436

  • 分页查询用户

    image-20220506141121914

使用组合注解优化RESTful开发

在SpringMVC中提供了一些组合注解,来简化代码的书写:

  • @RestController
    • 效果: @Controller + @ResponseBody
  • @GetMapping("/rest")
    • 效果: @RequestMapping(value = "/rest" , method = RequestMethod.GET)

代码示例:

  • 控制器类
//@Controller
@RestController // @RestController = @Controller + @ResponseBody
@RequestMapping("/rest")
public class RestfulController {
    //添加用户
    //@RequestMapping(value = "/rest",method = RequestMethod.POST)
    //@ResponseBody
    @PostMapping()
    public String add(@RequestBody User user){
        System.out.println("add: " + user);
        return "add success";
    }

    //修改用户
    //@RequestMapping(value = "/rest",method = RequestMethod.PUT)
    //@ResponseBody
    @PutMapping
    public String update(@RequestBody User user){
        System.out.println("update: "+ user);
        return "update success";
    }

    //删除所有用户
    //@RequestMapping(value = "/rest",method = RequestMethod.DELETE)
    //@ResponseBody
    @DeleteMapping
    public String deleteAll(){
        System.out.println("deleteAll");
        return "delete all success";
    }

    //查询所有用户
    //@RequestMapping(value = "/rest",method = RequestMethod.GET)
    //@ResponseBody
    @GetMapping
    public List<User> findAll(){
        System.out.println("findAll");
        User user1 = new User(1,"传智播客",16);
        User user2 = new User(2,"黑马程序员",13);
        List<User> userList = new ArrayList<User>();
        Collections.addAll(userList,user1,user2);
        return userList;
    }

    //根据用户id删除用户
    //@RequestMapping(value = "/rest/{id}",method = RequestMethod.DELETE)
    //@ResponseBody
    @DeleteMapping("/{id}")
    public String deleteById(@PathVariable Integer id){
        System.out.println("deleteById : " + id);
        return "delete success";
    }

    //根据用户id查询用户
    //@RequestMapping(value = "/rest/{id}",method = RequestMethod.GET)
    //@ResponseBody
    @GetMapping("/{id}")
    public User findById(@PathVariable Integer id){
        System.out.println("findById : " + id);
        User user = new User(1,"itheima",16);
        return user;
    }

    //分页查询用户
    //@RequestMapping(value = "/rest/{page}/{pageSize}",method = RequestMethod.GET)
    //@ResponseBody
    @GetMapping("/{page}/{pageSize}")
    public List<User> findByPage(@PathVariable Integer page,
                             @PathVariable Integer pageSize){
        System.out.println("findByPage : " + page + "," + pageSize);
        User user1 = new User(1,"传智播客",16);
        User user2 = new User(2,"黑马程序员",13);
        List<User> userList = new ArrayList<User>();
        Collections.addAll(userList,user1,user2);
        return userList;
    }
}

14_案例:基于RESTful页面数据交互

导入素材中的代码: springmvc_07_rest-case

  • 前端:vue+elementui
  • 后端:springmvc

标签:RequestMapping,return,请求,SpringMVC,day01,public,String
From: https://www.cnblogs.com/-turing/p/17206361.html

相关文章

  • SpringMVC-day02
    SpringMVC-day0201_基于SSM的三层架构目标了解基于SSM框架的三层架构技术体系路径SSM框架的三层架构技术体系SSM框架的三层架构技术体系在三层架构开发时会......
  • Spring-day01
    Spring-day01#前置课程1.javase 1).面向对象:封装,继承,多态(面向接口) 2).反射 3).动态代理2.javaweb 1).servlet编程规范 2).网络编程3.数据库 1).......
  • springmvc-通过控制器方法的形参获取请求参数
         ......
  • SpringMVC中的异常处理器
    SpringMVC中的异常处理器目录SpringMVC中的异常处理器一、概述二、异常处理器初始化位置默认策略@ControllerAdvice工作原理RequestMappingHandlerAdapterExceptionHandle......
  • 8_SpringMVC
    SpringMVCSpringMVC技术和Servlet技术功能等同,均属于web层开发技术学习目标掌握基于SpringMvc获取请求参数与响应json数据操作熟练应用基于REST风格的请求路径设置与......
  • 将springmvc.xml配置到resources目录
    web.xml配置<?xmlversion="1.0"encoding="UTF-8"?><web-appxmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-in......
  • Day01
    Linux-Day01课程内容Linux简介Linux安装Linux常用命令1.前言1.1什么是LinuxLinux是一套免费使用和自由传播的操作系统。说到操作系统,大家比较熟知的应该就是Wi......
  • 使用注解开发SpringMVC,也是以后开发的模板(重点)
    注解版配置SpringMVC(重点)第一步:新建一个moudel,添加web支持!建立包结构top.lostyou.controller第二步:由于maven可能存在资源过滤问题,我们将配置完善<!--在build中......
  • springmvc配置文件
    <?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"......
  • java-springmvc
    1、入门案例1.1、导包<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.18</version></dependency><de......