1.创建一个springboot项目
maven如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sunyue</groupId>
<artifactId>my_blog</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>my_blog</name>
<description></description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<relativePath></relativePath> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--文件压缩-->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
<!--markdown-->
<dependency>
<groupId>com.vladsch.flexmark</groupId>
<artifactId>flexmark-all</artifactId>
<version>0.50.42</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--热部署插件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.22</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<!--upload-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.sunyue.myblog.MyblogApplication</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.5</version>
<configuration>
<configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>3.4.4</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
2.创建一个控制层FileController
package com.sunyue.myblog.controller;
import com.sunyue.myblog.commons.EmptyUtil;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* 文件上传
*/
@CrossOrigin
@Controller
public class FileController {
// 获取配置文件中图片的路径
@Value("${cbs.imagesPath}")
private String UPLOADED_FOLDER;
/*
* 以下全为相对路径*/
//本地图片地址
//private static String UPLOADED_FOLDER = "src/main/resources/static/upload/";
//jar包方式部署服务器地址
//private static String UPLOADED_FOLDER = "upload/";
//docker-compose方式部署服务器地址
//private static String UPLOADED_FOLDER = "src/main/resources/static/upload/";
@GetMapping(value = "/file")
public String file() {
return "fileup";
}
private Map<String, Object> deleteFileUtil(String params) {
/*进来的是一个/images/5770871d-3e20-4f62-804e-f17f0ac0d562.jpg虚拟地址,对应实际地址需要截取处理*/
params = params.substring(params.lastIndexOf("/") + 1);
Map<String, Object> map = new HashMap<String, Object>();
String url = UPLOADED_FOLDER + params;
//获取相对路径暂时弃用
//File file = new File(url);
//String path = file.getAbsolutePath();
File filedel = new File(url);
if (!filedel.exists()) {
map.put("success", 0);
map.put("message", "文件不存在!");
} else {
map.put("success", 1);
map.put("message", "删除成功!");
filedel.delete();
}
return map;
}
private Map<String, Object> uploadFileUtil(MultipartFile file) {
Map<String, Object> map = new HashMap<String, Object>();
if (file.isEmpty()) {
map.put("success", 0);
map.put("message", "文件不存在");
return map;
}
// 后缀名...不需要后缀名在压缩操作中加入,如果没有压缩操作则需要但是文章插图时有个校验需要删除存在问题
//String fileName = file.getOriginalFilename(); // 文件名
//String suffixName = fileName.substring(fileName.lastIndexOf("."));
//fileName = UUID.randomUUID() + suffixName; // 新文件名
File fileDir = new File(UPLOADED_FOLDER);
String fileName = UUID.randomUUID().toString();
if (!fileDir.exists()) {
fileDir.mkdir();
}
try {
try {
/*先尝试压缩并保存图片*/
Thumbnails.of(file.getInputStream()).scale(0.5f)
.outputQuality(0.8)
//全部输出为jpg格式
.outputFormat("jpg")
.toFile(UPLOADED_FOLDER + "/" + fileName);
} catch (IOException e) {
}
/*不压缩文件如下*/
//file.transferTo(new File(path, fileName));
map.put("success", 1);
map.put("message", "上传成功!");
//上面压缩的所有后缀名都为jpg
map.put("url", "/images/" + fileName+".jpg");
/*这样也可以*/
//map.put("url", "../images/" + fileName);
} catch (
Exception e) {
map.put("success", 0);
map.put("message", "上传失败!");
e.printStackTrace();
}
return map;
}
@ResponseBody
@RequestMapping(value = "/fileUpload", method = RequestMethod.POST)
public Map<String, Object> FileUpload(@RequestParam("file") MultipartFile file) {
return uploadFileUtil(file);
}
@ResponseBody
@RequestMapping(value = "/fileUpdate", method = RequestMethod.POST)
public Map<String, Object> FileUpload1(@RequestParam("file") MultipartFile file, @RequestParam String params) {
Map map = new HashMap<String, Object>();
params = params.substring(params.lastIndexOf("/") + 1);
if (EmptyUtil.isEmpty(params)) {
map.put("success", 0);
map.put("message", "路径为空!");
} else {
map = deleteFileUtil(params);
}
map = uploadFileUtil(file);
return map;
}
@ResponseBody
@RequestMapping(value = "/fileDelete", method = RequestMethod.POST)
public Object FileDelete(HttpServletRequest request) {
String params = request.getParameter("params");
Map map = new HashMap<String, Object>();
if (EmptyUtil.isEmpty(params)) {
map.put("success", 0);
map.put("message", "路径为空!");
}
map = deleteFileUtil(params);
return map;
}
@ResponseBody
@RequestMapping(value = "/markdown", method = RequestMethod.POST)
public Map<String, Object> demo(@RequestParam(value = "editormd-image-file", required = false) MultipartFile file, HttpServletRequest request) {
return uploadFileUtil(file);
}
}
3.创建MyWebAppConfigurer 这里是配置资源映射路径
package com.sunyue.myblog;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
/**
* 资源映射路径
*/
@Configuration
public class MyWebAppConfigurer implements WebMvcConfigurer {
//跨域
/* @Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/index").setViewName("index");
}*/
/* @Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/upload/**").addResourceLocations("file:F:/img/");
}*/
// 获取配置文件中图片的路径
@Value("${cbs.imagesPath}")
private String mImagesPath;
// 访问图片方法
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//埋个坑,上线时判断路径用
String os = System.getProperty("os.name");
if (os.toLowerCase().startsWith("win")) { //如果是Windows系统
if (mImagesPath.equals("") || mImagesPath.equals("${cbs.imagesPath}")) {
String imagesPath = MyWebAppConfigurer.class.getClassLoader().getResource("").getPath();
if (imagesPath.indexOf(".jar") > 0) {
imagesPath = imagesPath.substring(0, imagesPath.indexOf(".jar"));
} else if (imagesPath.indexOf("classes") > 0) {
imagesPath = "file:" + imagesPath.substring(0, imagesPath.indexOf("classes"));
}
imagesPath = imagesPath.substring(0, imagesPath.lastIndexOf("/")) + "/images/";
mImagesPath = imagesPath;
}
LoggerFactory.getLogger(MyWebAppConfigurer.class).info("imagesPath1=" + mImagesPath);
//这个地方也只能是绝对路径
registry.addResourceHandler("/images/**").addResourceLocations("file:" + mImagesPath);
WebMvcConfigurer.super.addResourceHandlers(registry);
} else { //linux 和mac
// imagesPath2=/home/sunyue/docker/upload/
LoggerFactory.getLogger(MyWebAppConfigurer.class).info("imagesPath=" + mImagesPath);
//registry.addResourceHandler("/images/**").addResourceLocations(mImagesPath);
//绝对路径
registry.addResourceHandler("/images/**").addResourceLocations("file:" + mImagesPath);
WebMvcConfigurer.super.addResourceHandlers(registry);
}
}
}
4.前端模板文件
<div class="am-form-group">
<label for="userPhoto" class="am-u-sm-12 am-form-label am-text-left">用户头像
<span class="tpl-form-line-small-title">Images</span></label>
<div class="am-u-sm-12 am-margin-top-xs">
<input type="file" id="file" name="file" style="color: #ff5b67">
<input style="margin: 10px 0" type="button" id="upload" value="上传" class="am-btn-secondary">
<input style="margin: 10px 2px" type="button" id="cancel" value="取消" class="am-btn-danger">
<div class="am-form-group am-form-file">
<input type="text" id="userPhoto" name="userPhoto"
th:value="${user.userPhoto}"
class="tpl-form-input am-margin-top-xs" placeholder="图片地址"
readonly="readonly">
</div>
</div>
</div>
5.js:
<script type="text/javascript">
$(function () {
/*上传文件*/
$("#upload").click(function () {
var form = new FormData();
form.append("file", document.getElementById("file").files[0]);
$.ajax({
url: "/fileUpload", //后台url
data: form,
cache: false,
async: false,
type: "POST", //类型,POST或者GET
dataType: "json", //数据返回类型,可以是xml、json等
processData: false,
contentType: false,
enctype: 'multipart/form-data',
success: function (data) { //成功,回调函数
if (data.success == 1) {
$("#url img").attr("src", data.url);
$("#userPhoto").val(data.url);
$("#url1").html(data.url);
alert("图片上传成功!")
} else {
alert("上传失败");
}
},
error: function (er) {
alert(er);//失败,回调函数
}
});
});
/*取消上传文件*/
$("#cancel").click(function () {
var params = $("#userPhoto").val();
$.ajax({
url: "/fileDelete/?params=" + params,
type: "POST",
contentType: "application/json",//一定要加的属性
dataType: "json",
success: function (data) {
//data是服务器返回的数据
if (data.success == 1) {
$("#userPhoto").val("");
}
alert(data.message);
},
error: function (e) {
alert(e);//异常信息
}
});
});
});
</script>
6.配置文件application.properties:
#是否启用文件上传功能
spring.servlet.multipart.enabled=true
#指定文件写入磁盘后的阈值,默认为0
spring.servlet.multipart.file-size-threshold=0
#指定上传文件大小, 默认1M
spring.servlet.multipart.max-file-size=50Mb
#指定multipart / form-data请求允许的最大大小, 默认10M
spring.servlet.multipart.max-request-size=100Mb
#是否在文件或参数访问时懒惰地解析多部分请求
spring.servlet.multipart.resolve-lazily=false
#项目相对目录:classpath:static.upload
#本地绝对目录:file: 表示window的路径
cbs.imagesPath=D:/Javaweb/myblog/src/main/resources/static/upload/
#服务器端cbs.imagesPath=/home/ubuntu/web/upload/
#以下相对路径,在win这个也可以但是有几秒钟延迟
##cbs.imagesPath=classpath:/static/upload/