SpringMVC-6—SpringMVC实现文件上传

目录

一、文件上传的回顾

1、文件上传的必要前提

2、文件上传的原理分析

3、借助第三方组件实现文件上传

二、springmv c 传统方式的文件上传

1、说明  

2、实现步骤

(1)第一步:引入Commons-fileupload 文件上传依赖

(2)第二步:编写 jsp 页面

(3)第三步:编写控制器

(4)第四步:在springmvc.xml中配置文件解析器

3、问题:tomcat不能访问本地服务器上的图片

(1)创建本地目录,配置静态资源不过滤

(2)配置IDEA,勾选相关选项

(3)配置tomcat的server.xml文件

三、springmvc 跨服务器方式的文件上传

1、分服务器的目的

2、准备图片存放 tomcat 服务器

(1)修改默认端口——避免和idea使用tomcat端口重叠

(2)创建文件上传目录

(3)web.xml文件中加入允许读写操作

3、拷贝依赖

4、编写控制器实现上传图片

5、编写JSP + 配置解析器


一、文件上传的回顾

1、文件上传的必要前提

  • Aform 表单的 enctype 取值必须是: multipart/form-data (默认值是: application/x-www-form-urlencoded ) enctype:是表单请求正文的类型
  • B、 method 属性取值必须是 Post
  • C、提供一个文件选择域 <input type=”file” />

2、文件上传的原理分析

form 表单的 enctype 取值不是默认值后, request.getParameter() 将失效。 enctype=”application/x-www-form-urlencoded” 时,form 表单的正文内容是: key=value&key=value&key=value ,当 form 表单的 enctype 取值为 Mutilpart/form-data 时,请求正文内容就变成: 每一部分都是 MIME 类型描述的正文

// 请求头报文

POST /fileUpload HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 21382
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://localhost:8080
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryyAeL6Zw1JWwLK8Yc
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost:8080/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cookie: JSESSIONID=2D445DA78CC8A811A7DBA86679E6F6AE

3、借助第三方组件实现文件上传

使用 Commons-fileupload 组件实现文件上传,需要导入该组件相应的支撑 jar 包:Commons-fileupload commons-io

commons-io 不属于文件上传组件的开发 jar 文件,但Commons-fileupload 组件从 1.1 版本开始,它工作时需要 commons-io 包的支持。

二、springmv c 传统方式的文件上传

1、说明  

传统方式的文件上传,指的是我们上传的文件和访问的应用存在于同一台服务器上。并且上传完成之后,浏览器可能跳转。

2、实现步骤

(1)第一步:引入Commons-fileupload 文件上传依赖

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>

(2)第二步:编写 jsp 页面

<form action="/fileUpload" method="post" enctype="multipart/form-data">
    名称:<input type="text" name="picName"/><br/>
    图片:<input type="file" name="uploadFile"/><br/>
    <input type="submit" value="上传"/>
</form>

(3)第三步:编写控制器

/**
 * 文件上传的的控制器 * @Version 1.0
 */
@Controller
public class FileUploadController {
    /**
     * 文件上传
     */
    @RequestMapping("/fileUpload")
    public String testResponseJson(String picName, MultipartFile uploadFile, HttpServletRequest request) throws Exception {
        // 一、定义文件名
        String fileName = "";
        // 1.获取原始文件名
        String uploadFileName = uploadFile.getOriginalFilename();
        // 2.截取文件扩展名
        String extendName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
        // 3.把文件加上随机数,防止文件重复
        String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
        // 4.判断是否输入了文件名
        if (!StringUtils.isEmpty(picName)) {
            fileName = uuid + "_" + picName + "." + extendName;
        } else {
            fileName = uuid + "_" + uploadFileName;
        }
        System.out.println(fileName);
        // 二、使用request获取文件路径
        ServletContext context = request.getServletContext();
        String basePath = context.getRealPath("/uploads");
        // 三、解决同一文件夹中文件过多问题
        String datePath = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        // 四、判断路径是否存在
        File file = new File(basePath + "/" + datePath);
        if (!file.exists()) {
            file.mkdirs();
        }
        // 五、使用 MulitpartFile 接口中方法,把上传的文件写到指定位置
        uploadFile.transferTo(new File(file, fileName));
        return "success";
    }
}

(4)第四步:在springmvc.xml中配置文件解析器

    <!-- 配置文件上传解析器 -->
    <!-- id 的值是固定的-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 设置上传文件的最大尺寸为 5MB -->
        <property name="maxUploadSize">
            <value>5242880</value>
        </property>
    </bean>

注意: 文件上传的解析器 id 是固定的不能起别的名称,否则无法实现请求参数的绑定。(不光是文件,其他字段也将无法绑定)

上传结果:

3、问题:tomcat不能访问本地服务器上的图片

JAVA开发SSM为架构的系统时,把图片直接存储到tomcat/webapps下的某个文件中后,启动tomcat后,直接通过URL访问报404错误。

(1)创建本地目录,配置静态资源不过滤

(2)配置IDEA,勾选相关选项

(3)配置tomcat的server.xml文件

找到tomcat的server.xml文件,在该文件Host节点下加入:

<Context  path="/uploads" docBase="E://IDEA_WORK_SPACE//springmvcdemo//target//springmvcdemo-1.0-SNAPSHOT//uploads" reloadable="true" />

其中path是webapp下的文件夹,docBase是真实图片路径

访问结果:

三、springmvc 跨服务器方式的文件上传

1、分服务器的目的

在实际开发中,我们会有很多处理不同功能的服务器。例如:

  • 应用服务器:负责部署我们的应用
  • 数据库服务器:运行我们的数据库
  • 缓存和消息服务器:负责处理大并发访问的缓存和消息
  • 文件服务器:负责存储用户上传文件的服务器

分服务器处理的目的是让服务器各司其职,从而提高我们项目的运行效率

2、准备图片存放 tomcat 服务器

(1)修改默认端口——避免和idea使用tomcat端口重叠

<Server port="8015" shutdown="SHUTDOWN">
...
<Connector port="8090" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
...
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8019" protocol="AJP/1.3" redirectPort="8443" />
<Server/>

点击startup.bat,并测试:

(2)创建文件上传目录

图片存放 tomcat 服务器webapps目录下创建文件上传目录: myserver\myfiles

(3)web.xml文件中加入允许读写操作

tomcat 配置文件conf下,web.xml文件中加入允许读写操作。如下:

    <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
		<!--允许写入文件-->
		<init-param>
            <param-name>readonly</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

加入此行的含义是:接收文件的目标服务器可以支持写入操作文件修改完后,重新启动tomcat服务器

3、拷贝依赖

在我们负责处理文件上传的项目中还需添加拷贝文件上传的必备 jar

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-client</artifactId>
            <version>1.18.1</version>
        </dependency>

4、编写控制器实现上传图片

package com.test.controller;

/**
 * @author swadian
 * @date 2021/2/6
 * @Version 1.0
 * @describetion
 */

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.UUID;

/**
 * 文件上传的的控制器 * @Version 1.0
 */
@Controller
public class FileUploadController {
    /**
     * 文件上传的服务器地址
     */
    public static final String FILESERVERURL = "http://localhost:8090/myserver/myfiles/";

    /**
     * 文件上传
     */
    @RequestMapping("/fileUpload")
    public String testResponseJson(String picName, MultipartFile uploadFile, HttpServletRequest request) throws Exception {
        // 一、定义文件名
        String fileName = "";
        // 1.获取原始文件名
        String uploadFileName = uploadFile.getOriginalFilename();
        // 2.截取文件扩展名
        String extendName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
        // 3.把文件加上随机数,防止文件重复
        String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
        // 4.判断是否输入了文件名
        if (!StringUtils.isEmpty(picName)) {
            fileName = uuid + "_" + picName + "." + extendName;
        } else {
            fileName = uuid + "_" + uploadFileName;
        }
        System.out.println(fileName);
        // 5.创建 sun 公司提供的 jersey 包中的 Client 对象
        Client client = Client.create();
        // 6.指定上传文件的地址,该地址是 web 路径
        WebResource resource = client.resource(FILESERVERURL + fileName);
        // 7.实现上传
        String result = resource.put(String.class, uploadFile.getBytes());
        System.out.println(result);
        return "success";
    }
}

5、编写JSP + 配置解析器

编写JSP + 在springmvc.xml中配置文件解析器,步骤同传统模式一样。

执行结果:

服务器文件夹目录下可以看到上传文件:

通过浏览器可以访问到目标文件:

猜你喜欢

转载自blog.csdn.net/swadian2008/article/details/113727660