SpringMVC 实战指南:文件上传

第一章:常用的注解:

@RequestParam 注解:
  1. 作用:把请求中的指定名称的参数传递给控制器中的形参赋值

  2. 属性:

    1. value:请求参数中的名称
    2. required:请求参数中是否必须提供此参数,默认值是 true(必须提供)
  3. 代码:

    java 复制代码
    @Controller
    @RequestMapping("/dept")
    public class DeptController {
        /**
         * @RequestParam 注解:
         * required = false 默认值是 true,必须要传请求参数,不传就会报错
         * defaultValue = "abc" 如果没有传请求参数,默认使用该值
         * 当有默认值 defaultValue 属性时,required 属性设置为 true 不传值也是可以的
         */
        @RequestMapping("/save1")
        public String save1(@RequestParam(value = "username",required = false,defaultValue = "abc") String name){
            System.out.println("姓名:" + name);
            return "suc";
        }
    }
@RequestBody 注解:
  1. 作用:用于获取请求体的内容(注意:get方法不可以)

  2. 属性:

    1. required:是否必须有请求体,默认值是true

    2. 代码:

      java 复制代码
      @RequestMapping("/save2")
      public String save2(@RequestBody String body){
          System.out.println("请求内容:" + body);
          return "suc";
      }
@PathVaribale 注解:
  1. 作用:拥有绑定 url 中的占位符。例如: url 中有 /delete/{id}。{id} 就是占位符

  2. 属性:

    1. value:指定 url 中的占位符名字
  3. Resutful 风格的 URL:

    1. 请求路径一样,可以根据不同的请求方式去执行后台的不同方法
    2. restful 风格的 URL 优点
      1. 结构清晰
      2. 符合标准
      3. 易于理解
      4. 扩展方便
  4. 代码:

    java 复制代码
    @RequestMapping("/findById/{id}")
    public String findById(@PathVariable(value = "id") Integer id){
        System.out.println("根据id查询:" + id);
        return "suc";
    }
  5. 修改前端控制器的配置文件:

    XML 复制代码
    <!--配置前端控制器-->
    <servlet>
      <servlet-name>dispatcherServlet</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <!--加载springmvc.xml配置文件,配置的是Spring配置-->
      <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
      </init-param>
      <!--配置启动加载-->
      <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
      <servlet-name>dispatcherServlet</servlet-name>
      <url-pattern>/</url-pattern>
    </servlet-mapping>
@RequestHeader 注解:
  1. 作用:获取指定请求头的值

  2. 属性:

    1. value:请求头的名称
  3. 代码:

    java 复制代码
    /**
     * RequestHeader 获取请求头的值
     * @param header
     * @return
     */
    @RequestMapping("/save3")
    public String save3(@RequestHeader(value = "Accept") String header){
        System.out.println("Accept请求头的值:" + header);
        return "suc";
    }
@CookieValue 注解:
  1. 作用:用于获取指定 cookit 的名称的值

  2. 属性:

    1. value:cookie 名称
  3. 代码:

    java 复制代码
    /**
     * CookieValue 获取cookie的值
     * @param cookie
     * @return
     */
    @RequestMapping("/save4")
    public String save4(@CookieValue(value = "JSESSIONID") String cookie){
        System.out.println("值:" + cookie);
        return "suc";
    }

第二章:响应数据和结果视图

返回值分类
  1. 搭建环境,导入依赖:

    XML 复制代码
    <!-- 版本锁定 -->
    <properties>
      <spring.version>5.0.2.RELEASE</spring.version>
    </properties>
    
    <dependencies>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
      </dependency>
      
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
      </dependency>
      
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
      </dependency>
      
      <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
      </dependency>
      
      <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.0</version>
        <scope>provided</scope>
      </dependency>
    </dependencies>
  2. 配置前端控制器和过滤器:

    XML 复制代码
    <web-app>
      <!--配置解决中文乱码问题的过滤器-->
      <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>
      <!--配置前端控制器-->
      <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--加载springmvc.xml配置文件,配置的是Spring配置-->
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <!--配置启动加载-->
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>
    </web-app>
  3. 编写 springmvc.xml 配置文件:

    XML 复制代码
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:context="http://www.springframework.org/schema/context"
           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/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
    
        <!-- 配置spring 创建容器时要扫描的包 -->
        <context:component-scan base-package="com.qcby.mybatis"></context:component-scan>
    
        <!-- 配置视图解析器 -->
        <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/pages/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
    
        <!-- 让映射器、适配器和处理器生效(默认不配置也是可以的)-->
        <!-- <mvc:annotation-driven conversion-service="conversionService"/> -->
        <mvc:annotation-driven />
    </beans>
返回值类型为 String 类型:
  1. Controller 方法返回字符串可以指定逻辑视图的名称,根据视图解析器为物理视图的地址

    java 复制代码
    @Controller
    public class HelloController {
    
        @RequestMapping("/hello")
        public String sayHello(){
            System.out.println("入门方法已执行");
            return "suc";
        }
    
    }
返回类型为 void:
  1. 如果控制器的方法返回值编写成 void,执行程序报 404 的异常,原因是默认查找的 JSP 页面没有被找到

  2. 默认会跳转到 @RequestMapping(value = "/initUpdate"),initUpdate 页面

  3. 可以使用请求转发或者重定向跳转到指定的页面

    java 复制代码
    @Controller
    @RequestMapping("/hello")
    public class HelloController {
        @RequestMapping("/save1")
        public void save2(HttpServletRequest request, HttpServletResponse response) throws IOException {
            System.out.println("方法已被执行");
    
            //做出相应动作
            response.getWriter().println("hello");
        }
    
    }
返回值是 ModelAndView 对象:
  1. ModelAndView 对象是 Spring 提供的一个对象,可以用来调整具体的 JSP 视图

  2. 代码:

    java 复制代码
    @Controller
    @RequestMapping("/hello")
    public class HelloController {
        @RequestMapping("/save2")
        public ModelAndView save2(){
            System.out.println("方法被执行");
            //创建 mv 对象
            ModelAndView mv = new ModelAndView();
            //把一些数据存储到 mv 对象中
            mv.addObject("msg","用户名或者密码错误0");
            //设置逻辑视图的名称
            mv.setViewName("suc");
            return mv;
        }
    }
SpringMVC 框架提供的转发和重定向:
  1. forward 请求转发:

    1. controller 方法返回 String 类型,想进行请求转发也可以编写成:

      java 复制代码
      @Controller
      @RequestMapping("/hello")
      public class HelloController {
          /**
           * 返回 String
           * 请求转发
           * @return
           */
          @RequestMapping("/save3")
          public String save3(){
              System.out.println("方法被执行");
              return "forward:/WEB-INF/pages/suc.jsp";
          }
      }
  2. redirect 重定向:

    1. controller 方法返回 String 类型,想进行重定向也可以编写成:

      java 复制代码
      @Controller
      @RequestMapping("/hello")
      public class HelloController {
          
          @RequestMapping("/hello")
          public String sayHello(){
              System.out.println("入门方法已执行");
              return "suc";
          }
          
          /**
           * 返回 String
           * 重定向
           * @return
           */
          @RequestMapping("/save4")
          public String save4(){
              System.out.println("方法被执行");
              return "redirect:hello";
          }
      
      }
ResponseBody 响应 json 数据(重要):
  1. json 字符串和 JavaBean 对象相互转换的过程中,需要使用 jackson 的 jar 包

    XML 复制代码
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.9.0</version>
    </dependency>
  2. DispatcherServlet 会拦截到所有的资源,导致一个问题就是静态资源(img、css、js)也会被拦截到,从而不能被使用。

    1. 解决:问题就是需要配置静态资源不进行拦截,在 springmvc.xml 配置文件添加如下配置
  3. 标签配置不过滤:

    1. location 元素表示 webapp 目录下的包下所有文件

    2. mappin 元素表示以 /static 开头的所有请求路径,如 /static/a 或 /static/b

      XML 复制代码
      <!-- 设置静态资源不过滤 -->
      <mvc:resources mapping="/css/**" location="/css/" /><!-- 样式 -->
      <mvc:resources mapping="/images/**" location="/images/"/><!-- 图片-->
      <mvc:resources mapping="/js/**" location="/js/"/><!-- javascript -->
  4. js 代码编写:

    1. jquery 下载

      javascript 复制代码
      <%--
        Created by IntelliJ IDEA.
        User: L-J-X
        Date: 2025/1/14
        Time: 16:38
        To change this template use File | Settings | File Templates.
      --%>
      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
          <title>Controller 方法的返回值</title>
          <%-- 引入 jq --%>
          <script src="/js/jquery-2.1.4.min.js" type="text/javascript"/>
          <script>        //页面加载
              $(function(){
                  //单击事件
                  $("#bin").click(function (){
                      //发送 ajax 请求
                      $.ajax({
                          type:"post",
                          url:"/user/save1",
                          contentType:"application/json;charset=UTF-8",
                          data:'{"username:"zhangsan","age":"20"}',
                          datatype:"json",
                          success:function (data){
                              alert(data.username + " " + data.age);
                          }
                      });
                  });
              });
          </script>
      </head>
      <body>
          <h3>返回值是String</h3>
          <a href="/user/save1">返回String</a>
      
          <h3>返回值是void</h3>
          <a href="/user/save2">返回void</a>
      
          <h3>返回值是ModelAndView</h3>
          <a href="/user/save3">返回ModelAndView</a>
      
          <h3>返回值是String</h3>
          <a href="/user/save4">返回String</a>
      
          <h3>异步的数据交互</h3>
          <input type="button" value="ajax交互" id="btn">
      
      </body>
      </html>
  5. 后台代码编写:

    java 复制代码
    import com.qcby.mybatis.pojo.User;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.*;
    import sun.net.util.IPAddressUtil;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    @Controller
    @RequestMapping(("/user"))
    public class UserController {
        @RequestMapping("/save6")
        public User save6(@RequestBody User user){
            System.out.println(user);
    
            //模拟调用业务层代码
            user.setUsername("hello");
            user.setAge(100);
            //把 user 对象转换成 json 字符串再响应。使用 @ResposeBody 注解 response.getWriter().print()
            return user;
        }
    }
  6. 实体类代码:

    java 复制代码
    package com.qcby.mybatis.pojo;
    
    
    import org.springframework.format.annotation.DateTimeFormat;
    
    import java.io.Serializable;
    import java.util.Date;
    import java.util.List;
    
    public class User implements Serializable {
        private String username;
        private Integer age;
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "username='" + username + '\'' +
                    ", age=" + age +
                    '}';
        }
    }

第三章:文件上传

  1. 导入依赖:

    XML 复制代码
    <dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
    </dependency>
    
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.4</version>
    </dependency>
  2. 编写文件上传的 JSP 页面:

    html 复制代码
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>文件上传</title>
    </head>
    <body>
        <h3>文件上传</h3>
        <form action="/fileupload" method="post" enctype="multipart/form-data">
            选择文件:<input type="file" name="upload"/><br/>
            <input type="submit" value="上传"/>
        </form>
    </body>
    </html>
SpringMVC 传统方式文件上传:
  1. 配置文件解析器对象:

    XML 复制代码
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:context="http://www.springframework.org/schema/context"
           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/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
            
        <!-- 启动 Tomcat 服务器的时候,就会被加载 -->
        <!-- 配置注解扫描 -->
        <context:component-scan base-package="com.qcby.mybatis"/>
    
        <!-- 配置视图解析器,进行页面的跳转 -->
        <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!-- 需要跳转的页面 -->
            <property name="prefix" value="/WEB-INF/pages/"/>
            <!-- 跳转页面的后缀名 -->
            <property name="suffix" value=".jsp"/>
        </bean>
    
        <!-- 配置文件上传的解析组件。id 的名称是不固定的,不能乱写 -->
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <!-- 设置文件上传的总大小 8M = 8 * 1024 * 1024 -->
            <property name="maxUploadSize" value="8388608"/>
        </bean>
    
        <!-- 让映射器、适配器和处理器生效(默认不配置也是可以的)-->
        <mvc:annotation-driven/>
    </beans>
  2. SpringMVC 框架提供了 MultiparFile 对象,该对象表示上传的文件,要求变量名称必须和表单 file 标签的 name 属性名称相同:

    java 复制代码
    @Controller
    @RequestMapping("/upload")
    public class IploadController {
        /**
         * 文件上传
         * MultipartFile upload 文件上传解析器对象解析 request 后,文件上传对象
         */
        @RequestMapping("/fileupload")
        public String upload(MultipartFile upload, HttpServletRequest request) throws IOException {
            //文件存储位置
            String realPath = request.getSession().getServletContext().getRealPath("/uploads");
            //创建该文件夹
            File file = new File(realPath);
    
            //判断该文件夹是否存在
            if(!file.exists()){
                //创建文件夹
                file.mkdirs();
            }
    
            //获取到上传文件的名称
            String filename = upload.getOriginalFilename();
    
            //把文件的名称修改成唯一的值 sdfs-csdf-fwer-sdfw
            String uuid = UUID.randomUUID().toString().replace("-","").toUpperCase();
    
            //唯一的值
            filename = uuid + "_" + filename;
            System.out.println("文件名称:" + filename);
    
            //上传文件
            upload.transferTo(new File(file,filename));
            return "suc";
        }
    }
相关推荐
许彰午4 分钟前
52-useWebSocket自动重连
java·低代码·架构
青山木7 分钟前
RocketMQ 入门到原理(一):整体架构与消息的生命周期
java·分布式·后端·中间件·架构·rocketmq
黑马程序员毕设13 分钟前
基于微信小程序的二手交易平台设计与实现报告
前端·人工智能·spring boot·后端·考研
xcl092513 分钟前
上海24小时自助健身房系统软件开发实战与架构解析
java·spring boot
苏渡苇17 分钟前
Spring Insight 里如何把 Span 收成一条链路
spring boot·spring·spring cloud·系统监控·apm
张宜强31 分钟前
023 SpringBoot实现萌宠集市
java·课程设计
花哥码天下33 分钟前
docker流水线
java
十二同学啊1 小时前
Drools规则引擎:让复杂业务规则从代码中解耦
java·后端·开源
周先生FullStack1 小时前
Mac + 容器本地 MySQL/Redis 环境搭建与网络原理实战
java·spring boot·微服务·容器·架构·个人开发
打工仔折腾 AI1 小时前
Pascal Editor 本地部署实战:Bun 启动 WebGPU 3D 编辑器并解决公网访问报错
人工智能·后端·python·性能优化