1 Star 0 Fork 0

cgrs572/SpringMvcDemo

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

SpringMVC获取请求参数

  • 环境准备工作等均省略,可详见快速入门,此处只写非共有部分代码

  • 该部分示例项目SpringMvcThree已上传至Gitee,可自行下载

  • 客户端请求参数的格式为:name=value&password=value... ...

  • 服务端想要获取请求参数有时需要对数据进行封装,SpringMVC可接收如下类型的参数

    • 普通数据类型(基本数据类型以及字符串类型)
    • POJO类型
    • 数组类型
    • 集合类型

获取普通数据类型

  • 注意

    • Controller中的业务方法的参数名称要与请求参数的名称一致,如图所示

      <img alt="image-20240722173311114">

      在该截图中返回值为void,代表controller控制器中的该业务方法quickMethod9不回写数据,但仍然需要@ResponseBody注解,此时代表ResponseBody的响应体为空,也就是说前端页面为空。

    • 针对获取普通数据类型来说,参数未自动映射匹配有两种方法:

      • 在pom.xml文件中添加maven插件

      • 使用@RequestParam注解

      • 以上两种方式详见代码示例部分

代码示例

  • 此处只写controller控制器类,其余部分搭建可详见快速入门以及数据响应部分内容

  • 在controller包下创建UserController类,代码如下

    //将Usercontroller放到Spring容器中
    @Controller
    @RequestMapping("/user")
    public class UserController {
    
        @ResponseBody
        @RequestMapping(value = "/quick1")
        public void save1(String username, int age) {
            System.out.println("name:" + name);
            System.out.println("age:" + age);
        }
    }
    

    此时运行截图如下,会报错

    <img alt="image-20241121222247734">

    报错原因:错误说明 Spring MVC 无法推断参数名称,通常是因为编译时没有启用参数名的保留功能,或者方法参数缺少显式绑定的注解

  • ==解决方法==

    • 方案一: 启用参数名的保留功能,即在pom.xml文件中加上maven插件,插件代码如下:

      <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <!-- maven插件版本 -->
          <version>3.13.0</version> 
          <configuration>
              <!-- 所使用的Java版本 -->
              <source>21</source> 
              <target>21</target>
              <compilerArgs>
                  <arg>-parameters</arg>
              </compilerArgs>
          </configuration>
      </plugin>
      

      <img alt="image-20241121223131756">

    • 方案二: 为方法参数添加 @RequestParam 注解,明确指定参数名称,更改后的UserController类,代码如下

      • 注意:获取普通数据类型的参数以方案二为准,以此来避免影响后续获取其它类型参数的示例操作(即以pom.xml文件中未添加maven插件来演示后续获取各种类型的请求参数的操作,以此来证明其它类型均可自动映射匹配)
      //将Usercontroller放到Spring容器中
      @Controller
      @RequestMapping(value = "/user")
      public class UserController {
      
      
          @RequestMapping(value = "quick1")
          @ResponseBody
          public void save1(@RequestParam("username")String username, @RequestParam("age")int age) throws IOException {
              System.out.println(username);
              System.out.println(age);
          }
      }
      

    运行后前端页面为空白,但是控制台会有输出,如图所示

    <img alt="image-20241121223411922">

获取POJO类型

  • 注意

    • Controller中业务方法的参数为pojo类对象,且该pojo类中的的属性名要与请求参数的名称一致,如图所示

      <img alt="image-20241122132859810">

    • 获取POJO类型时,不需要去添加maven插件或使用@RequestParam注解来使参数自动映射匹配,在本代码示例中的获取普通数据类型使用的是注解方式来进行参数匹配,以此来区别说明POJO类型不需要去添加maven插件或使用@RequestParam注解。

代码示例

  • 创建pojo包,并在该包下创建一个User类,代码如下

    package at.guigu.pojo;
    
    public class User {
        private String name;
        private int age;
        public User() {}
        public User(String name, int age) {
            this.name = name;
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
  • 在controller包下的UserController类中添加save2方法,完整代码如下:

    package at.guigu.controller;
    
    import at.guigu.pojo.User;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.io.IOException;
    
    //将Usercontroller放到Spring容器中
    @Controller
    @RequestMapping(value = "/user")
    public class UserController {
    
        // 获取普通数据类型
        @RequestMapping(value = "/quick1")
        @ResponseBody
        public void save1(@RequestParam("username")String username, @RequestParam("age")int age) throws IOException {
            System.out.println(username);
            System.out.println(age);
        }
    
        // 获取pojo类型
        @ResponseBody
        @RequestMapping("/quick2")
        public void save2(User user) throws IOException {
            System.out.println(user);
        }
    
    }
    

    <img alt="image-20241122134859145">

获取数组类型

  • 注意:

    • Controller中业务方法的参数的数组名称要与请求参数的名称一致,如图所示

      <img alt="image-20241122135326923">

    • 针对获取数组类型来说,参数未自动映射匹配有两种方法:

      • 在pom.xml文件中添加maven插件

      • 使用@RequestParam注解

      • 以上两种方法的操作与获取获取普通数据类型一致,可详见获取普通数据类型部分的代码示例,此处仅以注解形式示例

代码示例

  • 在controller包下的UserController类中添加save3方法,完整代码如下:

    package at.guigu.controller;
    
    import at.guigu.pojo.User;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.io.IOException;
    import java.util.Arrays;
    
    //将Usercontroller放到Spring容器中
    @Controller
    @RequestMapping(value = "/user")
    public class UserController {
    
        // 获取普通数据类型
        @RequestMapping(value = "/quick1")
        @ResponseBody
        public void save1(@RequestParam("username")String username, @RequestParam("age")int age) throws IOException {
            System.out.println(username);
            System.out.println(age);
        }
    
        // 获取POJO类型
        @ResponseBody
        @RequestMapping("/quick2")
        public void save2(User user) throws IOException {
            System.out.println(user);
        }
    
        // 获取数组类型
        @ResponseBody
        @RequestMapping("/quick3")
        public void save3(@RequestParam("strs")String[] strs) throws IOException {
            // 由于直接打印数组时只会打印出其地址,所以将其转为List集合输出到控制台
            System.out.println(Arrays.asList(strs));
        }
    }
    

    <img alt="image-20241122140622192">

获取集合类型

  • 有两种获取方式
    • 使用POJO类进行集合封装,然后获取集合类型的请求参数
    • 不使用POJO类进行集合封装

方式一:使用POJO类进行集合封装

  • 注意
    • 获取集合参数时,要将集合参数封装到一个POJO类中才可以,也就是说,集合要封装到一个对象中(一般定义为VO类),作为这个对象里面的私有属性存在.此时就相当于获取POJO类型,详见代码示例

代码示例

  • Step1:POJO类中创建User类(代码详见获取POJO类型),创建VO类,代码如下

    package at.guigu.pojo;
    
    import java.util.List;
    
    public class VO {
    
        // 将想要获取的集合封装到对象中
        private List<User> userList;
    
        public List<User> getUserList() {
            return userList;
        }
    
        public void setUserList(List<User> userList) {
            this.userList = userList;
        }
    
        @Override
        public String toString() {
            return "VO{" +
                    "userList=" + userList +
                    '}';
        }
    }
    
  • Step2:在controller包下的UserController类中添加save4方法,完整代码如下:

    package at.guigu.controller;
    import at.guigu.pojo.User;
    import at.guigu.pojo.VO;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.io.IOException;
    import java.util.Arrays;
    
    //将Usercontroller放到Spring容器中
    @Controller
    @RequestMapping(value = "/user")
    public class UserController {
    
        // 获取普通数据类型
        @RequestMapping(value = "/quick1")
        @ResponseBody
        public void save1(@RequestParam("username")String username, @RequestParam("age")int age) throws IOException {
            System.out.println(username);
            System.out.println(age);
        }
    
        // 获取POJO类型
        @ResponseBody
        @RequestMapping("/quick2")
        public void save2(User user) throws IOException {
            System.out.println(user);
        }
    
        // 获取数组类型
        @ResponseBody
        @RequestMapping("/quick3")
        public void save3(@RequestParam("strs")String[] strs) throws IOException {
            // 由于直接打印数组时只会打印出其地址,所以将其转为List集合输出到控制台
            System.out.println(Arrays.asList(strs));
        }
    
        // 获取集合类型
        @ResponseBody
        @RequestMapping("/quick4")
        public void save4(VO vo) throws IOException {
            System.out.println(vo);
        }
    }
    

    此时相等于获取POJO类型:所以请求参数名称要与该POJO类(即VO类)中的属性名一致,而在VO类中该属性userList为一个集合,所以不仅要与userList一致,更要进一步与该集合里面存储的对象User的属性名样一致

  • Step3:以页面为例(post方式提交)web项目核心目录(即webapp)下创建一个form.jsp页面,代码如下:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
        <head>
            <title>Title</title>
        </head>
        <body>
            <%--将表单提交到控制器映射地址下的/user/quick4,也就是UserController类下的save4业务方法中--%>
            <form action="/SpringMvcThree/user/quick4" method="post">
                <%--将第一个请求参数提交到userList集合中第一个元素的name属性中--%>
                <input type="text" name="userList[0].name"><br/>
                <%--将第一个请求参数提交到userList集合中第二个元素的age属性中--%>
                <input type="text" name="userList[0].age"><br/>
                <input type="text" name="userList[0].name"><br/>
                <input type="text" name="userList[0].age"><br/>
                <input type="submit" value="提交">
            </form>
        </body>
    </html>
    

    注意:因为请求参数名称要与VO类中的集合属性名一致,又因为集合中存储的是POJO类对象(即User),而User类中有两个属性nameage,所以请求参数名称要与集合名.POJO类属性名一致,所以表单中name属性值为userList[0].name,它的含义就是集合中第一个元素的name属性。

    运行后截图如下所示:

    <img alt="image-20241122145555021">

方式二:不使用POJO类进行集合封装

  • 注意
    • 当使用ajax提交表单时,可以指定contentType为json形式,然后在对应业务方法的参数位置使用@RequestBody注解就可以直接接收集合数据而不需要使用POJO进行封装

代码示例

  • Step1:在web项目核心目录(即webapp)下创建js目录,引入jquery源码文件jquery-3.7.1.js官网自行下载

  • Step2:web项目核心目录(即webapp)下创建一个ajax.jsp文件,并在该文件中引入jquery的源码文件,最终代码如下:

    <%--
      Created by IntelliJ IDEA.
      User: 10195
      Date: 2024/11/22
      Time: 16:04
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
        <head>
            <title>Title</title>
        </head>
        <body>
            <script src="js/jquery-3.7.1.js"></script>
            <script>
                // 创建核心对象
                var userList = new Array();
                userList.push({name:"zhangsna", age:15});
                userList.push({name:"lisi", age:16});
                $.ajax({
                   type:"POST",
                   url:"user/quick5",
                   data:JSON.stringify(userList),
                   contentType:"application/json;charset=utf-8"
                });
            </script>
        </body>
    </html>
    
  • Step3:在springMVC的核心配置文件中添加如下代码:

    • 原因:在SpringMVC中默认会拦截对所有资源的请求,包括静态资源;若不单独配置则会使静态资源请求被误认为是需要交给核心前端控制器处理的业务请求,此时由于前端控制器无法找到与之对应的业务方法,从而导致资源无法正确加载,所以需要在SpringMVC的核心配置文件中对这些资源进行开放访问。

      <!--配置静态资源的路径映射,开放某些资源的访问-->
      <mvc:resources mapping="/js/**" location="/js/"/>
      
    • springMVC的核心配置文件完整代码如下:

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:mvc="http://www.springframework.org/schema/mvc"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans.xsd
             http://www.springframework.org/schema/context
             http://www.springframework.org/schema/context/spring-context.xsd
             http://www.springframework.org/schema/mvc
             http://www.springframework.org/schema/mvc/spring-mvc.xsd">
      
          <!--配置Controller层的注解的组件扫描-->
          <context:component-scan base-package="at.guigu.controller"></context:component-scan>
          <!--等同于
          <context:component-scan base-package="at.guigu">
              type指定要扫描的内容为注解,expression指定要扫描的对应注解的全限定名
              只扫描at.guigu包下有@Controller注解的类
              <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
          </context:component-scan>
          -->
          <!--配置内部资源视图解析器-->
          <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
              <!--将InternalResourceViewResolver类中的前缀属性prefix的值设为/jsp/-->
              <property name="prefix" value="/user/"></property>
              <!--将InternalResourceViewResolver类中的前缀属性suffix的值设为.jsp-->
              <property name="suffix" value=".jsp"></property>
          </bean>
      
          <!--mvc的注解驱动-->
          <mvc:annotation-driven/>
          <!--等同于配置处理器适配器-->
          <!--<bean id="handlerAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
              <property name="messageConverters">
                  <list>
                      <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
                  </list>
              </property>
          </bean>-->
          <mvc:resources mapping="/js/**" location="/js/"/>
      </beans>
      
  • Step4:在controller包下的UserController类中添加save5方法,完整代码如下:

    package at.guigu.controller;
    
    import at.guigu.pojo.User;
    import at.guigu.pojo.VO;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.List;
    
    //将Usercontroller放到Spring容器中
    @Controller
    @RequestMapping(value = "/user")
    public class UserController {
    
        // 获取普通数据类型
        @RequestMapping(value = "/quick1")
        @ResponseBody
        public void save1(@RequestParam("username")String username, @RequestParam("age")int age) throws IOException {
            System.out.println(username);
            System.out.println(age);
        }
    
        // 获取POJO类型
        @ResponseBody
        @RequestMapping("/quick2")
        public void save2(User user) throws IOException {
            System.out.println(user);
        }
    
        // 获取数组类型
        @ResponseBody
        @RequestMapping("/quick3")
        public void save3(@RequestParam("strs")String[] strs) throws IOException {
            // 由于直接打印数组时只会打印出其地址,所以将其转为List集合输出到控制台
            System.out.println(Arrays.asList(strs));
        }
    
        // 获取集合类型方式一
        @ResponseBody
        @RequestMapping("/quick4")
        public void save4(VO vo) throws IOException {
            System.out.println(vo);
        }
    
        // 获取集合类型方式二
        @ResponseBody
        @RequestMapping("/quick5")
        public void save5(@RequestBody List<User> userList) throws IOException {
            System.out.println(userList);
        }
    }
    

    <img alt="image-20241122162512241">

开放静态资源的请求访问

  • 注意

    • 在SpringMVC中默认会拦截对所有资源的请求,包括静态资源;若不单独配置则会使静态资源请求被误认为是需要交给核心前端控制器处理的业务请求,此时由于前端控制器无法找到与之对应的业务方法,从而导致资源无法正确加载,所以需要在SpringMVC的核心配置文件中对这些资源进行开放访问。
  • 通过<mvc:resources>标签进行资源路径配置标签常用属性如下:

    <mvc:resources>标签属性 解释
    mapping 告诉 Spring MVC,当用户请求某些特定 URL 时,这些请求是访问静态资源,而不是交给控制器处理。/js/**代表js后可以是多级url地址
    location 定义资源在服务器上的实际存放位置
  • 由于每开放一种静态资源就要写一个该标签代码,所以可用如下代码代替

    <mvc:default-servlet-handler/>
    

    解释: 在SpringMVC中默认会拦截对所有资源的请求,包括静态资源;若不单独配置则会使静态资源请求被误认为是需要交给核心前端控制器处理的业务请求,此时由于前端控制器无法找到与之对应的业务方法,从而导致资源无法正确加载,此时就会交由Tomcat来找对应的静态资源,从而使得资源正确加载

    简要总结: SpringMVC框架无法找到对应资源时就会让原始容器Tomcat去找静态资源

  • 开放对图片、jquery文件等静态资源访问的代码示例如下

    <!--配置静态资源的路径映射,开放某些资源的访问-->
    <mvc:resources mapping="/js/**" location="/js/"/>
    <mvc:resources mapping="/img/**" location="/img/"/>
    

    等同于

    <mvc:default-servlet-handler/>
    

请求参数乱码问题

  • 当使用POST请求时,数据会出现乱码问题(可详见使用POJO类进行集合封装的代码示例),解决方法:

    • 在web项目核心目录(即webapp)下的WEB-INF中的web.xml中配置一个全局过滤器来进行编码的过滤,代码如下

      注意:<filter>以及<filter-mapping>标签需要写到<linstener>标签前,因为web.xml中有严格的标签顺序

      <!--全局过滤器-->
        <filter>
          <filter-name>CharacterEncodingFilter</filter-name>
          <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
          <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
          </init-param>
        </filter>
        <filter-mapping>
          <filter-name>CharacterEncodingFilter</filter-name>
          <url-pattern>/*</url-pattern>
        </filter-mapping>
      
    • 此时再次运行使用POJO类进行集合封装的代码示例后就不会出现乱码问题了,运行截图如下

      <img alt="image-20241122170210417">

@requestParam注解

@requestParam注解属性 解释
value 请求参数的名称
required 该注解指定的请求参数是否必须存在,默认为true,提交时若该参数不存在则会报错
defaultValue 当该注解没有指定请求参数时,则使用指定默认值
  • 定义:当请求参数的名称与Controller控制器中对应的业务方法的参数名称不一致时,将它们显式的绑定到一块

    <img alt="image-20241122170730432">

  • 代码示例如下:

    • 在controller包下的UserController类中添加save6方法,完整代码如下:

      package at.guigu.controller;
      import at.guigu.pojo.User;
      import at.guigu.pojo.VO;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestBody;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestParam;
      import org.springframework.web.bind.annotation.ResponseBody;
      
      import java.io.IOException;
      import java.util.Arrays;
      import java.util.List;
      
      //将Usercontroller放到Spring容器中
      @Controller
      @RequestMapping(value = "/user")
      public class UserController {
      
          // 获取普通数据类型
          @RequestMapping(value = "/quick1")
          @ResponseBody
          public void save1(@RequestParam("username")String username, @RequestParam("age")int age) throws IOException {
              System.out.println(username);
              System.out.println(age);
          }
      
          // 获取POJO类型
          @ResponseBody
          @RequestMapping("/quick2")
          public void save2(User user) throws IOException {
              System.out.println(user);
          }
      
          // 获取数组类型
          @ResponseBody
          @RequestMapping("/quick3")
          public void save3(@RequestParam("strs")String[] strs) throws IOException {
              // 由于直接打印数组时只会打印出其地址,所以将其转为List集合输出到控制台
              System.out.println(Arrays.asList(strs));
          }
      
          // 获取集合类型方式一
          @ResponseBody
          @RequestMapping("/quick4")
          public void save4(VO vo) throws IOException {
              System.out.println(vo);
          }
      
          // 获取集合类型方式二
          @ResponseBody
          @RequestMapping("/quick5")
          public void save5(@RequestBody List<User> userList) throws IOException {
              System.out.println(userList);
          }
      
          // 测试@RequestParam注解
          @RequestMapping(value = "/quick1")
          @ResponseBody
          public void save6(@RequestParam(value = "name", required = false, defaultValue = "zhangzhang")String username) throws IOException {
              System.out.println(username);
          }
      }
      
      • 请求参数名与业务方法的参数名不一致

        <img alt="image-20241122172006564">

      • 不写请求参数,则会将指定默认值赋值给业务方法对应的参数

        <img alt="image-20241122172241307">

获取Restful风格的请求参数

  • Restful定义

    • Restful时一种软件架构风格、设计风格,而不是标准

    • 它只是提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件

    • 基于该风格的软件会更简洁更有层次,更易实现缓存机制等

    • 可以利用Restful风格来省略请求参数名的书写,比如

      http://localhost:8080/SpringMvcThree/user/quick6?name=zhangsan
      

      可改写为

      http://localhost:8080/SpringMvcThree/user/quick6/zhangsan
      
  • 当使用Restful风格来获取请求参数时,需要在方法的@RequestMapping注解中用占位符指明映射地址后的为请求参数;同时用@PathVariable注解来修饰业务方法中的参数,且该注解的value值要与@RequestMapping注解中的占位符名称一致

    <img alt="image-20241122174110784">

  • Restful风格请求使用的是url+请求方式来表示一次请求目的,Http协议中有4种操作方式:

    • GET:用于获取资源
      • /user/1 GET:获取id=1的user
    • POST:用于新建资源
      • /user POST:新增user
    • PUT:用于更新资源
      • /user/1 PUT:更新id=1的user
    • DELETE:用于删除资源
      • /user/1 DELETE:删除id=1的user

代码示例

  • 在controller包下创建UserControllerTwo类,并在该类中添加save1方法,完整代码如下:

    package at.guigu.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Controller
    @RequestMapping("/user2")
    public class UserControllerTwo {
    
        // Restful风格的请求参数
        @ResponseBody
        @RequestMapping("/quickk1/{name}")
        public void save1(@PathVariable(value = "name") String userName) {
            System.out.println(userName);
        }
    }
    

    <img alt="image-20241122175202893">

自定义类型转换器

  • SpringMVC默认已经提供了一些常用的类型转换器,比如将客户端提交的字符串转换成int类型进行参数设置。但不是所有是数据类型都提供了转换器,比如日期类型的数据,此时就需要自定义转换器
  • 开发步骤
    • 自定义一个实现Converter接口的转换器类
    • 在SpringMVC的核心配置文件中声明转换器类
    • 在核心配置文件中用<annotation-driven>(即mvc的注解驱动)标签中引用转换器类
  • 注意
    • 自定义类型转换器时,参数不会自动映射匹配,所以可使用如下两种方法
      • 使用@RequestParam注解
      • 在pom.xml文件中添加maven插件
      • 以上两种方式代码示例详见获取普通数据类型

代码示例

本代码示例以日期类型为例:将日期封装为yyyy-MM-dd形式

注意:日期默认封装格式为yyyy/MM/dd形式,若请求参数中为yyyy-MM-dd形式则会报错,所以本示例是将其转换为常用的yyyy-MM-dd形式

  • Step1: 创建一个与三层架构包同级的converter包,然后定义一个实现Converter接口的类DataConverter,并定义该类的泛型为<String, Date>,然后重写其中的convert方法,在该方法中将日期转换成指定格式的日期对象并返回

    • 注意:
      • 该接口是org.springframework.core.convert.converter.Converter包下的
      • <String, Date>中第一个参数String为请求参数字符串;第二个参数Date为要转换到的类型
      • convert方法的参数为客户端的请求参数
    package at.guigu.converter;
    
    import org.springframework.core.convert.converter.Converter;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class DataConverter implements Converter<String, Date> {
        @Override
        public Date convert(String source) {
            // 将日期字符串转换成指定的日期对象并返回
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            Date date = null;
            try {
                date = format.parse(source);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return date;
        }
    }
    
  • Step2: 在SpringMVC的核心配置文件中声明转换器类,核心配置文件代码如下

    <!--声明转换器类-->
        <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
            <property name="converters">
                <list>
                    <bean class="at.guigu.converter.DataConverter"></bean>
                </list>
            </property>
        </bean>
    
  • Step3: 在SpringMVC的核心配置文件中用<annotation-driven>标签中的conversion-service属性引用转换器类的id,代码如下

    <mvc:annotation-driven conversion-service="conversionService"/>
    

    SpringMVC的核心配置文件代码如下

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/mvc
           http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    
        <!--配置Controller层的注解的组件扫描-->
        <context:component-scan base-package="at.guigu.controller"></context:component-scan>
        <!--等同于
        <context:component-scan base-package="at.guigu">
            type指定要扫描的内容为注解,expression指定要扫描的对应注解的全限定名
            只扫描at.guigu包下有@Controller注解的类
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        </context:component-scan>
        -->
        <!--配置内部资源视图解析器-->
        <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!--将InternalResourceViewResolver类中的前缀属性prefix的值设为/jsp/-->
            <property name="prefix" value="/user/"></property>
            <!--将InternalResourceViewResolver类中的前缀属性suffix的值设为.jsp-->
            <property name="suffix" value=".jsp"></property>
        </bean>
    
        <!--mvc的注解驱动-->
        <!--利用conversion-service来引用转换器类,属性值为转换器对应的id-->
        <mvc:annotation-driven conversion-service="conversionService"/>
        <!--等同于配置处理器适配器-->
        <!--<bean id="handlerAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
            <property name="messageConverters">
                <list>
                    <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
                </list>
            </property>
        </bean>-->
        <!--配置静态资源的路径映射,让 Spring MVC 可以处理静态文件-->
        <mvc:default-servlet-handler/>
        
        <!--声明转换器类-->
        <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
            <property name="converters">
                <list>
                    <bean class="at.guigu.converter.DataConverter"></bean>
                </list>
            </property>
        </bean>
    </beans>
    
  • Step4: 在controller包下创建UserControllerThree类并添加save1方法,完整代码如下:

    package at.guigu.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.io.IOException;
    import java.util.Date;
    
    @Controller
    @RequestMapping("/user3")
    public class UserControllerThree {
    
        @ResponseBody
        @RequestMapping("/quickk1")
        public void save1(@RequestParam("date") Date date) throws IOException {
            System.out.println(date);
        }
    }
    

    运行截图如下

    <img alt="image-20241122212829005">

获取Servlet的相关API

  • SpringMVC支持使用原始ServletAPI对象作为控制器方法的参数进行注入,常用对象有

    • HttpServletRequest
    • HttpServletResponse
    • HttpSession
  • 获取方式: 只需要将想要的Servlet的API作为控制器对应方法的参数即可

    • 方法一般是谁调用谁传参,因为业务方法是SpringMVC框架调用的,所以SpringMVC会自动根据方法的参数进行注入
  • 测试示例

    • 在controller包下创建UserControllerFour类并添加save1方法,完整代码如下:

      package at.guigu.controller;
      
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.ResponseBody;
      
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import javax.servlet.http.HttpSession;
      
      @Controller
      @RequestMapping("/user4")
      public class UserControllerFour {
          @ResponseBody
          @RequestMapping("/quick1")
          public void save1(HttpServletRequest req, HttpServletResponse res, HttpSession hs) throws Exception{
              System.out.println(req);
              System.out.println(res);
              System.out.println(hs);
          }
      }
      

      <img alt="image-20241122215345240">

获取请求头信息

  • 利用@RequestHeader注解来获取请求头信息,相当于web阶段所学的request.getHeader(name)方法,可详见会话跟踪技术部分内容

    @RequestHeader注解属性 解释
    value 请求头名称
    required 是否必须携带该请求头,默认为true,即必须携带该请求头才能访问这个资源
  • 测试示例

    • 在controller包下创建UserControllerFive类并添加save1方法,代码如下:

      package at.guigu.controller;
      
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.ResponseBody;
      
      @Controller
      @RequestMapping("/user5")
      public class UserControllerFive {
          @ResponseBody
          @RequestMapping("/quick1")
          public void save1() throws Exception{
          }
      }
      

      运行后通过开发者工具可看到请求头信息,如图所示

      <img alt="image-20241122220250237">

    • 假设现在获取请求头user-agent的信息,则代码如下:

      package at.guigu.controller;
      
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestHeader;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.ResponseBody;
      
      @Controller
      @RequestMapping("/user5")
      public class UserControllerFive {
          @ResponseBody
          @RequestMapping("/quick1")
          public void save1(@RequestHeader(value = "User-Agent", required = false) String user_agent) throws Exception{
              System.out.println(user_agent);
          }
      }
      

      <img alt="image-20241122220715639">

获取指定Cookie请求头信息

  • @RequestHeader只能根据如图所示1中的请求头来获取2中的信息,而有些请求头后的信息有键值对,比如Cookie中又有很多键值对Cookie,此时若想获取Cookie里面的小Cookie的话@RequestHeader注解就会失效。

    <img alt="image-20241122221937185">

  • Cookie不只有一个,所以属于特殊请求头,如图所示

    <img alt="image-20241122221229221">

  • @CookieValue获取指定Cookie的值

    @CookieValue注解属性 解释
    value Cookie名称
    required 是否必须携带该Cookie,默认为true,即必须携带该Cookie才能访问这个资源
  • 代码示例(此处以JSESSIONID这个Cookie为例)

    • UserControllerFive类中添加save2方法,代码如下:

      package at.guigu.controller;
      
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.CookieValue;
      import org.springframework.web.bind.annotation.RequestHeader;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.ResponseBody;
      
      @Controller
      @RequestMapping("/user5")
      public class UserControllerFive {
          // 获取普通请求头
          @ResponseBody
          @RequestMapping("/quick1")
          public void save1(@RequestHeader(value = "User-Agent", required = false) String user_agent) throws Exception{
              System.out.println(user_agent);
          }
          // 获取特殊请求头:获取指定Cookie
          @ResponseBody
          @RequestMapping("/quick2")
          public void save2(@CookieValue(value = "JSESSIONID", required = false) String jessionid) throws Exception{
              System.out.println(jessionid);
          }
      }
      

      <img alt="image-20241122221638052">

  • 注意:除以上注解之外,也可使用通用方式(即使用HttpServletRequest接口中的方法)来获取请求头信息,可详见会话跟踪技术部分内容

文件上传(获取文件)

  • 文件上传客户端三要素

    • 表单项type="file"
    • 表单提交方式为post
    • 表单的enctype属性是多部分表单形式,即enctype="mulipart/form-data"

    <img alt="image-20241123125316316">

  • 注意

    • 当form表单修改为多部分表单时,request.getParameter(String name)会失效,因为该方法只能获取单个参数值

    • 默认情况下,enctype="application/x-www-form-urlencoded",此时form表单的正文内容是key=value&key=value&key=value

    • enctype="mulipart/form-data"时,请求正文内容就会变成多部分形式,此时能够获取表单的所有数据,如图所示

      <img alt="image-20241123133207163">

  • 文件上传步骤

    • 在pom.xml文件中导入坐标:fileupload和io两个坐标

      <!--fileupload坐标-->
      <dependency>
          <groupId>commons-fileupload</groupId>
          <artifactId>commons-fileupload</artifactId>
          <version>1.5</version>
      </dependency>
      
      <!--io坐标-->
      <dependency>
          <groupId>commons-io</groupId>
          <artifactId>commons-io</artifactId>
          <version>2.17.0</version>
      </dependency>
      
    • 在SpringMVC的核心配置文件中配置文件上传解析器

    • 编写文件上传代码

  • 单文件上传和多文件上传的公共步骤(后续代码演示不在演示公共步骤)

    • 在pom.xml文件中导入fileupload和io两个坐标,文件完整代码如下:

      <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/maven-v4_0_0.xsd">
          <modelVersion>4.0.0</modelVersion>
          <parent>
              <groupId>org.example</groupId>
              <artifactId>SpringMvcDemo</artifactId>
              <version>1.0-SNAPSHOT</version>
          </parent>
          <artifactId>SpringMvcThree</artifactId>
          <packaging>war</packaging>
          <name>SpringMvcThree Maven Webapp</name>
          <url>http://maven.apache.org</url>
          <dependencies>
              <dependency>
                  <groupId>junit</groupId>
                  <artifactId>junit</artifactId>
                  <version>3.8.1</version>
                  <scope>test</scope>
              </dependency>
      
              <!--===================Spring相关坐标=======================-->
              <!--spring坐标-->
              <dependency>
                  <groupId>org.springframework</groupId>
                  <artifactId>spring-context</artifactId>
                  <version>6.1.6</version>
              </dependency>
      
              <!--spring-web -->
              <dependency>
                  <groupId>org.springframework</groupId>
                  <artifactId>spring-web</artifactId>
                  <version>5.2.25.RELEASE</version>
              </dependency>
      
              <!--spring-test坐标-->
              <dependency>
                  <groupId>org.springframework</groupId>
                  <artifactId>spring-test</artifactId>
                  <version>6.1.6</version>
                  <scope>test</scope>
              </dependency>
      
              <!--Annotation坐标-->
              <dependency>
                  <groupId>javax.annotation</groupId>
                  <artifactId>javax.annotation-api</artifactId>
                  <version>1.3.2</version>
              </dependency>
              <dependency>
                  <groupId>junit</groupId>
                  <artifactId>junit</artifactId>
                  <version>4.13.2</version>
                  <scope>test</scope>
              </dependency>
      
              <!-- servlet-->
              <dependency>
                  <groupId>javax.servlet</groupId>
                  <artifactId>javax.servlet-api</artifactId>
                  <version>4.0.1</version>
                  <scope>provided</scope>
              </dependency>
      
              <!--jsp-->
              <dependency>
                  <groupId>javax.servlet.jsp</groupId>
                  <artifactId>javax.servlet.jsp-api</artifactId>
                  <version>2.3.3</version>
                  <scope>provided</scope>
              </dependency>
              <!--===================SpringMVC相关坐标=======================-->
              <!--spring-webmvc-->
              <dependency>
                  <groupId>org.springframework</groupId>
                  <artifactId>spring-webmvc</artifactId>
                  <version>5.2.25.RELEASE</version>
              </dependency>
              <!--jackson-core-->
              <dependency>
                  <groupId>com.fasterxml.jackson.core</groupId>
                  <artifactId>jackson-core</artifactId>
                  <version>2.17.1</version>
              </dependency>
              <!--jackson-databind-->
              <dependency>
                  <groupId>com.fasterxml.jackson.core</groupId>
                  <artifactId>jackson-databind</artifactId>
                  <version>2.17.1</version>
              </dependency>
              <!--jackson-annotations-->
              <dependency>
                  <groupId>com.fasterxml.jackson.core</groupId>
                  <artifactId>jackson-annotations</artifactId>
                  <version>2.17.1</version>
              </dependency>
              <!--=====================数据库相关坐标=========================-->
              <!--mysql坐标-->
              <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
                  <version>8.0.33</version>
              </dependency>
      
              <!--druid坐标-->
              <dependency>
                  <groupId>com.alibaba</groupId>
                  <artifactId>druid</artifactId>
                  <version>1.2.18</version>
              </dependency>
      
              <!--c3p0坐标-->
              <dependency>
                  <groupId>com.mchange</groupId>
                  <artifactId>c3p0</artifactId>
                  <version>0.9.5.5</version>
              </dependency>
              <!--=====================MyBatis相关坐标=========================-->
              <!--spring-jdbc-->
              <dependency>
                  <groupId>org.springframework</groupId>
                  <artifactId>spring-jdbc</artifactId>
                  <version>6.1.10</version>
              </dependency>
      
              <!--mybatis-spring-->
              <dependency>
                  <groupId>org.mybatis</groupId>
                  <artifactId>mybatis-spring</artifactId>
                  <version>3.0.3</version>
              </dependency>
      
              <!--MyBatis坐标-->
              <dependency>
                  <groupId>org.mybatis</groupId>
                  <artifactId>mybatis</artifactId>
                  <version>3.5.16</version>
              </dependency>
      
              <!--=====================文件上传相关坐标=========================-->
              <!--fileupload坐标-->
              <dependency>
                  <groupId>commons-fileupload</groupId>
                  <artifactId>commons-fileupload</artifactId>
                  <version>1.5</version>
              </dependency>
      
              <!--io坐标-->
              <dependency>
                  <groupId>commons-io</groupId>
                  <artifactId>commons-io</artifactId>
                  <version>2.17.0</version>
              </dependency>
      
          </dependencies>
          <build>
              <finalName>SpringMvcThree</finalName>
              <plugins>
                  <!-- Tomcat插件 -->
                  <plugin>
                      <groupId>org.apache.tomcat.maven</groupId>
                      <artifactId>tomcat7-maven-plugin</artifactId>
                      <version>2.2</version>
                  </plugin>
                  <!--<plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-compiler-plugin</artifactId>
                      &lt;!&ndash; maven插件版本 &ndash;&gt;
                      <version>3.13.0</version>
                      <configuration>
                          &lt;!&ndash; Java版本 &ndash;&gt;
                          <source>21</source>
                          <compilerArgs>
                              <arg>-parameters</arg>
                          </compilerArgs>
                      </configuration>
                  </plugin>-->
              </plugins>
          </build>
      </project>
      
    • 在SpringMVC的核心配置文件中配置文件上传解析器,代码如下

      <!--配置文件上传解析器-->
      <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
          <!--所上传文件的编码类型-->
          <property name="defaultEncoding" value="UTF-8"/>
          <!--所上传的单个文件的大小-->
          <property name="maxUploadSizePerFile" value="500000"/>
          <!--所上传的总文件的大小-->
          <property name="maxUploadSize" value="5000000"/>
      </bean>
      

      SpringMVC核心配置文件代码如下

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:mvc="http://www.springframework.org/schema/mvc"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans.xsd
             http://www.springframework.org/schema/context
             http://www.springframework.org/schema/context/spring-context.xsd
             http://www.springframework.org/schema/mvc
             http://www.springframework.org/schema/mvc/spring-mvc.xsd">
      
          <!--配置Controller层的注解的组件扫描-->
          <context:component-scan base-package="at.guigu.controller"></context:component-scan>
          <!--等同于
          <context:component-scan base-package="at.guigu">
              type指定要扫描的内容为注解,expression指定要扫描的对应注解的全限定名
              只扫描at.guigu包下有@Controller注解的类
              <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
          </context:component-scan>
          -->
          <!--配置内部资源视图解析器-->
          <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
              <!--将InternalResourceViewResolver类中的前缀属性prefix的值设为/jsp/-->
              <property name="prefix" value="/user/"></property>
              <!--将InternalResourceViewResolver类中的前缀属性suffix的值设为.jsp-->
              <property name="suffix" value=".jsp"></property>
          </bean>
      
          <!--mvc的注解驱动-->
          <mvc:annotation-driven conversion-service="conversionService"/>
          <!--等同于配置处理器适配器-->
          <!--<bean id="handlerAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
              <property name="messageConverters">
                  <list>
                      <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
                  </list>
              </property>
          </bean>-->
          <!--配置静态资源的路径映射,让 Spring MVC 可以处理静态文件-->
          <mvc:default-servlet-handler/>
          <!--声明转换器类-->
          <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
              <property name="converters">
                  <list>
                      <bean class="at.guigu.converter.DataConverter"></bean>
                  </list>
              </property>
          </bean>
          <!--配置文件上传解析器-->
          <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
              <!--所上传文件的编码类型-->
              <property name="defaultEncoding" value="UTF-8"/>
              <!--所上传的单个文件的大小-->
              <property name="maxUploadSizePerFile" value="500000"/>
              <!--所上传的总文件的大小-->
              <property name="maxUploadSize" value="5000000"/>
          </bean>
      </beans>
      

单文件上传示例

  • 在web项目核心目录(即webapp)下创建文件upload.jsp,文件代码如下:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
        <head>
            <title>Title</title>
        </head>
        <body>
            <form action="/SpringMvcThree/user6/quick1" method="post" enctype="multipart/form-data">
                名称<input type="text" name = "username"><br/>
                文件<input type="file" name = "uploadFile"><br/>
                <input type="submit" value="提交"><br/>
            </form>
        </body>
    </html>
    
  • 在controller包下创建UserControllerSix类并添加save1方法,完整代码如下:

    package at.guigu.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.File;
    import java.io.IOException;
    
    @Controller
    @RequestMapping("/user6")
    public class UserControllerSix {
        @ResponseBody
        @RequestMapping("/quick1")
        public void save1(@RequestParam("username") String username, @RequestParam("uploadFile") MultipartFile uploadFile) throws IOException {
            System.out.println(username);
            System.out.println(uploadFile);
            // 获取上传文件名
            String originalFilename = uploadFile.getOriginalFilename();
            // 保存文件
            uploadFile.transferTo(new File("F:\\node\\idea\\test\\" + originalFilename));
        }
    }
    

    <img alt="image-20241123142718400">

    • 注意

      • 业务方法的参数名要与请求参数名一致,由于表单上传的文件会被SpringMVC封装成一个MultipartFile对象,且对象名为表单中所定义的文件的name属性值,所以对应业务方法中第二个参数的名为uploadFile

      • 单文件上传时,参数不会自动映射匹配,解决方法有两种:

        • 在pom.xml文件中添加maven插件

        • 使用@RequestParam注解

        • 以上两种方式详见获取普通数据类型的代码示例部分

多文件上传示例

  • 方式一:文件name属性的属性名不一样

    • 在web项目核心目录(即webapp)下创建文件upload2.jsp,文件代码如下:

      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
          <head>
              <title>Title</title>
          </head>
          <body>
              <form action="/SpringMvcThree/user6/quick2" method="post" enctype="multipart/form-data">
                  名称<input type="text" name = "username"><br/>
                  文件1<input type="file" name = "uploadFile1"><br/>
                  文件2<input type="file" name = "uploadFile2"><br/>
                  <input type="submit" value="提交"><br/>
              </form>
          </body>
      </html>
      
    • UserControllerSix类中添加save2方法,完整代码如下:

      package at.guigu.controller;
      
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestParam;
      import org.springframework.web.bind.annotation.ResponseBody;
      import org.springframework.web.multipart.MultipartFile;
      
      import java.io.File;
      import java.io.IOException;
      
      @Controller
      @RequestMapping("/user6")
      public class UserControllerSix {
          
          // 单文件上传
          @ResponseBody
          @RequestMapping("/quick1")
          public void save1(@RequestParam("username") String username, @RequestParam("uploadFile") MultipartFile uploadFile) throws IOException {
              System.out.println(username);
              System.out.println(uploadFile);
              // 获取上传文件名
              String originalFilename = uploadFile.getOriginalFilename();
              // 保存文件
              uploadFile.transferTo(new File("F:\\node\\idea\\test\\" + originalFilename));
          }
          
          //多文件上传 方式一
          @ResponseBody
          @RequestMapping("/quick2")
          public void save2(@RequestParam("username") String username, @RequestParam("uploadFile1") MultipartFile uploadFile1, @RequestParam("uploadFile2") MultipartFile uploadFile2) throws IOException {
              System.out.println(username);
              System.out.println(uploadFile1);
              System.out.println(uploadFile2);
              // 获取上传文件1的文件名
              String originalFilename1 = uploadFile1.getOriginalFilename();
              // 保存文件1
              uploadFile1.transferTo(new File("F:\\node\\idea\\test\\" + originalFilename1));
              // 获取上传文件2的文件名
              String originalFilename2 = uploadFile2.getOriginalFilename();
              // 保存文件2
              uploadFile2.transferTo(new File("F:\\node\\idea\\test\\" + originalFilename2));
          }
      }
      

      <img alt="image-20241123144117411">

  • 方式二:文件name属性的属性名一样,此时用MultipartFile对象数组

    • 在web项目核心目录(即webapp)下创建文件upload3.jsp,文件代码如下:

      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
          <head>
              <title>Title</title>
          </head>
          <body>
              <form action="/SpringMvcThree/user6/quick3" method="post" enctype="multipart/form-data">
                  名称<input type="text" name = "username"><br/>
                  文件1<input type="file" name = "uploadFiles"><br/>
                  文件2<input type="file" name = "uploadFiles"><br/>
                  <input type="submit" value="提交"><br/>
              </form>
          </body>
      </html>
      
    • UserControllerSix类中添加save2方法,完整代码如下:

      package at.guigu.controller;
      
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestParam;
      import org.springframework.web.bind.annotation.ResponseBody;
      import org.springframework.web.multipart.MultipartFile;
      
      import java.io.File;
      import java.io.IOException;
      
      @Controller
      @RequestMapping("/user6")
      public class UserControllerSix {
          // 单文件上传
          @ResponseBody
          @RequestMapping("/quick1")
          public void save1(@RequestParam("username") String username, @RequestParam("uploadFile") MultipartFile uploadFile) throws IOException {
              System.out.println(username);
              System.out.println(uploadFile);
              // 获取上传文件名
              String originalFilename = uploadFile.getOriginalFilename();
              // 保存文件
              uploadFile.transferTo(new File("F:\\node\\idea\\test\\" + originalFilename));
          }
          //多文件上传 方式一
          @ResponseBody
          @RequestMapping("/quick2")
          public void save2(@RequestParam("username") String username, @RequestParam("uploadFile1") MultipartFile uploadFile1, @RequestParam("uploadFile2") MultipartFile uploadFile2) throws IOException {
              System.out.println(username);
              System.out.println(uploadFile1);
              System.out.println(uploadFile2);
              // 获取上传文件1的文件名
              String originalFilename1 = uploadFile1.getOriginalFilename();
              // 保存文件1
              uploadFile1.transferTo(new File("F:\\node\\idea\\test\\" + originalFilename1));
              // 获取上传文件2的文件名
              String originalFilename2 = uploadFile2.getOriginalFilename();
              // 保存文件2
              uploadFile2.transferTo(new File("F:\\node\\idea\\test\\" + originalFilename2));
          }
          // 多文件上传 方式二
          @ResponseBody
          @RequestMapping("/quick3")
          public void save3(@RequestParam("username") String username, @RequestParam("uploadFiles") MultipartFile[] uploadFiles) throws IOException {
              System.out.println(username);
              for (MultipartFile file : uploadFiles) {
                  System.out.println(file);
                  // 获取上传文件名
                  String originalFilename = file.getOriginalFilename();
                  // 保存文件
                  file.transferTo(new File("F:\\node\\idea\\test\\" + originalFilename));
              }
          }
      }
      

      <img alt="image-20241123144951578">

马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/cgrs572/spring-mvc-demo.git
git@gitee.com:cgrs572/spring-mvc-demo.git
cgrs572
spring-mvc-demo
SpringMvcDemo
master

搜索帮助