原文地址:https://blog.csdn.net/weixin_41092717/article/details/81080152
文件上传
文件上传是项目开发中最常见的功能。为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器。
一旦设置了enctype为multipart/form-data,浏览器即会采用二进制流的方式来处理表单数据,而对于文件上传的处理则涉及在服务器端解析原始的HTTP响应。在2003年,Apache Software Foundation发布了开源的Commons FileUpload组件,其很快成为Servlet/JSP程序员上传文件的最佳选择。
Servlet3.0规范已经提供方法来处理文件上传,但这种上传需要在Servlet中完成。而SpringMVC则提供了更简单的封装。
SpringMVC为文件上传提供了直接的支持,这种支持是用即插即用的MultipartResolver实现的。SpringMVC使用Apache Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver。因此,SpringMVC的文件上传还需要依赖Apache Commons FileUpload的组件。
这个实例教程是我在其他项目中取的lib包,是用idea开发的一个demo。采用Tomcat7作为web服务器大家跟随我的步骤做一般不会有问题。
第一步创建springmvc项目点击file—>new—> project勾选如下图所示的选项后续next;中途会有项目的名字这里自己随意我取得名字叫mvc;创建项目的过程中会自动倒部分SpringMVC的jar包依赖,后续还需要添加。
创建好的项目结构
2.lib需要的包结构图因为是从其他项目中提取得jar包其中有几个是用不到的;如果闲麻烦可以到百度云下载
提醒:如果你直接从我的链接下载最好把你创建工程时自动下载的依赖jar包删除,然后直接导入
链接:https://pan.baidu.com/s/1Hdapx9J2K9_CPtIM15ImxA
提取密码:8tk3
下面我们在WebContent/WEB-INF下创建一个content文件夹,用于放文件的上传、下载等jsp文件,下面我们创建uploadForm.jsp文件,演示SpringMVC的文件上传:
<%-- Created by IntelliJ IDEA. User: YYBJ Date: 2018/7/13 Time: 10:54 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <!-- jQuery --> <script src="/assets/js/jquery.min.js"></script> <!-- 如果你不想从网上下载js再导入项目可以用百度在线网址js文件 注意:电脑要联网才行 --> <!-- <script src="http://libs.baidu.com/jquery/1.11.3/jquery.min.js"></script> --> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>文件上传</title> </head> <body> <h2>文件上传</h2> <form id="tf" enctype="multipart/form-data" > <table> <tr> <td>文件描述:</td> <td><input type="text" name="description"></td> </tr> <tr> <td>请选择文件:</td> <td><input type="file" name="file"></td> </tr> <tr> <td><input type="button" value="上传" οnclick="test()"></td> </tr> </table> </form> <script > function test(){ alert("aaaaaaaaaaaa") var form = new FormData(document.getElementById("tf")); $.ajax({ url:"/controller/upload", type:"post", data:form, processData:false, contentType:false, success:function(data){ if(data=="1"){ alert("上传成功") }else { alert("上传失败") } } }); } </script> </body> </html>
注意提醒:这里ajax结合formdata对象上传文件是比较方便的如果对formdata不了解可以自行查看关于formdata的资料提供一个链接参考
https://developer.mozilla.org/zh-CN/docs/Web/API/FormData/Using_FormData_Objects
SpringMVC会将上传的文件绑定到MultipartFile对象中。MultipartFile提供了获取上传文件内容、文件名等方法。
通过transferTo()方法还可以将文件存储到硬件中,MultipartFile对象中的常用方法如下:
byte[] getBytes():获取文件数据
String getContentType[]:获取文件MIME类型,如image/jpeg等
InputStream getInputStream():获取文件流
String getName():获取表单中文件组件的名字
String getOriginalFilename():获取上传文件的原名
Long getSize():获取文件的字节大小,单位为byte
boolean isEmpty():是否有上传文件
void transferTo(File dest):将上传文件保存到一个目录文件中
SpringMVC上下文中默认没有装配MultipartResolver,因此默认情况下其不能处理文件上传工作。如果想使用spring的文件上传功能,
则需要在上下文中配置MultipartResolver。在dispatcher-servlet.xml进行配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" 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可以自动去扫描base-pack下面的包或者子包下面的java文件, 如果扫描到有Spring的相关注解的类,则把这些类注册为Spring的bean --> <context:component-scan base-package="cn.edu.jseti"/> <!-- 视图解析器 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 前缀 --> <property name="prefix"> <value>/WEB-INF/content/</value> </property> <!-- 后缀 --> <property name="suffix"> <value>.jsp</value> </property> </bean> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 上传文件大小上限,单位为字节(10MB) --> <property name="maxUploadSize"> <value>10485760</value> </property> <!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 --> <property name="defaultEncoding"> <value>UTF-8</value> </property> </bean> </beans>
在applicationContext.xml文件中同样添加包扫描
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 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 "> <!-- spring可以自动去扫描base-pack下面的包或者子包下面的java文件, 如果扫描到有Spring的相关注解的类,则把这些类注册为Spring的bean --> <context:component-scan base-package="cn.edu.jseti"/>
在web.xml文件中添加必要的过滤器和servlet配置
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <display-name>MultipartFileTest</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <!-- 定义Spring MVC的前端控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/dispatcher-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- 让Spring MVC的前端控制器拦截所有请求 --> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.json</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>springmvc</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> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
在最外层的index.jsp文件中添加一行跳转请求。正常情况下我们的jsp页面都放在web-INF下。一般是不能直接跳转访问的所以我们采用调用接口在接口中请求跳转。这里会请求到controller目录下的intoload方法这时候注解的方式就起作用了。
<%-- Created by IntelliJ IDEA. User: YYBJ Date: 2018/7/16 Time: 11:20 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <jsp:forward page="/controller/intoload"/>
负责上传文件的表单和一般表单有一些区别,负责上传文件的表单的编码类型必须是“multipart/form-data”。
我们再src下创建一个包“cn.edu.jseti.controller”,然后创建一个FileUploadController类,用于实现文件的上传和下载功能。以下是所有的controller代码。注意:这里会用到注解的开发所以需要配置.xml文件在后续步骤
package cn.edu.jseti.controller; import cn.edu.jseti.domain.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import org.apache.commons.io.FileUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.ui.Model; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; /** * Created by YYBJ on 2018/7/16. * ZCL */ @Controller @RequestMapping("/controller") public class FileUploadController { //这个方法是进行页面跳转的 jsp页面在WEB-INF下不能直接访问 @RequestMapping(value = "/intoload") public ModelAndView intoload(HttpServletRequest request, HttpServletResponse response)throws Exception{ System.out.println("111111111111111"); ModelAndView mv = new ModelAndView(); mv.setViewName("/uploadForm"); return mv; } //上传文件会自动绑定到MultipartFile中 @RequestMapping("/upload") @ResponseBody public String upload(HttpServletRequest request, @RequestParam("description") String description, @RequestParam("file") MultipartFile file) throws Exception { System.out.println(description); //如果文件不为空,写入上传路径 if(!file.isEmpty()) { //上传文件路径 String path = request.getServletContext().getRealPath("/images/"); System.out.println(path); //上传文件名 String filename = file.getOriginalFilename(); File filepath = new File(path,filename); //判断路径是否存在,如果不存在就创建一个 if (!filepath.getParentFile().exists()) { filepath.getParentFile().mkdirs(); } //将上传文件保存到一个目标文件当中 file.transferTo(new File(path + File.separator + filename)); //输出文件上传最终的路径 测试查看 System.out.println(path + File.separator + filename); return "1"; } else { return "0"; } } }
最终启动项目测试控制台Tomcat基本没有报错,这时开始测试,启动项目自动跳转到文件上传页面。如果跳转出错看自己的tomc配置路径是否有问题。
最终测试完成 从控制台查看输出的路径找到图片是否存在到此文件上传完成。有问题可以留言
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_41092717/article/details/81080152