1:首先在項目的pom文件中添加兩個依賴
<!-- 文件上傳組件 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!-- 圖片處理類 -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
2:resource中添加 file-message.properties 配置文件
配置文件內(nèi)容如下
#文件壓縮大小(大于4兆壓縮)
message.fileSize=4194304
#圖片保存路徑
message.upPath=D:\\MyProjectName\\UploadData\\images
#壓縮比例
message.scaleRatio=0.20f
#圖片類型
message.imageType=png,jpg,jpeg
3:新建 MessageProperties 類,對應(yīng) file-message.properties 配置文件
@Component
@ConfigurationProperties(prefix="message")
@PropertySource("classpath:file-message.properties")
public class MessageProperties {
private long fileSize; //壓縮大小
private double scaleRatio; //壓縮比例
private String upPath; //保存路徑
private String imageType; //圖片類型
public long getFileSize() {
return fileSize;
}
public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}
public double getScaleRatio() {
return scaleRatio;
}
public void setScaleRatio(double scaleRatio) {
this.scaleRatio = scaleRatio;
}
public String getUpPath() {
return upPath;
}
public void setUpPath(String upPath) {
this.upPath = upPath;
}
public String getImageType() {
return imageType;
}
public void setImageType(String imageType) {
this.imageType = imageType;
}
}
@PropertySource("classpath:file-message.properties")對應(yīng)第二步配置文件的名稱
當(dāng)然也可以不新建 file-message.properties 文件衅金, file-message.properties 文件里的內(nèi)容可以直接寫在 application.properties 配置文件中耳幢,那MessageProperties 類就應(yīng)該按下面這種寫法:
@Component
public class MessageProperties {
@Value("${fileSize}")
private long fileSize; //壓縮大小
@Value("${scaleRatio}")
private double scaleRatio; //壓縮比例
@Value("${MDDIMG_LOCATION}")
private String upPath; //保存路徑
@Value("${imageType}")
private String imageType; //圖片類型
...
}
4:service層接口
public interface FileUpAndDownService {
Map<String, Object> uploadPicture(MultipartFile file) throws ServiceException;
}
5:service層接口實現(xiàn)
@Service
public class FileUpAndDownServiceImpl implements FileUpAndDownService {
@Autowired
private MessageProperties config; //用來獲取file-message.properties配置文件中的信息
@Override
public Map<String, Object> uploadPicture(MultipartFile file) throws ServiceException {
try {
Map<String, Object> resMap = new HashMap<>();
String[] IMAGE_TYPE = config.getImageType().split(",");
String path = null;
boolean flag = false;
for (String type : IMAGE_TYPE) {
if (StringUtils.endsWithIgnoreCase(file.getOriginalFilename(), type)) {
flag = true;
break;
}
}
if (flag) {
resMap.put("result", IStatusMessage.SystemStatus.SUCCESS.getMessage());
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
// 獲得文件類型
String fileType = file.getContentType();
// 獲得文件后綴名稱
String imageName = fileType.substring(fileType.indexOf("/") + 1);
// 原名稱
String oldFileName = file.getOriginalFilename();
// 新名稱
String newFileName = uuid + "." + imageName;
// 年月日文件夾
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String basedir = sdf.format(new Date());
// 進(jìn)行壓縮(大于4M)
if (file.getSize() > config.getFileSize()) {
// 重新生成
String newUUID = UUID.randomUUID().toString().replaceAll("-", "");
newFileName = newUUID + "." + imageName;
path = config.getUpPath() + "/" + basedir + "/" + newUUID + "." + imageName;
// 如果目錄不存在則創(chuàng)建目錄
File oldFile = new File(path);
if (!oldFile.exists()) {
oldFile.mkdirs();
}
file.transferTo(oldFile);
// 壓縮圖片
Thumbnails.of(oldFile).scale(config.getScaleRatio()).toFile(path);
// 顯示路徑
resMap.put("path", "/" + basedir + "/" + newUUID + "." + imageName);
} else {
path = config.getUpPath() + "/" + basedir + "/" + uuid + "." + imageName;
// 如果目錄不存在則創(chuàng)建目錄
File uploadFile = new File(path);
if (!uploadFile.exists()) {
uploadFile.mkdirs();
}
file.transferTo(uploadFile);
// 顯示路徑
resMap.put("path", "/" + basedir + "/" + uuid + "." + imageName);
}
resMap.put("oldFileName", oldFileName);
resMap.put("newFileName", newFileName);
resMap.put("fileSize", file.getSize());
} else {
resMap.put("result", "圖片格式不正確,支持png|jpg|jpeg");
}
return resMap;
} catch (Exception e) {
e.printStackTrace();
throw new ServiceException(e.getMessage());
}
}
}
6:Controller層的實現(xiàn)
@Controller
@RequestMapping("/upload")
public class FileUploadController {
private static final Logger LOGGER = LoggerFactory.getLogger(FileUploadController.class);
@Autowired
private FileUpAndDownService fileUpAndDownService;
@RequestMapping(value = "/setFileUpload", method = RequestMethod.POST)
@ResponseBody
public ResponseResult setFileUpload(@RequestParam(value = "file", required = false) MultipartFile file) {
ResponseResult result = new ResponseResult();
try {
Map<String, Object> resultMap = upload(file);
if (!IStatusMessage.SystemStatus.SUCCESS.getMessage().equals(resultMap.get("result"))) {
result.setCode(IStatusMessage.SystemStatus.PARAM_ERROR.getCode());
result.setMessage((String) resultMap.get("msg"));
return result;
}
result.setData(resultMap);
} catch (ServiceException e) {
e.printStackTrace();
LOGGER.error(">>>>>>圖片上傳異常考传,e={}", e.getMessage());
result.setCode(IStatusMessage.SystemStatus.ERROR.getCode());
result.setMessage(IStatusMessage.FILE_UPLOAD_ERROR);
}
return result;
}
private Map<String, Object> upload(MultipartFile file) throws ServiceException {
Map<String, Object> returnMap = new HashMap<>();
try {
if (!file.isEmpty()) {
Map<String, Object> picMap = fileUpAndDownService.uploadPicture(file);
if (IStatusMessage.SystemStatus.SUCCESS.getMessage().equals(picMap.get("result"))) {
return picMap;
} else {
returnMap.put("result", IStatusMessage.SystemStatus.ERROR.getMessage());
returnMap.put("msg", picMap.get("result"));
}
} else {
LOGGER.info(">>>>>>上傳圖片為空文件");
returnMap.put("result", IStatusMessage.SystemStatus.ERROR.getMessage());
returnMap.put("msg", IStatusMessage.FILE_UPLOAD_NULL);
}
} catch (Exception e) {
e.printStackTrace();
throw new ServiceException(IStatusMessage.FILE_UPLOAD_ERROR);
}
return returnMap;
}
}
7:springboot項目中還需要添加下面一段代碼到Application啟動類中
@SpringBootApplication
//exclude表示自動配置時不包括Multipart配置
@EnableAutoConfiguration(exclude = {MultipartAutoConfiguration.class})
public class StartApplication {
public static void main(String[] args) {
...
}
/**
* 顯示聲明CommonsMultipartResolver為mutipartResolver
*/
@Bean(name = "multipartResolver")
public MultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
//resolver.setDefaultEncoding("UTF-8");
//resolveLazily屬性啟用是為了推遲文件解析,以在在UploadAction中捕獲文件大小異常
resolver.setResolveLazily(true);
resolver.setMaxInMemorySize(40960);
resolver.setMaxUploadSize(3 * 1024 * 1024);//上傳文件大小 3M 3*1024*1024
return resolver;
}
}
頂部 @EnableAutoConfiguration(exclude = {MultipartAutoConfiguration.class}) 注解不要忘了
這兩段代碼不加的話奥邮,可能會造成圖片上傳成文件夾形式浇衬,上傳失敗峭范!
8:前端HTML界面,直接使用layui
HTML:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<link rel="stylesheet" href="/js/layui/css/layui.css"/>
<script type="text/javascript" src="/js/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="/js/layui/layui.js"></script>
<script type="text/javascript" src="/js/index.js"></script>
<button type="button" class="layui-btn" id="uploadBtn">
<i class="layui-icon"></i>上傳
</button>
</body>
</html>
JS:
layui.use('upload', function () {
var upload = layui.upload;
//執(zhí)行實例
var uploadInst = upload.render({
elem: '#uploadBtn' //綁定元素
, url: '/upload/setFileUpload' //上傳接口
, multiple: true
, before: function (obj) {
//可設(shè)置回顯
console.log(obj)
}
, done: function (res) {
console.log(res);
//上傳完畢回調(diào)
if (res.code != 1000) {
return layer.msg('上傳失敗');
} else {
return layer.msg('上傳成功');
}
}
, error: function () {
//請求異潮窦回調(diào)
}
});
});
上傳成功后會返回如下信息:
上傳失斏纯亍:
ServiceException為自定義接口異常處理:
public class ServiceException extends Exception {
public ServiceException() {
super();
}
public ServiceException(String message){
super(message);
}
public ServiceException(Throwable throwable){
super(throwable);
}
public ServiceException(String message ,Throwable throwable){
super(message, throwable);
}
}
IStatusMessage為自定義響應(yīng)狀態(tài)信息枚舉類:
public interface IStatusMessage {
String getCode();
String getMessage();
enum SystemStatus implements IStatusMessage {
SUCCESS("1000", "操作成功"), //請求成功
ERROR("1001", "網(wǎng)絡(luò)異常,請稍后重試~"),
FILE_UPLOAD_NULL("1002","上傳圖片為空文件"), ; //請求失敗
private String code;
private String message;
SystemStatus(String code, String message) {
this.code = code;
this.message = message;
}
public String getCode() {
return this.code;
}
public String getMessage() {
return this.message;
}
}
}
ResponseResult前端響應(yīng)結(jié)果類:
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
public class ResponseResult implements Serializable {
private static final long serialVersionUID = -148117940294941578L;
private String code;
private String message;
private Object obj;
private Map<String,Object> data; //默認(rèn)為hashMap,也可為對象
public String getCode() {
return code;
}
public ResponseResult() {
this.code = IStatusMessage.SystemStatus.SUCCESS.getCode();
this.message = IStatusMessage.SystemStatus.SUCCESS.getMessage();
}
public ResponseResult(IStatusMessage statusMessage){
this.code = statusMessage.getCode();
this.message = statusMessage.getMessage();
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
public Map<String,Object> getData() {
return data;
}
public void setData(Map<String,Object> data) {
this.data = data;
}
public void putData(String key,Object value){
if( this. data == null ){
this.data = new HashMap<String,Object>();
}
this.data.put(key, value);
}
}