SpringMVC----(1)基础

news2024/10/6 4:04:41

SringMVC

  • 1 SpringMVC简介
  • 2 SpringMVC入门案例
    • 2.1 入门案例
    • 2.2 入门案例工作流程
    • 2.3 bean加载控制
    • 2.4 PostMan工具
  • 3 请求与响应
    • 3.1 请求映射路径
    • 3.2 Get和Post请求发送普通参数
    • 3.3 请求头的五种类型参数传递
    • 3.4 请求体的JSON数据传输参数
    • 3.5 日期型参数
    • 3.6 响应
  • 4 REST风格
    • 4.1 REST简介
    • 4.2 RESTful入门案例
    • 4.3 RESTful优化(简化开发)
    • 4.4 案例:基于RESTful页面数据交互

1 SpringMVC简介

SpringMVC是隶属于Spring框架的一部分,主要是用来进行Web开发,是对Servlet进行了封装。

  • SpringMVC技术与Servlet技术功能等同,均属于web层开发技术
  • SpringMVC是一种基于Java实现MVC模型的轻量级Web框架
  • 优点:使用简单,开发便捷(相比于Servlet);灵活性强

2 SpringMVC入门案例

2.1 入门案例

实现:

  1. 使用SpringMVC技术需要先导入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.zs</groupId>
    <artifactId>springmvc_01_quickstart</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>
        <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>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <port>8080</port>
                    <path>/</path>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
  1. 创建SpringMVC控制器类(等同于Servlet功能)
//设置springmvc的核心控制器bean,使用@Controller定义bean
@Controller
public class UserController {
    //设置当前控制器方法请求访问路径
    @RequestMapping("/save")
    //@ResponseBody设置当前控制器方法响应内容为当前返回值,无需解析
    @ResponseBody
    public String save(){
        System.out.println("user save ...");
        //如果不加@ResponseBody,系统会根据返回值字符串寻找路径,例如return "index.jsp";会跳转到jsp页面
        //返回真正json只需要返回对象,在pom引入jackson,springmvcconfig配置类注解@@EnableWebMvc,下面注释的语句就是返回JSON数据
        //return new User("zhangsan",23);
        return "{'info':'springmvc'}";
    }
}
  1. 初始化SpringMVC环境(同Spring环境),设定SpringMVC加载对应的bean
//3.创建SpringMVC的配置文件,加载controller对应的bean
@Configuration
@ComponentScan("com.zs.controller")
public class SpringMvcConfig {
}
  1. 初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术处理的请求
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
    //创建Servlet容器时,加载springmvc的配置。将springmvc对应的bean并放入WebApplicationContext对象范围中。
    //最终返回web容器WebApplicationContext ,web容器就是springmvc最终体现的容器。ApplicationContext应用上下文,容器
    protected WebApplicationContext createServletApplicationContext() {
        //创建注解配置的web容器。使用AnnotationConfigWebApplicationContext,比前面Spring创建注解容器的类AnnotationConfigApplicationContext中间多了Web
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        //加载springmvc的配置类字节码到web容器中,从而可以让web容器管理加载配置类管理的bean
        //因为AnnotationConfigWebApplicationContext类没有带参构造方法,所以要手动为容器加载指定配置类字节码文件
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }
 
    //设置由springmvc拦截并处理的请求路径,即springmvc拦截哪些请求。
    //返回值String数组只有一个"/",代表所有路径都由springmvc处理
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
 
    //加载spring配置类,方法和加载springmvc方法相同,只是加载的配置类改成spring的配置文件
    //如果创建Servlet容器时需要加载非表现层的bean,使用当前方法进行,使用方式和createServletApplicationContext相同。
    protected WebApplicationContext createRootApplicationContext() {
      AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringConfig.class);
        return ctx;
    }
}

运行:
在这里插入图片描述

  • @Controller
    在这里插入图片描述
  • @RequestMapping
    在这里插入图片描述
  • @ResponseBody
    在这里插入图片描述
  • AbstractDispatcherServletInitializer在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 案例总结:
    在这里插入图片描述

2.2 入门案例工作流程

在这里插入图片描述

  • 启动服务器初始化过程(容器初始化工作流程):
    • 服务器启动,执行ServletContainersInitConfig类,初始化web容器。功能类似于以前的web.xml
    • 执行createServletApplicationContext方法,创建了WebApplicationContext对象
    • 加载SpringMvcConfig配置类
    • 执行@ComponentScan加载对应的bean
    • 加载UserController,每个@RequestMapping的名称对应一个具体的方法
    • 执行getServletMappings方法,设定SpringMVC拦截请求的路径规则
  • 单次请求过程:
    • 发送请求http://localhost/save
    • web容器发现该请求满足SpringMVC拦截规则,将请求交给SpringMVC处理
    • 解析请求路径/save
    • 由/save匹配执行对应的方法save()
    • 执行save()
    • 检测到有@ResponseBody直接将save()方法的返回值作为响应体返回给请求方

2.3 bean加载控制

在这里插入图片描述

  • SpringMVC相关的bean(表现层bean,controller)
  • Spring控制的bean:业务bean(Service);功能bean(DataSource等)
  • 问题:因为功能不同,如何避免Spring错误加载到SpringMVC的bean?
  • 解决:加载Spring控制的bean的时候排除掉SpringMVC控制的bean
  • SpringMVC相关bean加载控制:
    SpringMVC加载的bean对应的包均在com.itheima.controller包内
  • Spring相关bean加兹安控制:
    方法一:Spring加载的bean设定扫描范围为com.itheima,排除掉controller包中的bean
    方法二:Spring加载的bean设定扫描范围为精准范围,例如service包、dao包等
    方式三:不区分Spring与SpringMVC的环境,加载到同一个环境中(了解)

方式一:

@Configuration
@ComponentScan({"com.itheima.service","comitheima.dao"})
public class SpringConfig {
}

方式二:

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

excludeFilters属性:设置扫描加载bean时,排除的过滤规则
type属性:设置排除规则,当前使用按照bean定义时的注解类型进行排除
ANNOTATION:按照注解排除
ASSIGNABLE_TYPE:按照指定的类型过滤
ASPECTJ:按照Aspectj表达式排除,基本上不会用
REGEX:按照正则表达式排除
CUSTOM:按照自定义规则排除
大家只需要知道第一种ANNOTATION即可
classes属性:设置排除的具体注解类,当前设置排除@Controller定义的bean

总结:
在这里插入图片描述

  • bean的加载格式:
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
    protected WebApplicationContext createRootApplicationContext() {
      AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringConfig.class);
        return ctx;
    }
}
  • 简化开发
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
 
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }
 
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }
 
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

2.4 PostMan工具

如果要求发送的是post请求,我们就得准备页面在页面上准备form表单,测试起来比较麻烦。所以我们就需要借助一些第三方工具,如PostMan

  • PostMan是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件
  • 作用:常用于进行接口测试
  • 特征:简单、实用、美观、大方

基本使用:

  • 注册登录

  • 创建工作空间/进入工作空间
    在这里插入图片描述

  • 发起请求测试结果
    在这里插入图片描述

3 请求与响应

3.1 请求映射路径

思考:团队多人开发,每个人设置不同的请求路径,冲突问题如何解决?
解决:设置模块名作为请求路径前缀
@RequestMapping
在这里插入图片描述

3.2 Get和Post请求发送普通参数

  • Get请求传参
    普通参数:url地址传参,地址参数与形参变量名相同,定义形参即可接受参数
    在这里插入图片描述
  • Post请求参数
    普通参数:form表单post请求传参,表单参数名与形参变量名相同,定义形参即可接收参数
    在这里插入图片描述
  • Get请求中文乱码问题解决
    如果Tomcat8.5之前版本,我们传递的参数中有中文,接收到的参数会出现中文乱码问题。
    解决乱码:
    Tomcat8.5以后的版本已经处理了中文乱码的问题,但是IDEA中的Tomcat插件目前只到Tomcat7,所以需要修改pom.xml来解决GET请求中文乱码问题
<build>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <port>80</port><!--tomcat端口号-->
          <path>/</path> <!--虚拟目录-->
          <uriEncoding>UTF-8</uriEncoding><!--访问路径编解码字符集-->
        </configuration>
      </plugin>
    </plugins>
  </build>
  • Post请求中文乱码问题
    所有Tomcat版本都中文乱码
    解决:配置过滤器,在Servlet容器配置类里,alt+insert重写getServletFilters过滤器方法
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }
 
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }
 
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
 
    //重写getServletFilters过滤器方法,返回数组传入CharacterEncodingFilter过滤器对象,乱码处理
    @Override
    protected Filter[] getServletFilters() {
        //创建字符编码过滤器CharacterEncodingFilter对象
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        //设置编码
        filter.setEncoding("UTF-8");
        //返回过滤器数组,元素为CharacterEncodingFilter对象
        return new Filter[]{filter};
    }
}

说明:CharacterEncodingFilter是在spring-webmvc包中,会自动导入对应的依赖jar包

3.3 请求头的五种类型参数传递

  • 普通参数
    问题:如果形参与地址参数名不一致该如何解决?
    解决方案:使用@RequestParam注解,用法跟dao层传参@Param类似

示例:
发送请求与参数:

http://localhost/commonParamDifferentName?name=张三&age=18

接收参数::

	@RequestMapping("/commonParamDifferentName")
    @ResponseBody
    public String commonParamDifferentName(@RequestParam("name") String userName , int age){
        System.out.println("普通参数传递 userName ==> "+userName);
        System.out.println("普通参数传递 age ==> "+age);
        return "{'module':'common param different name'}";
    }
  • POJO数据类型
    请求参数名与形参对象的属性名相同,定义POJO类型形参即可接收参数

示例:
POJO类,User

public class User {
    private String name;
    private int age;
    //setter...getter...略
}

发送请求和参数:

http://localhost/commonParamDifferentName?name=张三&age=18

接收参数:

//POJO参数:请求参数与形参对象中的属性对应即可完成参数传递
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
    System.out.println("pojo参数传递 user ==> "+user);
    return "{'module':'pojo param'}";
}

说明:请求参数key的名称要和POJO中属性的名称一致,否则无法封装

  • 嵌套POJO类型参数
    请求参数名与形参对象属性名相同,注意内嵌的pojo类在发送请求时参数要设成内嵌类对象.属性名,形参依然是传外层类的对象,按照对象层次结构关系即可接收嵌套POJO属性参数

示例:
发送请求和参数:
在这里插入图片描述接收参数:

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

示例:
在这里插入图片描述

  • 集合类型参数
    请求参数名与形参集合对象名相同,且请求参数为多个,@RequestParam绑定参数关系
    在这里插入图片描述
    在这里插入图片描述

3.4 请求体的JSON数据传输参数

  1. 添加json数据转换相关坐标
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.0</version>
        </dependency>
  1. 设置发送json数据(请求body中添加json数据)
    在这里插入图片描述
  2. 开启自动转换json数据的支持@EnableWebMvc
@Configuration
@ComponentScan("com.itheima.controller")
//开启json数据类型自动转换
@EnableWebMvc
public class SpringMvcConfig {
}

说明:@EnableWebMvc,这个注解功能很强大,这里用到的是将JSON数据自动类型转换成对象的功能

4.设置接收json数据@RequestBody

  • JSON普通数组:
    在这里插入图片描述
 
@RequestMapping("/listParamForJson")
@ResponseBody
//使用@RequestBody注解将前端请求体传递的json数组数据,传递并转换到形参的集合对象中作为数据
public String listParamForJson(@RequestBody List<String> likes){
    System.out.println("list common(json)参数传递 list ==> "+likes);
    return "{'module':'list common for json param'}";
}
  • JSON对象(POJO)
    在这里插入图片描述
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
    System.out.println("pojo(json)参数传递 user ==> "+user);
    return "{'module':'pojo for json param'}";
}
  • JSON对象数组(POJO)
    在这里插入图片描述
@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'}";
}
  • @EnableWebMvc
    在这里插入图片描述
  • @RequestBody
    在这里插入图片描述
  • @RequestBody与@RequestParam区别
    在这里插入图片描述

3.5 日期型参数

  • 日期类型数据基于系统不同格式也不尽相同
    在这里插入图片描述
  • 接收形参时,根据不同的日期格式设置不同的接收方式
@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("参数传递 date1(yyyy-MM-dd) ==> "+date1);
    System.out.println("参数传递 date2(yyyy/MM/dd HH:mm:ss) ==> "+date2);
    return "{'module':'data param'}";
}

使用PostMan发送请求,携带两个不同的日期格式:

http://localhost/dataParam?date=2088/08/08&date1=2088-08-08&date2=2088/08/08 8:08:08
  • @DataTimeFormat
    在这里插入图片描述
  • 类型转换内部实现原理:类型转换器
    后台需要的数据类型有很多中在数据的传递过程中存在很多类型的转换,如:前端传递字符串,后端使用日期Date接收等等
    问题:谁来做这个类型转换?如何实现类型转换的?
    答案:SpringMVC,提供了很多类型转换接口和实现类
    • Converter接口,所属的包为org.springframework.core.convert.converter:
      在这里插入图片描述
      框架中有提供很多对应Converter接口的实现类,用来实现不同数据类型之间的转换,如:
      请求参数年龄数据(String→Integer)
      日期格式转换(String → Date)
  • HttpMessageConverter接口:该接口是实现对象与JSON之间的转换工作

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

3.6 响应

  • 响应页面
@Controller
public class UserController {
 
    @RequestMapping("/toJumpPage")
    //注意
    //1.此处不能添加@ResponseBody,如果加了该注入,会直接将page.jsp当字符串返回前端
    //2.方法需要返回String
    public String toJumpPage(){
        System.out.println("跳转页面");
        return "page.jsp";
    }
 
}
  • 响应数据:文本数据
@Controller
public class UserController {
 
    @RequestMapping("/toText")
    //注意此处该注解就不能省略,如果省略了,会把response text当前页面名称去查找,如果没有回报404错误
    @ResponseBody
    public String toText(){
        System.out.println("返回纯文本数据");
        return "response text";
    }
 
}
  • 响应数据:JSON数据(对象转JSON)
@Controller
public class UserController {
 
    @RequestMapping("/toJsonPOJO")
    @ResponseBody
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")    //导入jackson-databind后可以格式化日期格式
    public User toJsonPOJO(){
        System.out.println("返回json对象数据");
        User user = new User();
        user.setName("itcast");
        user.setAge(15);
        return user;
    }
}

返回值为实体类对象,设置返回值为实体类类型,即可实现返回对应对象的json数据,需要依赖@ResponseBody注解和@EnableWebMvc注解

  • 响应数据:JSON数据(对象集合转JSON数组)
@Controller
public class UserController {
 
    @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;
    }
 
}
  • @ResponseBody
    在这里插入图片描述

当方法上有@ReponseBody注解后
方法的返回值为字符串,会将其作为文本内容直接响应给前端
方法的返回值为对象,会将对象转换成JSON响应给前端

此处又使用到了类型转换,内部通过HttpMessageConverter接口的实现类完成的

4 REST风格

4.1 REST简介

  • REST(Representational State Transfer),表现性状态转换,它是一种软件架构风格
    • 传统风格资源描述形式
      在这里插入图片描述

    • REST风格描述形式
      在这里插入图片描述

  • 优点
    • 隐藏资源访问行为,无法通过地址得知对资源是何种操作
    • 书写简化

问题:一个相同的url地址即可以是新增也可以是修改或者查询,我们该如何区分?
答:通过调用它的行为进行区分

  • 按照REST风格访问资源时使用行为动作即请求方式区分对资源进行了何种操作
    • http://localhost/users 查询全部用户信息 GET(查询)
    • http://localhost/users/1 查询指定用户信息 GET(查询)
    • http://localhost/users 添加用户信息 POST(新增/保存)
    • http://localhost/users 修改用户信息 PUT(修改/更新)
    • http://localhost/users/1 删除用户信息 DELETE(删除)
  • 根据REST风格对资源进行访问称为RESTful

4.2 RESTful入门案例

环境准备:
1.导入坐标:

<?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_06_rest</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>
 
  <dependencies>
    <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>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>
  </dependencies>
 
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <port>8080</port>
          <path>/</path>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
  1. 创建实体类User和Book
  public class User {
      private String name;
      private int age;
      //getter...setter...toString省略
  }
 
  public class Book {
      private String name;
      private double price;
       //getter...setter...toString省略
  }
  1. 编写UserController和BookController
  @Controller
  public class UserController {
      @RequestMapping("/save")
      @ResponseBody
      public String save(@RequestBody User user) {
          System.out.println("user save..."+user);
          return "{'module':'user save'}";
      }
 
      @RequestMapping("/delete")
      @ResponseBody
      public String delete(Integer id) {
          System.out.println("user delete..." + id);
          return "{'module':'user delete'}";
      }
 
      @RequestMapping("/update")
      @ResponseBody
      public String update(@RequestBody User user) {
          System.out.println("user update..." + user);
          return "{'module':'user update'}";
      }
 
      @RequestMapping("/getById")
      @ResponseBody
      public String getById(Integer id) {
          System.out.println("user getById..." + id);
          return "{'module':'user getById'}";
      }
 
      @RequestMapping("/findAll")
      @ResponseBody
      public String getAll() {
          System.out.println("user getAll...");
          return "{'module':'user getAll'}";
      }
  }
 
 
  @Controller
  public class BookController {
 
      @RequestMapping(value = "/books",method = RequestMethod.POST)
      @ResponseBody
      public String save(@RequestBody Book book){
          System.out.println("book save..." + book);
          return "{'module':'book save'}";
      }
 
      @RequestMapping(value = "/books/{id}",method = RequestMethod.DELETE)
      @ResponseBody
      public String delete(@PathVariable Integer id){
          System.out.println("book delete..." + id);
          return "{'module':'book delete'}";
      }
 
      @RequestMapping(value = "/books",method = RequestMethod.PUT)
      @ResponseBody
      public String update(@RequestBody Book book){
          System.out.println("book update..." + book);
          return "{'module':'book update'}";
      }
 
      @RequestMapping(value = "/books/{id}",method = RequestMethod.GET)
      @ResponseBody
      public String getById(@PathVariable Integer id){
          System.out.println("book getById..." + id);
          return "{'module':'book getById'}";
      }
 
      @RequestMapping(value = "/books",method = RequestMethod.GET)
      @ResponseBody
      public String getAll(){
          System.out.println("book getAll...");
          return "{'module':'book getAll'}";
      }
 
  }
  1. 创建对应的配置类
  public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
      protected Class<?>[] getRootConfigClasses() {
          return new Class[0];
      }
 
      protected Class<?>[] getServletConfigClasses() {
          return new Class[]{SpringMvcConfig.class};
      }
 
      protected String[] getServletMappings() {
          return new String[]{"/"};
      }
 
      //乱码处理
      @Override
      protected Filter[] getServletFilters() {
          CharacterEncodingFilter filter = new CharacterEncodingFilter();
          filter.setEncoding("UTF-8");
          return new Filter[]{filter};
      }
  }
 
  @Configuration
  @ComponentScan("com.itheima.controller")
  //开启json数据类型自动转换
  @EnableWebMvc
  public class SpringMvcConfig {
  }

REST风格实现@RequestMapping的method属性,@PathVariable

  1. 设定http请求动作 @RequestMapping的method属性
    @RequestMapping(value = "/users",method = RequestMethod.POST)
    @ResponseBody
    public String save() {
        System.out.println("user save...");
        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'}";
    }
  1. 设定请求参数路径(路径变量)
    @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
    在这里插入图片描述
  • @PathVariable
    在这里插入图片描述
  • @RequestBody @RequestParam @PathVariable
    在这里插入图片描述

4.3 RESTful优化(简化开发)

/*@Controller
@ResponseBody*/
@RestController
@RequestMapping("/books")
public class BookController {
    //@RequestMapping(method = RequestMethod.POST)
    @PostMapping
    public String save(@RequestBody Book book){
        System.out.println("book save..." + book);
        return "{'module':'book save'}";
    }

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

    //@RequestMapping(method = RequestMethod.PUT)
    @PutMapping
    public String update(@RequestBody Book book){
        System.out.println("book update..." + book);
        return "{'module':'book update'}";
    }

    //@RequestMapping(value = "/{id}",method = RequestMethod.GET)
    @GetMapping("/{id}")
    public String getById(@PathVariable Integer id){
        System.out.println("book getById..." + id);
        return "{'module':'book getById'}";
    }

    //@RequestMapping(method = RequestMethod.GET)
    @GetMapping
    public String getAll(){
        System.out.println("book getAll...");
        return "{'module':'book getAll'}";
    }
}

  • @RestController
    在这里插入图片描述
  • 4种标准请求动作映射(@GetMapping @PostMapping @PutMapping @DeleteMapping)
    在这里插入图片描述

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

实现:

1.搭建项目导入jar包
2.编写Controller类,提供两个方法,一个用来做列表查询,一个用来做新增
3.在方法上使用RESTful进行路径设置
4.完成请求、参数的接收和结果的响应
5.使用PostMan进行测试
6.将前端页面拷贝到项目中
7.页面发送ajax请求
8.完成页面数据的展示

  1. 导入依赖
<?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.zs</groupId>
    <artifactId>spring_rest_case</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>
        <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>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <port>8080</port>
                    <path>/</path>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
  1. 实体类Book
  public class Book {
      private Integer id;
      private String type;
      private String name;
      private String description;
      //setter...getter...toString略
  }
  1. BookController
@RestController
@RequestMapping("/books")
public class BookController {
    @PostMapping
    public String save(@RequestBody Book book) {
        System.out.println("book save =>"+book);
        return "{'module':'book save success'}";
    }
    @GetMapping
    public List<Book> getAll() {
        System.out.println("book getAll is running ...");
        List<Book> bookList = new ArrayList<Book>();

        Book book1 = new Book();
        book1.setType("计算机");
        book1.setName("SpringMVC入门教程");
        book1.setDescription("小试牛刀");
        bookList.add(book1);

        Book book2 = new Book();
        book2.setType("计算机");
        book2.setName("SpringMVC实战教程");
        book2.setDescription("一代宗师");
        bookList.add(book2);

        Book book3 = new Book();
        book3.setType("计算机丛书");
        book3.setName("SpringMVC实战教程进阶");
        book3.setDescription("一代宗师呕心创作");
        bookList.add(book3);

        return bookList;
    }
}

  1. 创建对应的配置类
  public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
      protected Class<?>[] getRootConfigClasses() {
          return new Class[0];
      }
 
      protected Class<?>[] getServletConfigClasses() {
          return new Class[]{SpringMvcConfig.class};
      }
 
      protected String[] getServletMappings() {
          return new String[]{"/"};
      }
 
      //乱码处理
      @Override
      protected Filter[] getServletFilters() {
          CharacterEncodingFilter filter = new CharacterEncodingFilter();
          filter.setEncoding("UTF-8");
          return new Filter[]{filter};
      }
  }
 
  @Configuration
  @ComponentScan("com.zs.controller")
  //开启json数据类型自动转换
  @EnableWebMvc
  public class SpringMvcConfig {
  }
  1. PostMan测试
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  2. 拷贝静态页面
    在这里插入图片描述
  3. 访问pages目录下的books.html
    在这里插入图片描述
    问题:在这里插入图片描述
    原因:SpringMVC拦截了静态资源,根据/pages/books.html去controller找对应的方法,找不到所以会报404的错误。静态资源应该交给Tomcat处理,而不是springmvc处理
    在这里插入图片描述
    解决方案:SpringMVC将静态资源进行放行
    方式一:
    创建 SpringMvcSupport 配置类,设置静态资源访问过滤。
    继承WebMvcConfigurationSupport 类,重写addResourceHandlers方法
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        //当访问/pages/**时,走/pages目录下的内容
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    }
}

SpringMvcConfig扫描SpringMvcSupport配置类


@Configuration
//@ComponentScan({"com.itheima.controller","com.itheima.config"})
@ComponentScan("com.zs")
@EnableWebMvc
public class SpringMvcConfig {
}

方式二:
SpringMvcConfig 实现WebMvcConfigurer 接口,既可以添加资源处理器,也可以添加拦截器,既然不用config的SpringMvcSupport,springmvc配置类也就不用扫描config目录

@Configuration
@ComponentScan({"package1.controller"})
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer {
    @Autowired
    private ProjectInterception projectInterception;
    //添加拦截器,配置本地资源映射路径,在访问A(虚拟的)的时候,需要到B(实际的)的位置去访问。
//    @Override
//    public void addInterceptors(InterceptorRegistry registry) {
//        registry.addInterceptor(projectInterception).addPathPatterns("/books","/books/*");
        //如果只拦截/books,发送http://localhost/books/100后会发现拦截器没有被执行
        //registry.addInterceptor(projectInterceptor).addPathPatterns("/books");
//    }
    //添加资源处理器
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    }
}
  1. 前端页面通过异步提交访问后台控制器
saveBook () {
    axios.post("/books",this.formData).then((res)=>{
        
    });
},
//主页列表查询
getAll() {
    axios.get("/books").then((res)=>{
        this.dataList = res.data;
    });
},


参考文章

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/786825.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringCloud整合Nacos配置中心

&#x1f4dd; 学技术、更要掌握学习的方法&#xff0c;一起学习&#xff0c;让进步发生 &#x1f469;&#x1f3fb; 作者&#xff1a;一只IT攻城狮 &#xff0c;关注我&#xff0c;不迷路 。 &#x1f490;学习建议&#xff1a;1、养成习惯&#xff0c;学习java的任何一个技术…

NoSQL之Redis配置使用

目录 一、关系数据库与非关系型数据库 1.1.关系型数据库的概述 1.2关系型数据库的优缺点 1.2.1优点 1.2.2缺点 1.3.非关系型数据库的概述 二.关系数据库与非关系型数据库的区别 2.1数据存储方式不同 2.2扩展方式不同 2.3对事务性的支持不同 2.4非关系型数据库产生背景 2…

亚马逊攀岩绳EN892:2012+A1:2016安全带标准、攀岩安全带EN 12277:2015登山装备要求和ASTM F1772–17体育运动安全标准规范

如果您在亚马逊商城发布商品&#xff0c;则必须遵守适用于这些商品和商品信息的所有联邦、州和地方法律以及亚马逊政策&#xff08;包括本政策&#xff09;。 本政策适用的攀岩安全带 本政策适用于主要在攀岩或登山期间使用且使用者双脚不接触地面时使用的安全带。安全带是一种…

Xshell使用sftp传输文件

单击工具栏新建回话图标&#xff0c;在弹出的新建回话窗口中协议选择SFTP&#xff0c;输入主机名或ip地址&#xff0c;端口号22&#xff0c;单击连接&#xff0c;输入用户名和密码完成创建连接。 本地/远程目录设置&#xff1a;新建会话时在下图中SFTP中设置文件上传下载的本地…

基于vue+element 分页的封装

目录标题 项目场景&#xff1a;认识分页1.current-page2.page-sizes3.page-size4.layout5.total6.size-change7.current-change 封装分页&#xff1a;创建paging&#xff1a;进行封装 页面中使用&#xff1a;引入效果 项目场景&#xff1a; 分页也是我们在实际应用当中非常常见…

Nginx与Tomcat服务器的区别以及个人网站部署方案

- Nginx和Tomcat作用一样吗&#xff1f; 答&#xff1a;不完全相同。Nginx 和 Tomcat 都可以作为 Web 服务器&#xff0c;但它们的作用略有不同。 Nginx 是一个高性能的 Web 服务器和反向代理服务器。它的主要作用是提供静态文件服务、反向代理、负载均衡、缓存、SSL 加密等功…

《PyTorch深度学习实践》

文章目录 1.线性模型2.梯度下降算法3.反向传播3.1原理3.2Tensor in PyTorch 4.用PyTorch实现线性模型 1.线性模型 2.梯度下降算法 # 梯度下降x_data [1.0,2.0,3.0] y_data [2.0,4.0,6.0]w 3.0def forward(x):return x*w# 损失函数 def cost(xs,ys):cost 0for x,y in zip(x…

VR全景在酒店的发展状况如何?酒店该如何做营销?

现阶段&#xff0c;VR全景技术已经被酒店、民宿、旅游景区、房产楼盘、校园等行业所应用&#xff0c;每天都有不少人通过VR全景展示来了解酒店的设施环境&#xff0c;而酒店也可以借此机会&#xff0c;详细展示自身优势&#xff0c;更大范围吸引顾客。 VR酒店拥有真实、立体的全…

某商业落地充电桩后台服务器通迅协议V4.9.

充电机智能终端与智能中心管理系统 通迅协议 目录 一、网络拓扑 4 1.1 功能界定 4 1.1.1 充电机智能终端 4 1.1.2 智能中心管理系统 4 1.2 接口定义 4 1.3 通信方式 4 1.4 通信规约 5 1.5 报文格式 7 1.6 关键命令 8 二、应用层 9 2.1 数据格式&#xff1a; 9 2.2…

全面解析Bootstrap排版使用方法(文字样式)

全面解析Bootstrap排版使用方法&#xff08;文字样式&#xff09; 一、段落 段落是排版中另一个重要元素之一。在Bootstrap中为文本设置了一个全局的文本样式&#xff08;这里所说的文本是指正文文本&#xff09;&#xff1a; 1、全局文本字号为14px(font-size)。 2、行高为…

bash: /etc/profile: 权限不够

添加环境变量的时候显示没有权限 echo “export PATH”/usr/local/ARM-toolchain/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/:$PATH"" >> /etc/profile bash: /etc/profile: 权限不够 sudo chmod 777 /etc/profile echo “export PATH”/us…

Flink任务优化分享

Flink任务优化分享 1.背景介绍 线上计算任务在某版本上线之后发现每日的任务时长都需要三个多小时才能完成&#xff0c;计算时间超过了预估时间&#xff0c;通过Dolphinscheduler的每日调度任务看&#xff0c;在数据层 dwd 的数据分段任务存在严重的性能问题&#xff0c;每天…

安装requests模块及其他依赖库的完美解决办法

业务场景 导入requests库时报错&#xff0c;单独离线下载安装requests&#xff0c;发现仍然报错&#xff0c;问题在于requests库有其他依赖库。 WARNING: Retrying (Retry(total1, connectNone, readNone, redirectNone, statusNone)) after connection broken by NewConnect…

【历史上的今天】7 月 24 日:Caldera 诉微软案;AMD 宣布收购 ATI;谷歌推出 Chromecast

整理 | 王启隆 透过「历史上的今天」&#xff0c;从过去看未来&#xff0c;从现在亦可以改变未来。 今天是 2023 年 7 月 24 日&#xff0c;在 1951 年的今天&#xff0c;晶体管发明家 John Bardeen 通知 AT&T 贝尔实验室&#xff0c;他将离开公司&#xff0c;与 Walter B…

PaddleOCR #PP-OCR常见异常扫雷

异常一&#xff1a;ModuleNotFoundError: No module named ‘tools.infer’ 实验案例&#xff1a; PaddleOCR #使用PaddleOCR进行光学字符识别&#xff08;PP-OCR文本检测识别&#xff09; 参考代码&#xff1a; 图片文本检测实验时&#xff0c;运行代码出现异常&#xff1a;M…

查看端口是否开通的方法

1.使用curl方式 curl -vv telnet://192.168.2.95:6080 在没有wget的本地化服务器中&#xff0c;可以使用该方法查看端口。 2.使用telnet方式 telnet ip 端口 失败的情况&#xff1a; 3.在安卓设备上使用adb的方式查看端口是否开放 adb shell nc ip 端口 4.还有一种思路…

PgSQL-使用技巧-如何衡量网络对性能的影响

PgSQL-使用技巧-如何衡量网络对性能的影响 PG数据库和应用之间常见的部件有连接池、负载平衡组件、路由、防火墙等。我们常常不在意或者认为涉及的网络hops对整体性能产生的额外开销是理所当然的。但在很多情况下&#xff0c;它可能会导致严重的性能损失和拖累整体吞吐量。相当…

Python中的datetime模块

time模块用于取得UNIX纪元时间戳&#xff0c;并加以处理。但是&#xff0c;如果以方便的格式显示日期&#xff0c;或对日期进行算数运算&#xff0c;就应该使用datetime模块。 目录 1. datetime数据类型 1&#xff09; datetime.datetime.now()表示特定时刻 2&#xff09;da…

K8s卷存储详解(一)

K8s卷存储详解&#xff08;一&#xff09; K8s 存储K8s卷分类K8s目前支持的卷类型 临时卷类型EmptyDirCSI 临时卷通用临时卷 K8s 存储 什么是卷&#xff1f;为什么要用卷&#xff1f; 我们知道K8s是基于容器&#xff0c;对各个Pod进行管理的。Pod是由容器构成的&#xff0c;我…

一图读懂数电票丨发票新时代的机遇与挑战

随着国家“金税4期”的推进,“全电票”近期被正式更名为“数电票”。它的出现为企业的发票管理带来了哪些机遇与挑战?下图为你简单梳理: 数电票的应用,将有助于彻底解决现有业务流程中的发票管理环节存在的集中化和自动化难题。它将推动对发票的管理与企业的业务流程、法务工…