Java框架_SpringMVC_day05_文件上传

目录

六、SpringMVC 实现文件上传

6.1 文件上传的必要前提

6.2 SpringMVC 传统方式的文件上传

6.2.1 数据准备

6.2.2 普通文件上传

6.2.3 SpringMVC 方式上传文件

6.3 SpringMVC 跨服务器方式的文件上传

6.3.1 分服务器存储的目的

6.3.2 准备两个 tomcat 服务器(创建图片服务器)

6.3.3 文件上传

6.3.4 可能出现的问题


六、SpringMVC 实现文件上传

6.1 文件上传的必要前提

  • form 表单的 enctype 值必须是:multipart/form-data (支持二进制数据)
  • method 属性取值必须是 post
  • 提供一个文件选择域 <input type="file" />

6.2 SpringMVC 传统方式的文件上传

6.2.1 数据准备

导入 jar 包

<?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.cpz</groupId>
    <artifactId>springmvc_fileupload</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <!-- 版本锁定 -->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <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>

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

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="">

    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <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>

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

springmvc.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">

    <!-- 1:配置spring创建容器时要扫描的包 -->
    <context:component-scan base-package="com.cpz"></context:component-scan>
    <!-- 2:配置视图解析器 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
    <!-- 3:配置spring开启注解mvc的支持 -->
    <mvc:annotation-driven></mvc:annotation-driven>

    <!-- 设置静态资源不过滤 -->
    <!--去掉所有的静态资源,让DispatchServlet不能拦截静态资源-->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>
   
</beans>

6.2.2 普通文件上传

index.jsp

<form action="user/testFileUpload1" method="post" enctype="multipart/form-data">
    文件上传1:<input type="file" name="upload"/><br/>
    <input type="submit" value="上传"/>
</form>

Controller

    @RequestMapping(value = "/testFileUpload1")
    public String testFileUpload1(HttpServletRequest request) throws Exception {
        System.out.println("执行了 testFileUpload1 方法!!!");
        // 1:上传的位置,获取到项目根目录下的uploads文件夹绝对路径
        String realPath = request.getSession().getServletContext().getRealPath("/upload");
        // 创建 File 对象
        File file = new File(realPath);
        // 判断是否存在
        if (!file.exists()){
            file.mkdirs();
        }

        //2:创建ServletFileUpload和磁盘文件项工厂
        DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
        ServletFileUpload fileUpload = new ServletFileUpload(diskFileItemFactory);
        // 3:解析request,遍历FileItem对象
        List<FileItem> list = fileUpload.parseRequest(request);
        // 遍历,获取到每一个文件项的对象
        for (FileItem fileItem : list) {
            // 判断当前是否为文件项
            if (fileItem.isFormField()){

            }else{
                String fileName = fileItem.getName();
                // 生成唯一标识
                String uuid = UUID.randomUUID().toString().replace("-", "");
                fileName = uuid + "_" + fileName;
                // 4:上传文件,调用write()方法
                fileItem.write(new File(file,fileName));
                // 删除临时文件
                fileItem.delete();
            }
        }
        return "success";
    }

6.2.3 SpringMVC 方式上传文件

       SpringMVC框架提供了MultipartFile对象,该对象表示上传的文件,要求变量名称必须和表单file标签的name属性名称相同。

springmvc.xml

    <!-- 配置文件解析器对象,要求id名称必须是multipartResolver -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--文件大小限制:10*1024*1024字节,表示10M-->
        <property name="maxUploadSize" value="10485760"></property>
    </bean>

index.jsp

<form action="user/testFileUpload2" method="post" enctype="multipart/form-data">
    选择文件2:<input type="file" name="upload"><br/>
    <input type="submit" value="上传"/><br/>
</form>

Controller

/**
     * 使用的是SpringMVC的文件上传
     * 框架提供了一个类,表示上传文件的对象,底层已经帮你解析了request对象,把文件上传对象通过方法的参数传递进来
     *
     * MultipartFile upload    变量名称必须和表单file标签的name属性名称相同,上传文件的对象,SpringMVC框架传递给你的。
     */
    @RequestMapping(value = "/testFileUpload2")
    public String testFileUpload2(HttpServletRequest request,MultipartFile upload) throws Exception {
        System.out.println("执行了 testFileUpload2 方法!!!");
        String realPath = request.getSession().getServletContext().getRealPath("/upload");
        File file = new File(realPath);
        if (!file.exists()){
            file.mkdirs();
        }

        // 获取到文件的名称
        String fileName = upload.getOriginalFilename();
        String uuid = UUID.randomUUID().toString().replace("-","");
        fileName = uuid + "_" + fileName;
        // 使用upload对象中方法直接上传文件
        upload.transferTo(new File(file,fileName));

        return "success";
    }

6.3 SpringMVC 跨服务器方式的文件上传

6.3.1 分服务器存储的目的

在实际开发中,我们会有很多处理不同功能的服务器。例如: (注意:此处说的不是服务器集群)

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

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

 

6.3.2 准备两个 tomcat 服务器(创建图片服务器)

【注意】两个服务器的端口需要不一致,在图片服务器中需要创建一个 upload 文件夹(最好在里面随便放点文件)。

在负责处理文件上传的项目中导入必备 jar 包:

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

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-core</artifactId>
            <version>1.18.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-client</artifactId>
            <version>1.18.1</version>
        </dependency>

6.3.3 文件上传

index.jsp

<form action="user/testFileUpload3" method="post" enctype="multipart/form-data">
    选择文件3:<input type="file" name="upload"><br/>
    <input type="submit" value="上传"/><br/>
</form>

Controller

    @RequestMapping(value = "/testFileUpload3")
    public String testFileUpload3(MultipartFile upload,Model model) throws Exception {
        System.out.println("执行了 testFileUpload3 方法!!!");
        //1:指定上传文件的路径
        String path = "http://localhost:9090/springmvc_fileuploadserver/upload/";

        // 获取文件名称
        String fileName = upload.getOriginalFilename();
        String uuid = UUID.randomUUID().toString().replace("-","");
        fileName = uuid + "_" + fileName;

        // 2.上传文件
        //创建客户端对象
        Client client = Client.create();
        // 连接图片服务器
        WebResource webResource = client.resource(path + "" +fileName);
        // 把文件上传到图片服务器上
        webResource.put(upload.getBytes());
        model.addAttribute("fileName",fileName);
        return "success";
    }

可以再 success.jsp 中回显图片

<h1>文件上传成功</h1>
<img src="http://localhost:9090/springmvc_fileuploadserver/upload/${ fileName }">

6.3.4 可能出现的问题

returned a response status of 403 Forbidden

       出现这个错误的原因是因为我将图片上传单独部署了一个服务器。但是图片不能写入。需要在这个存储图片的项目所在的tomcat中配置可写操作。具体的是在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>

       加入此行的含义是:接收文件的目标服务器可以支持写入操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值