Project(5)——基于SpringMVC的文件上传

Project(5)——基于SpringMVC的文件上传

1、创建项目

创建Maven Project,Group Id值为cn.tedu.spring,Artifact Id为SPRINGMVC-UPLOAD,在配置依赖时,此次需要spring-webmvc依赖,另外,还需要commons-fileupload依赖:


        <!-- spring-webmvc -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>5.2.1.RELEASE</version>
		</dependency>
		
		<!-- 文件上传 -->
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.4</version>
		</dependency>
		

web.xml 中配置 Servlet

<?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_2_5.xsd"
	version="2.5">
	<display-name>SMVCU</display-name>
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>default.html</welcome-file>
		<welcome-file>default.htm</welcome-file>
		<welcome-file>default.jsp</welcome-file>
	</welcome-file-list>

	<servlet>
		<servlet-name>MyBatis</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring-*.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>MyBatis</servlet-name>
		<url-pattern>*.do</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>

</web-app>

2、设计界面

webapp下创建index.html,作为用户选择文件上传的界面,该界面中,上传控件必须是<input type="file"/>,控件所在的表单必须使用POST方式提交请求,且必须配置enctype="multipart/form-data",其它部分可以自行设计,例如:

    <h1>基于SpringMVC的文件上传</h1>
	<form action="" method="post" enctype="multipart/form-data">
		<p>请选择要上传的文件</p>
		<input type="file" name="file"> <input type="submit"
			value="上传">
	</form>

在这里插入图片描述

3、配置MultipartResolver

在Spring的配置文件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"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">


	





	
</beans>

添加CommonsMultipartResolver配置:

    <!-- 组件扫描 -->
	<context:component-scan base-package="cn.tedu.spring"></context:component-scan>
	
	<!-- 配置ViewResolver-视图解析器 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/"></property>
		<property name="suffix" value=".jsp"></property>
	</bean>
	
	<!-- 注解驱动 -->
	<mvc:annotation-driven></mvc:annotation-driven>


    <!-- CommonsMultipartResolver -->
	<bean id="multipartResolver"
	    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	</bean>
	

添加以上配置后,暂时可以不用添加更多配置。

4、通过控制器接受并处理请求

创建cn.tedu.spring.UploadController控制器类,为控制器类添加@Controller注解:

@Controller
public class UploadController{

}

检查Spring的配置文件,其中的组件扫描应该设置为cn.tedu.spring

然后在控制器类中添加处理请求的方法,该方法中必须添加MultipartFile file参数,该参数名需要与前端页面的控件中使用的name属性的值保持一致,另外,需要添加@RequestParam("file")注解,使用注解后,需要保持一致的名称就是注解中使用的名称:

    @Controller
    public class UploadController{
        
        @RequestMapping("upload.do")
        public String handleUpload(@RequestParam("file") MultipartFile file){
    
            return null;
        }
    }

参数对象表示的就是客户端提交的需要上传的文件,只需要调用参数对象transferTo(File dest)方法即可实现文件上传!

另外,在前端页面中,还要设置表单提交到upload.do路径。

5、关于上传后在服务器端的文件名

保存到服务器端后使用的文件名必须不能发生冲突,否则,后续上传的文件,会覆盖前序上传的文件!

关于File类,使用1个String作为构造方法参数时,表示目标文件的完整路径,也可以使用2个String作为构造方法的参数,第1个表示文件夹,第2个表示文件名,所以,也可以是:

    // 确定上传到服务器,保存到的目标文件
    File dest = new File("D:/","baidu.png");

接下来,应该将第2个参数设置为变量,以保证各上传的文件名不发生冲突!

关于文件名的设置策略,可以自行决定,使用时间、随机数等元素作为文件名的一部分,就可以保证文件名不会发生冲突!

        // 确定文件名
		String filename = UUID.randomUUID().toString() + suffix;

		// 确定上传到服务器,保存到的目标文件
		File dest = new File("D:/",filename);

另外,还需要保证文件有正确的扩展名,应该取决于上传时,该文件在客户端计算机中保存时使用的名称,通过参数对象fileString getoriginalFilename()方法可以获取文件的原名,然后查询最后一个小数点的位置,并截取出扩展名即可:


		// 获取文件原名
		String originalFilename = file.getOriginalFilename();
		System.out.println("originalFilename = " + originalFilename);
		// 获取扩展名
		String suffix = "";
		int beginIndex = originalFilename.lastIndexOf(".");
		// 对于没有 . 的文件,要进行判断,如果没有 . 则lastIndexOf的值为-1,只需拼接空字符串即可。
		if(beginIndex != -1) {
			suffix = originalFilename.substring(beginIndex);
		}
		// 利用随机数确定文件名
		String filename = UUID.randomUUID().toString() + suffix;

6、文件夹

文件必须上传到部署的Tomcat中,当上传后,才可以保证后续的使用或下载,可以通过HttpServletRequest对象的getServletContext().getRealPath("upload")获取指定的文件夹的实际路径。再添加一个HttpServletRequest参数:

@RequestMapping(value = "upload.do", method = RequestMethod.POST)
	public String upload(@RequestParam("file") MultipartFile file, HttpServletRequest request)
	...
	..
	..
	..
        // 确定上传的文件夹
		String dirPath = request.getServletContext().getRealPath("upload");
		File dir = new File(dirPath);
		if (!dir.exists()) {
			dir.mkdirs();
		}
		System.out.println("dir = " + dir);
		// ...
		// ...
		// ...
		// 确定上传到服务器,保存到的目标文件
        File dest = new File(dir, filename);

基于该文件夹确定最终上传的文件位置:

        // 确定上传到服务器,保存到的目标文件
        File dest = new File(dir, filename);

7、MultipartFile相关API

7.1.boolean isEmpty()

该方法用于判断上传的文件是否为空,当用户没有选择上传的文件,或选中的文件是空文件(0字节)时,该方法返回true,可用于验证:

        // 判断上传文件是否为空文件
		boolean isEmpty = file.isEmpty();
		System.out.println("isEmpty = " + isEmpty);
		if(isEmpty) {
			return "error";
		}

7.2.long getSize()

该方法用于获取文件的大小,以字节为单位,通常,用于限制上传的文件大小:

        long size = file.getSize();
		System.out.println("size = " + size);
		if(size > 10 * 1024 * 1024) {
			return "error";
		}

7.3.String getContentType()

该方法用于获取文件的MIME类型,通常,用于限制上传的文件的类型:

        String contentType = file.getContentType();
		System.out.println("contentType = " + contentType);
		List<String> types = new ArrayList<String>();
		types.add("image/jpeg");
		types.add("image/gif");
		types.add("image/png");
		if(!types.contains(contentType)) {
			return "error";
		}

关于各种文件扩展名对应的MIME类型,可以上网查阅,也可以在Tomcat目录中的conf/web.xml文件中查找。MIME的值,完全取决于文件的扩展名,如果文件的扩展名被修改,MIME也可能发生变化。

7.4.String getOriginalFilename()

获取文件的原名,即该文件在客户端的文件全名,典型的用途就是获取文件的扩展名。

        // 获取文件原名
		String originalFilename = file.getOriginalFilename();
		System.out.println("originalFilename = " + originalFilename);

7.5. void transferTo(File dest)

执行保存所上传的文件。

        // 确定上传到服务器,保存到的目标文件
		File dest = new File(dir, filename);
		System.out.println("将文件保存到:" + dest);
		// 执行保存
		file.transferTo(dest);

7.6.InputStream getInputStream()

获取输入字节流,用于自定义接收所上传的文件的数据。

注意:该方法与以上transferTo()不可以同时使用,对于每个请求,只能选取其中1个方法来获取数据并保存文件。

8、关于MultipartResolver的配置

8.1. maxUploadSize

用于配置上传的文件的最大大小,例如:当设置值为10M时,则上传的文件均不可以超过10M,即使一次性上传10个文件,则10个文件的大小总和不允许超过10M。

例如可以配置最大大小为10M为:

在XML中的配置是全局配置,

    <!-- CommonsMultipartResolver -->
	<bean id="multipartResolver"
	    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	    <property name="maxUploadSize" value="10485760"></property>
	</bean>

以上7.2.的配置为具体功能的配置:

        long size = file.getSize();
		System.out.println("size = " + size);
		if(size > 10 * 1024 * 1024) {
			return "error";
		}

8.2.maxUploadSizePerFile

用于配置上传的每个文件的最大大小,例如:当设置值为10M时,如果一次性上传10个文件,则每个文件都不允许超过10M,但是总大小可以接近100M。

8.3.defaultEncoding

用于配置默认编码,上传的文件本身是不考虑编码问题的,只要文件的内容(表示文件内容信息含义的二进制序列)是正确的就可以了!由于上传过程中,会通过CommonsMultipartResolver去组织上传时表单中的数据,表单中可能包括例如输入框等控件,则同一个表单中还可能提交例如用户名等文本信息,这些信息都需要使用正确的编码来进行传递!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值