1.新建一个自动配置文件custom.properties并编写
注意:服务器地址必须绝对路径,系统路径形式。
2.编写读取配置文件的工具类PropertiesUtil.
package com.crawler.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* 读取properties文件
*
* @author fanhx
*/
public class PropertiesUtils {
private Properties properties;
private static PropertiesUtils propertiesUtils = new PropertiesUtils();
/**
* 私有构造,禁止直接创建
*/
private PropertiesUtils() {
properties = new Properties();
InputStream in = PropertiesUtils.class.getClassLoader()
.getResourceAsStream("custom.properties");
try {
properties.load(in);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取单例
*
* @return PropertiesUtils
*/
public static PropertiesUtils getInstance() {
if (propertiesUtils == null) {
propertiesUtils = new PropertiesUtils();
}
return propertiesUtils;
}
/**
* 根据属性名读取值
*
* @param name
* 名称
*/
public Object getProperty(String name) {
return properties.getProperty(name);
}
/*************************************************************************/
/***************************** 读取属性,封装字段 **************************/
/*************************************************************************/
/**
* 是否调试模式
*/
public Boolean isDebug() {
return "true".equals(properties.getProperty("isDebug"));
}
public String getAttachmentServer() {
return properties.getProperty("attachmentServer");
}
public String getAttachmentPath() {
return properties.getProperty("attachmentPath");
}
public String getAttachmentGainPpath() {
return properties.getProperty("attachmentGainPath");
}
public static void main(String[] args) {
PropertiesUtils pro = PropertiesUtils.getInstance();
String value = String.valueOf(pro.getProperty(
"custom.properties.name").toString());
System.out.println(value);
}
}
3.定义上传文件返回类型FileResult.
package com.crawler.entity;
/**
*
* @ClassName: FileResult
* @Description:文件上传的返回实体
* @author fanhx
*
*/
public class FileResult {
private String fileName;
private String extName;
private long fileSize;
private String severPath;
public FileResult() {
super();
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getExtName() {
return extName;
}
public void setExtName(String extName) {
this.extName = extName;
}
public long getFileSize() {
return fileSize;
}
public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}
public String getSeverPath() {
return severPath;
}
public void setSeverPath(String severPath) {
this.severPath = severPath;
}
@Override
public String toString() {
return "FileResult [fileName=" + fileName + ", extName=" + extName
+ ", fileSize=" + fileSize + ", severPath=" + severPath + "]";
}
}
4.编写返回客户端响应模板
package com.crawler.entity;
import java.io.Serializable;
/**
*
* @ClassName:DataResult
* @Description:返回客户端的响应结果
* @author:
* @date:2019年7月10日
*/
public class DataResult implements Serializable{
//操作是否成功
private boolean successed;
//返回的提示消息
private String message;
//返回的数据
private Object data;
public DataResult(boolean successed, String message, Object data) {
super();
this.successed = successed;
this.message = message;
this.data = data;
}
public boolean isSuccessed() {
return successed;
}
public String getMessage() {
return message;
}
public Object getData() {
return data;
}
public void setSuccessed(boolean successed) {
this.successed = successed;
}
public void setMessage(String message) {
this.message = message;
}
public void setData(Object data) {
this.data = data;
}
}
5.编写上传文件工具类FileUploadUtil.
package com.crawler.util;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.web.multipart.MultipartFile;
import com.crawler.entity.DataResult;
import com.crawler.entity.FileResult;
import com.mysql.jdbc.StringUtils;
import net.coobird.thumbnailator.Thumbnails;
import java.io.File;
import java.io.IOException;
import java.util.*;
/**
* 文件上传工具类
*
* @author fanhx
*/
public class FileUploadUtil {
/**
* 属性配置
*/
private static PropertiesUtils pro = PropertiesUtils.getInstance();
/**
* 方法描述:根据文件的绝对路径创建一个文件对象.
*
* @param filePath 文件的绝对路径
* @return 返回创建的这个文件对象
* @author "fanhx"
*/
public static File createFile(String filePath) throws IOException {
// 获取文件的完整目录
String fileDir = FilenameUtils.getFullPath(filePath);
// 判断目录是否存在,不存在就创建一个目录
File file = new File(fileDir);
if (!file.isDirectory()) {
//创建失败返回null
if (!file.mkdirs()) {
throw new IOException("文件目录创建失败...");
}
}
// 判断这个文件是否存在,不存在就创建
file = new File(filePath);
if (!file.exists()) {
if (!file.createNewFile()) {
throw new IOException("目标文件创建失败...");
}
}
return file;
}
/**
* 方法描述:判断extension中是否存在extName
*
* @param extension 使用逗号隔开的字符串,精确匹配例如:txt,jpg,png,zip
* @param extName 文件的后缀名
* @author "fanhx"
*/
private static void isContains(String extension, String extName) {
if (StringUtils.isNullOrEmpty(extension)) {
// 切割文件扩展名
List<String> exts = StringUtils.split(extension, ",",true);
if (!exts.isEmpty()) {
assert exts != null;
//判断
if (!exts.contains(extName)) {
throw new RuntimeException("上传文件的类型只能是:" + extension);
}
} else {
// 判断文件的后缀名是否为extension
if (!extension.equalsIgnoreCase(extName)) {
throw new RuntimeException("上传文件的类型只能是:" + extension);
}
}
}
}
/**
* 方法描述:处理上传的图片
*
* @param serverPath 图片的绝对路径
* @param childFile 子文件夹
* @param extName 文件的后缀
* @author "fanhx"
*/
private static String thumbnails(String serverPath, String childFile, String extName)
throws IOException {
// 压缩后的相对路径文件名
String toFilePath = getDestPath(childFile, extName);
/*
* scale:图片缩放比例
* outputQuality:图片压缩比例
* toFile:图片位置
* outputFormat:文件输出后缀名
* Thumbnails: 如果用来压缩 png 格式的文件,会越压越大,
* 得把png格式的图片转换为jpg格式
*/
if ("png".equalsIgnoreCase(extName)) {
// 由于outputFormat会自动在路径后加上后缀名,所以移除以前的后缀名
String removeExtensionFilePath = FilenameUtils.removeExtension(toFilePath);
Thumbnails.of(serverPath).scale(1f)
.outputQuality(0.5f)
.outputFormat("jpg")
.toFile(getServerPath(removeExtensionFilePath));
toFilePath = removeExtensionFilePath + ".jpg";
} else {
Thumbnails.of(serverPath).scale(1f).outputQuality(0.5f)
.toFile(getServerPath(toFilePath));
}
// 删除被压缩的文件
FileUtils.forceDelete(new File(serverPath));
return toFilePath;
}
/**
* 方法描述:生成文件文件名
*
* @param childFile 子目录
* @param extName 后缀名
* @author "fanhx"
*/
private static String getDestPath(String childFile, String extName) {
String sb = childFile + "/"
+ RandomUtils.nextInt(0, 99999)
+ "." + extName;
return sb;
}
/**
* 方法描述:生成文件在的实际的路径
* 创建时间:2018-10-20 20:46:18
*
* @param destPath 文件的相对路径
* @author "lixingwu"
*/
private static String getServerPath(String destPath) {
// 文件分隔符转化为当前系统的格式
String attachmentGainPpathString = pro.getAttachmentGainPpath();
return FilenameUtils.separatorsToSystem(attachmentGainPpathString + destPath);
}
/**
* 方法描述:上传文件.
*
* @param multipartFile 上传的文件对象,必传
* @param childFile 上传的父目录,为空直接上传到指定目录 (会在指定的目录下新建该目录,例如:/user/1023)
* @param extension 允许上传的文件后缀名,为空不限定上传的文件类型 (使用逗号隔开的字符串,精确匹配例如:txt,jpg,png,zip)
* @param isImage 上传的是否是图片,如果是就会进行图片压缩;如果不希望图片被压缩,则传false,让其以文件的形式来保存
* @return the file result
* @throws IOException 异常信息应返回
* @author "lixingwu"
*/
private static FileResult saveFile(MultipartFile multipartFile, String childFile, String extension, Boolean isImage) throws IOException {
if (null == multipartFile || multipartFile.isEmpty()) {
throw new IOException("上传的文件对象不存在...");
}
// 文件名
String fileName = multipartFile.getOriginalFilename();
// 文件后缀名
String extName = FilenameUtils.getExtension(fileName);
if (StringUtils.isNullOrEmpty(extName)) {
throw new RuntimeException("文件类型未定义不能上传...");
}
// 判断文件的后缀名是否符合规则
isContains(extension, extName);
// 创建目标文件的名称,规则请看destPath方法
String destPath = getDestPath(childFile, extName);
// 文件的实际路径
String serverPath = getServerPath(destPath);
// 创建文件
File destFile = createFile(serverPath);
// 保存文件
multipartFile.transferTo(destFile);
// 拼装返回的数据
FileResult result = new FileResult();
//如果是图片,就进行图片处理
if (BooleanUtils.isTrue(isImage)) {
// 图片处理
String toFilePath = thumbnails(serverPath, childFile, extName);
// 得到处理后的图片文件对象
File file = new File(getServerPath(toFilePath));
// 压缩后的文件后缀名
String extExtName = FilenameUtils.getExtension(toFilePath);
// 源文件=源文件名.压缩后的后缀名
String extFileName = FilenameUtils.getBaseName(fileName) + "." + FilenameUtils.getExtension(toFilePath);
result.setFileSize(file.length());
result.setSeverPath(toFilePath);
result.setFileName(extFileName);
result.setExtName(extExtName);
} else {
result.setFileSize(multipartFile.getSize());
result.setFileName(fileName);
result.setExtName(extName);
result.setSeverPath(destPath);
}
return result;
}
/**
* 方法描述:上传文件.
*
* @param multipartFile 上传的文件对象,必传
* @param childFile 上传的父目录,为空直接上传到指定目录 (会在指定的目录下新建该目录,例如:/user/1023)
* @param extension 允许上传的文件后缀名,为空不限定上传的文件类型 (使用逗号隔开的字符串,精确匹配例如:txt,jpg,png,zip)
* @return the file result
* @throws IOException 异常信息应返回
* @author "fanhx"
*/
public static DataResult saveFile(MultipartFile multipartFile, String childFile, String extension) throws IOException {
FileResult file = saveFile(multipartFile, childFile, extension, false);
if(file!=null){
return new DataResult(true, "上传图片成功!",file);
}
return new DataResult(false, "上传图片失败!", file);
}
/**
* 方法描述:上传图片.
*
* @param multipartFile 上传的文件对象,必传
* @param childFile 上传的父目录,为空直接上传到指定目录 (会在指定的目录下新建该目录,例如:/user/1023)
* @param extension 允许上传的文件后缀名,为空不限定上传的文件类型 (使用逗号隔开的字符串,精确匹配例如:txt,jpg,png,zip)
* @return the file result
* @throws IOException 异常信息应返回
* @author "lixingwu"
*/
public static DataResult saveImage(MultipartFile multipartFile, String childFile, String extension) throws IOException {
FileResult image = saveFile(multipartFile, childFile, extension, true);
if(image!=null){
return new DataResult(true, "上传图片成功!", image);
}
return new DataResult(false, "上传图片失败!", null);
}
}
6.编写UploadController,以便进行页面测试
package com.crawler.controller;
import java.io.IOException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
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 com.crawler.entity.DataResult;
import com.crawler.util.FileUploadUtil;
@RequestMapping("/upload")
@Controller
@Api(description = "Upload Controller", tags = { "Upload-Contoller" })
public class UploadController {
/**
*
* @param childFile
* 上传的父目录
* @param extension
* 允许上传的文件后缀名
* @author "lixingwu"
*/
@ApiOperation(value = "文件上传", notes = "图片也可以使用,但是图片不会被压缩")
@PostMapping("/uploadFile")
@ResponseBody
public DataResult uploadFile(
MultipartFile multipart,
@RequestParam(value = "childFile", required = false, defaultValue = "") String childFile,
@RequestParam(value = "extension", required = false, defaultValue = "") String extension)
throws IOException {
return FileUploadUtil.saveFile(multipart, childFile, extension);
}
/**
* 方法描述:图片上传,只能给图片使用,其他文件调用会异常. 创建时间:2018-10-19 14:10:32
*
* @param childFile
* 上传的父目录
* @param extension
* 允许上传的文件后缀名
* @author "lixingwu"
*/
@ApiOperation(value = "图片上传", notes = "只能给图片使用,其他文件调用会异常")
@PostMapping("/uploadImage")
@ResponseBody
public DataResult uploadImage(
MultipartFile multipart,
@RequestParam(value = "childFile", required = false, defaultValue = "") String childFile,
@RequestParam(value = "extension", required = false, defaultValue = "") String extension)
throws IOException {
return FileUploadUtil
.saveImage(multipart, childFile, extension);
}
}
7.可以用Swagger进行接口测试。