Spring MVC 学习笔记 5《5.1 单文件上传》

版权声明:大家好,我是笨笨,笨笨的笨,笨笨的笨,转载请注明出处,谢谢! https://blog.csdn.net/jx520/article/details/89298186

添加依赖

/ssm/pom.xml
commons-fileupload 最新版是 2018年12月的 1.4版

<!-- 上传组件包 --> 
<dependency> 
    <groupId>commons-fileupload</groupId> 
    <artifactId>commons-fileupload</artifactId> 
    <version>1.4</version> 
</dependency> 

添加上传解析bean

/ssm/src/main/resources/spring-mvc.xml

<!-- =========================== 配置上传解析bean =========================== -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
 	<property name="defaultEncoding" value="utf-8"></property><!-- 设置解析编码格式 -->
	<property name="maxInMemorySize" value="10485760"></property><!-- 设置上传数据的总大小  字节 (10M)-->
	<property name="maxUploadSize" value="1024128392"></property><!--设置单个文件大小  字节-->
</bean>

CommonsMultipartResolver本身提供了限制大小的功能。但据说TomcatBug把抛出来的异常吃了,导致异常处理模块捕获不到异常,假装没发生。解决方案看这个 Spring MVC 学习笔记 6《触发异常后跳转控制》

添加控制层

上传图片

/ssm/src/main/java/com/jerry/ssm/controller/UpLoadController.java
图片上传界面 http://localhost/goUploadImage.html
图片上传接口 http://localhost/uploadImage

package com.jerry.ssm.controller;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.jerry.ssm.exception.JerryException;
import com.jerry.ssm.util.PropertiesUtils;

@Controller
@Scope("prototype")
public class UpLoadController {
	private final String allowedFilesType = ".jpg.png.jpeg.bmp.gif";
	private final Integer totalMaxFileSize = 1024 * 1024 * 2;
	
	/**
	 * 图片上传界面
	 * http://localhost/goUploadImage.html
	 * @throws JerryException 
	 */
	@RequestMapping("/goUploadImage.html")
	public String goUploadImage() throws JerryException {
		return "goUploadImage";
	}
	
	/**
	 * 图片上传接口
	 * http://localhost/uploadImage
	 * @param model
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value="/uploadImage", produces={"application/json; charset=UTF-8"})
	public Map<String, Object> uploadImage(Integer refType, Long refId, String remark, MultipartFile photo, HttpServletRequest request) {
		Map<String , Object> resultMap = new HashMap<String ,Object>();
		// ============================ 存储文件到服务器硬盘 ============================
		// --------------- 后端校验 开始 ---------------
		if(photo.isEmpty()){
			resultMap.put("code", "1000");
			resultMap.put("msg", "请选择图片");
			return resultMap;
		}
		// ------------ 文件名  ------------
		// 从原文件名中截取出扩展名
		String suffix = "";
		try {
			suffix = photo.getOriginalFilename().substring(photo.getOriginalFilename().lastIndexOf("."));
		} catch (Exception e) {
			e.printStackTrace();
			resultMap.put("code", "1001");
			resultMap.put("msg", "图片扩展名错误");
			return resultMap;
		}
		// 校验文件类型
		if(!allowedFilesType.contains(suffix.toLowerCase())){
			resultMap.put("code", "1002");
			resultMap.put("msg", "只支持上传 jpg,png,bmp 图片");
			return resultMap;
		}
		// 校验文件大小 2M
		if(photo.getSize() > totalMaxFileSize){
			resultMap.put("code", "1003");
			resultMap.put("msg", "图片最大2M");
			return resultMap;
		}
		// --------------- 后端校验 结束 ---------------
		
		//动态创建文件名 :图片类型_UUID_时间戳.扩展名
		String name= refType + "_" + UUID.randomUUID() + "_" +System.currentTimeMillis() + suffix;
		
		// ------------ 文件夹  ------------
		// 获取 webapp 目录下的绝对路径
		String urlPath = "image"+ File.separator + new SimpleDateFormat("yyyyMMdd").format(new Date());
		String realPath= PropertiesUtils.get("upload_path") + urlPath;
		File fpath = new File(realPath);
		if(!fpath.exists()){// 如果不存在就创建
			try {
				fpath.mkdirs();
			} catch (Exception e) {
				e.printStackTrace();
				resultMap.put("code", "2001");
				resultMap.put("msg", "创建保存路径失败");
				return resultMap;
			}
		}
		
		// ------------ 拼出完整路径,保存 ------------
		File file = new File(fpath, name);
		try {
			photo.transferTo(file);
		} catch (Exception e) {
			e.printStackTrace();
			resultMap.put("code", "4001");
			resultMap.put("msg", "图片保存失败");
			return resultMap;
		}
		
		//将上传记录存储到数据库记录表中(用户ID,上传文件原始名,上传文件新名,时间,文件类型)
		int i = 1; // 保存图片信息到数据库,返回成功标识(这一步本Demo就省了);
		if(i > 0){
			resultMap.put("code", "1000");
			resultMap.put("msg", "上传图片成功");
			resultMap.put("imageName", photo.getOriginalFilename());
			resultMap.put("url", urlPath + "/" + name);
			resultMap.put("fullUrl", request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+ "/" + urlPath + "/" + name);
		}else{
			resultMap.put("code", "4000");
			resultMap.put("msg", "上传图片失败");
		}			
		return resultMap;

	}
}

添加JSP 图片上传界面

/ssm/src/main/webapp/WEB-INF/jsp/goUploadImage.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
	<head>
		<title>SpringMVC 文件上传 Demo</title>
	</head>
	<body>
		<h1>SpringMVC 文件上传 Demo</h1>
		<form action="uploadImage" method="post" enctype="multipart/form-data">
			图片归属对象类型:<input type="text" name="refType"  value=""/><br />
			图片归属对象id:<input type="text" name="refId"  value=""/><br />
			图片描述:<input type="text" name="remark"  value=""/><br />
			图片:<input type="file" name="photo" /><br />
			<input type="submit" value="点击上传" />		
		</form>
	</body>
</html>

上传文件

/ssm/src/main/java/com/jerry/ssm/controller/UpLoadController.java 和上图一样也在这个控制器里,只是这里分开列,方便查看
文件上传界面 http://localhost/goUploadFile.html
单文件上传接口 http://localhost/uploadFile

	。。。
	/**
	 * 文件上传界面
	 * http://localhost/goUploadFile.html
	 * @throws JerryException 
	 */
	@RequestMapping("/goUploadFile.html")
	public String goUploadFile() throws JerryException {
		return "goUploadFile";
	}
	
	/**
	 * 文件上传接口
	 * http://localhost/uploadFile
	 * @param model
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value="/uploadFile", produces={"application/json; charset=UTF-8"})
	public Map<String, String> uploadFile(Integer refType, Long refId, String remark, @RequestParam("uploadfile") CommonsMultipartFile file, HttpServletRequest request) {
		return uploadFile(refType, file, request);
	}
	
	private Map<String, String> uploadFile(Integer refType, CommonsMultipartFile file, HttpServletRequest request) {
		Map<String , String> resultMap = new HashMap<String ,String>();
		// ============================ 存储文件到服务器硬盘 ============================
		// --------------- 后端校验 开始 ---------------
		if(file.isEmpty()){
			resultMap.put("code", "1000");
			resultMap.put("msg", "请选择上传文件");
			return resultMap;
		}
		// 扩展名校验
		String suffix = "";
		try {
			suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));// 从原文件名中截取出扩展名
		} catch (Exception e) {
			e.printStackTrace();
			resultMap.put("code", "1001");
			resultMap.put("msg", "扩展名错误");
			return resultMap;
		}
		// --------------- 后端校验 结束 ---------------
		
		// ------------ 生成文件名  ------------
		// 图片类型_UUID_时间戳.扩展名
 		String fileName= refType + "_" + DateFormatUtils.format(new Date(), "yyyyMMddHHmmss") + suffix;
		
		// ------------ 确定保存位置  ------------
		// 从配置文件读取绝对路径
		String diskPath = "file" + File.separator + new SimpleDateFormat("yyyyMMdd").format(new Date());
		// 用于展示的url虚拟路径
		String urlPath = diskPath.replace("\\", "/");
		// 生成保存路径
		File filePath = new File(PropertiesUtils.get("upload_path) + diskPath);
		if(!filePath.exists()){// 如果不存在就创建
			try {
				filePath.mkdirs();
			} catch (Exception e) {
				e.printStackTrace();
				resultMap.put("code", "2001");
				resultMap.put("msg", "创建保存路径失败");
				return resultMap;
			}
		}
		
		// ------------ 保存文件 ------------
		try {
			// filePath + fileName = 完整文件路径
			//file.transferTo(new File(filePath, fileName));
			// 保存上传的文件到硬盘
			FileUtils.copyInputStreamToFile(file.getInputStream(), new File(filePath, fileName));
		} catch (Exception e) {
			e.printStackTrace();
			resultMap.put("code", "4001");
			resultMap.put("msg", "文件保存失败");
			return resultMap;
		}
		
		//将上传记录存储到数据库记录表中(用户ID,上传文件原始名,上传文件新名,时间,文件类型)
		int i = 1; // 保存文件信息到数据库,返回成功标识(这一步本Demo就省了);
		
		// 返回结果给客户端
		if(i > 0){
			resultMap.put("code", "1000");
			resultMap.put("msg", "文件上传成功");
			resultMap.put("fileName", file.getOriginalFilename());
			resultMap.put("url", urlPath + "/" + fileName);
			resultMap.put("fullUrl", request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+ "/" + urlPath + "/" + fileName);
		}else{
			resultMap.put("code", "4000");
			resultMap.put("msg", "文件上传失败");
		}			
		return resultMap;
	}

添加JSP 文件上传界面

/ssm/src/main/webapp/WEB-INF/jsp/goUploadFile.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
	<head>
		<title>SpringMVC 文件上传 Demo</title>
	</head>
	<body>
		<h1>SpringMVC 单文件上传 Demo</h1>
		<form action="uploadFile" method="post" enctype="multipart/form-data">
			文件归属对象类型:<input type="text" name="refType"  value=""/><br />
			文件归属对象id:<input type="text" name="refId"  value=""/><br />
			文件描述:<input type="text" name="remark"  value=""/><br />
			文件:<input type="file" name="uploadfile" /><br />
			<input type="submit" value="点击上传" />		
		</form>				
	</body>
</html>

用于保存文件信息的表

CREATE TABLE `file_info` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `ref_type` int(11) unsigned DEFAULT NULL COMMENT '关联类型',
  `ref_id` bigint(20) unsigned DEFAULT NULL COMMENT '关联id',
  `img_url` varchar(255) DEFAULT NULL COMMENT '图片路径',
  `remark` varchar(255) DEFAULT '' COMMENT '文件描述',
  `original_filename` varchar(255) DEFAULT '' COMMENT '原文件名',
  `create_date` datetime DEFAULT NULL COMMENT '创建日期',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

用于保存图片信息的表

这里偷懒了,并没有做保存图片数据的部分。前面的几篇里相关的知识点都已经涵盖了。

CREATE TABLE `image` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `refType` int(11) unsigned DEFAULT NULL COMMENT '关联类型',
  `refId` bigint(20) unsigned DEFAULT NULL COMMENT '关联id',
  `url` varchar(255) DEFAULT NULL COMMENT '图片路径',
  `remark` varchar(255) DEFAULT '' COMMENT '图片描述',
  `originalFilename` varchar(255) DEFAULT '' COMMENT '原文件名',
  `create_date` datetime DEFAULT NULL COMMENT '创建日期',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

获取 Properties 工具类

/ssm/src/main/resources/system.properties
定义文件上传位置

扫描二维码关注公众号,回复: 6129049 查看本文章
# files upload path
upload_path=d:\\upload_files_path\\

/ssm/src/main/java/com/jerry/ssm/util/PropertiesUtils.java 工具类用来获取配置文件值。为写DEMO网上随便找了个工具类。

package com.jerry.ssm.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class PropertiesUtils {

	public static String get(String name) {
		return getProperties(name);
	}
	
	public static String getProperties(String name) {
		Properties props = null;
		String value = "";
		try {
			props = getPropertiesInCache();
			value = props.getProperty(name);
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return value;
	}

	public static Properties getPropertiesInCache() throws SecurityException, IOException {
		Properties pro = null;
		if (pro == null) {
			pro = getProperties();
		}
		return pro;
	}

	private static Properties getProperties() throws IOException {
		InputStream in = null;
		try {
			in = Thread.currentThread().getContextClassLoader().getResource("system.properties").openStream();
			Properties props = new Properties();
			props.load(in);

			return props;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (in != null)
				in.close(); // 别忘了关流
		}
		return null;
	}

	public static void putPropertiesToCache() throws IOException {
		Properties pro = getProperties();
	}
}

为保存文件的位置配置虚拟路径

工作空间\Servers\Tomcat v7.0 Server at localhost-config\server.xml

      <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">     
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t &quot;%r&quot; %s %b" prefix="localhost_access_log." suffix=".txt"/>
		<Context docBase="ssm" path="/" reloadable="true" source="org.eclipse.jst.j2ee.server:ssm"/>
		<Context debug="0" docBase="f:\upload_files_path\image" path="/image" reloadbale="true"/>
		<Context debug="0" docBase="f:\upload_files_path\file" path="/file" reloadbale="true"/>
      </Host>

在这里插入图片描述

甩锅说明

按理说我应该给图片信息表定义个对象,上传时用类似 fileInfoimageInfo这样的对象来接收文件信息。参数绑定相关看 Spring MVC 学习笔记 2《请求和参数绑定》#4 自定义对象类型

Demo源码下载

https://download.csdn.net/download/jx520/11114784

猜你喜欢

转载自blog.csdn.net/jx520/article/details/89298186