目次
3.3.1 JarBasePath.getBaseJarPathStr()
3.2 FileUploadUtils.upload(filePath, file) --ruoyi フレームワークには付属しています
4. 設定 -- 設定ファイルをローカルの場所にアップロードおよびダウンロードします (これもめまいがします)
5. サービスと XML は記述されていないため、ほとんど価値がありません
単一ファイルのアップロード
1、html
<!-- 注意,这个文件的上传和下载功能一定要放在一个form里方便处理-->
<form class="form-horizontal m" id="form-checkCarPhoto-show" th:object="${CarPhoto}">
<input id="id" name="id" th:field="*{id}" type="hidden">
<!-- 单文件上传按钮-->
<input id="filePath" name="filePath" class="form-control" type="file">
<a class="btn btn-success btn-xs " href="#" onclick="uploadFile()"><i class="fa fa-edit"></i>单文件上传</a>
<!-- 多文件打包下载按钮-->
<a class="btn btn-success btn-xs " href="#" onclick="downloadFile($('#id').val())"><i class="fa fa-edit"></i>全部下载</a>
</form>
2、JS
function uploadFile() {
var formData = new FormData(); //定义上传文件
if ($('#filePath')[0].files[0] == null) { //判断文件是否为空
$.modal.alertWarning("请先选择文件路径");
return false;
}
formData.append('fileName', $("#fileName").val()); //放入文件名
formData.append('file', $('#filePath')[0].files[0]); //放入文件地址
$.ajax({
url: prefix + "/add/"+$('#id').val() , //controller文件映射,依据自己定义的写
type: 'post',
cache: false,
data: formData,
processData: false, //Jquery是否会序列化数据
//contentType:发送信息至服务器时内容编码类型(告诉服务器从浏览器提交过来的数据格式)
// 默认值为contentType = "application/x-www-form-urlencoded"
// 在 ajax 中 contentType 设置为 false 是为了避免 JQuery 对其操作,从而失去分界符,而使服务器不能正常解析文件。
contentType: false,
dataType: "json",
success: function(result) {
$.operate.successCallback(result);
}
});
}
3、コントローラー
@PostMapping("/add/{cid}")
@ResponseBody
public AjaxResult addSave(@PathVariable("cid") Integer cid, @RequestParam("file") MultipartFile file, FileInfo fileInfo) throws IOException
{
// 上传文件路径
String filePath = Global.getProfile() + "check/";
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
CarPhoto carPhoto = new CarPhoto();
carPhoto.setPhotoUrl(fileName);
carPhoto.setCheckId(cid);
// 插入数据并返回结果至前端
return toAjax(carPhotoService.insertCarPhoto(carPhoto));
}
3.1 Global.getProfile()
package com.bloodmanage.common.config;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import com.bloodmanage.common.utils.http.JarBasePath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.bloodmanage.common.utils.StringUtils;
import com.bloodmanage.common.utils.YamlUtil;
/**
* 全局配置类
*
* @author songzihao
*/
public class Global
{
private static final Logger log = LoggerFactory.getLogger(Global.class);
private static JarBasePath jarBasePath = new JarBasePath();
private static String NAME = "application.yml";
/**
* 当前对象实例
*/
private static Global global = null;
/**
* 保存全局属性值
*/
private static Map<String, String> map = new HashMap<String, String>();
private Global()
{
}
/**
* 静态工厂方法 获取当前对象实例 多线程安全单例模式(使用双重同步锁)
*/
public static synchronized Global getInstance()
{
if (global == null)
{
synchronized (Global.class)
{
if (global == null)
global = new Global();
}
}
return global;
}
/**
* 获取配置
*/
public static String getConfig(String key)
{
String value = map.get(key);
if (value == null)
{
Map<?, ?> yamlMap = null;
try
{
yamlMap = YamlUtil.loadYaml(NAME);
value = String.valueOf(YamlUtil.getProperty(yamlMap, key));
map.put(key, value != null ? value : StringUtils.EMPTY);
}
catch (FileNotFoundException e)
{
log.error("获取全局配置异常 {}", key);
}
}
return value;
}
/**
* 获取文件上传路径
*/
public static String getProfile()
{
//return getAbsolute() + File.separator + getConfig("blood.profile");
return jarBasePath.getBaseJarPathStr();
}
/**
* 获取头像上传路径
*/
public static String getAvatarPath()
{
//String path = getAbsolute() + File.separator + getConfig("blood.profile") + File.separator + "avatar/";
//return path;
return jarBasePath.getBaseJarPathStr() + "avatar/";
}
/**
* 获取下载上传路径
*/
public static String getDownloadPath()
{
//return getAbsolute() + File.separator + getConfig("blood.profile") + File.separator + "download/";
//return getConfig("blood.profile") + "download/";
return jarBasePath.getBaseJarPathStr()+"download/";
}
/**
* 获取jar包的目录
* @return
*/
private static String getAbsolute() {
String jarWholePath = Global.class.getProtectionDomain().getCodeSource().getLocation().getFile();
try {
jarWholePath = java.net.URLDecoder.decode(jarWholePath, "UTF-8");
} catch (UnsupportedEncodingException e) { System.out.println(e.toString()); }
String jarPath = new File(jarWholePath).getParentFile().getAbsolutePath();
jarPath = jarPath.substring(0, jarPath.indexOf("bloodmanage"));
return jarPath;
}
}
3.3.1 JarBasePath.getBaseJarPathStr()
public class JarBasePath {
private static final Logger log = LoggerFactory.getLogger(JarBasePath.class);
/**
* 获取当前jar包所在系统中的目录
*/
public File getBaseJarPath() {
ApplicationHome home = new ApplicationHome(getClass());
File jarFile = home.getSource();
return jarFile.getParentFile();
}
public String getBaseJarPathStr() {
File file = getBaseJarPath();
return file.getAbsolutePath().toLowerCase().trim() + "/";
}
}
3.2 FileUploadUtils.upload(filePath, file) --ruoyi フレームワークには付属しています
package com.bloodmanage.framework.util;
import java.io.File;
import java.io.IOException;
import org.apache.tomcat.util.http.fileupload.FileUploadBase.FileSizeLimitExceededException;
import org.springframework.web.multipart.MultipartFile;
import com.bloodmanage.common.config.Global;
import com.bloodmanage.common.exception.file.FileNameLengthLimitExceededException;
import com.bloodmanage.common.utils.Md5Utils;
/**
* 文件上传工具类
*
* @author xing
*/
public class FileUploadUtils
{
/**
* 默认大小 50M
*/
public static final long DEFAULT_MAX_SIZE = 52428800;
/**
* 默认上传的地址
*/
private static String defaultBaseDir = Global.getProfile();
/**
* 默认的文件名最大长度
*/
public static final int DEFAULT_FILE_NAME_LENGTH = 200;
/**
* 默认文件类型jpg
*/
public static final String IMAGE_JPG_EXTENSION = ".jpg";
private static int counter = 0;
public static void setDefaultBaseDir(String defaultBaseDir)
{
FileUploadUtils.defaultBaseDir = defaultBaseDir;
}
public static String getDefaultBaseDir()
{
return defaultBaseDir;
}
/**
* 以默认配置进行文件上传
*
* @param file 上传的文件
* @return 文件名称
* @throws Exception
*/
public static final String upload(MultipartFile file) throws IOException
{
try
{
return upload(getDefaultBaseDir(), file, FileUploadUtils.IMAGE_JPG_EXTENSION);
}
catch (Exception e)
{
throw new IOException(e);
}
}
/**
* 根据文件路径上传
*
* @param baseDir 相对应用的基目录
* @param file 上传的文件
* @return 文件名称
* @throws IOException
*/
public static final String upload(String baseDir, MultipartFile file) throws IOException
{
try
{
return upload(baseDir, file, FileUploadUtils.IMAGE_JPG_EXTENSION);
}
catch (Exception e)
{
throw new IOException(e);
}
}
/**
* 文件上传
*
* @param baseDir 相对应用的基目录
* @param file 上传的文件
* @param needDatePathAndRandomName 是否需要日期目录和随机文件名前缀
* @param extension 上传文件类型
* @return 返回上传成功的文件名
* @throws FileSizeLimitExceededException 如果超出最大大小
* @throws FileNameLengthLimitExceededException 文件名太长
* @throws IOException 比如读写文件出错时
*/
public static final String upload(String baseDir, MultipartFile file, String extension)
throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException
{
int fileNamelength = file.getOriginalFilename().length();
if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
{
throw new FileNameLengthLimitExceededException(file.getOriginalFilename(), fileNamelength,
FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
}
assertAllowed(file);
String fileName = encodingFilename(file.getOriginalFilename(), extension);
File desc = getAbsoluteFile(baseDir, baseDir + fileName);
file.transferTo(desc);
return fileName;
}
private static final File getAbsoluteFile(String uploadDir, String filename) throws IOException
{
File desc = new File(File.separator + filename);
if (!desc.getParentFile().exists())
{
desc.getParentFile().mkdirs();
}
if (!desc.exists())
{
desc.createNewFile();
}
return desc;
}
/**
* 编码文件名
*/
private static final String encodingFilename(String filename, String extension)
{
filename = filename.replace("_", " ");
filename = Md5Utils.hash(filename + System.nanoTime() + counter++) + extension;
return filename;
}
/**
* 文件大小校验
*
* @param file 上传的文件
* @return
* @throws FileSizeLimitExceededException 如果超出最大大小
*/
public static final void assertAllowed(MultipartFile file) throws FileSizeLimitExceededException
{
long size = file.getSize();
if (DEFAULT_MAX_SIZE != -1 && size > DEFAULT_MAX_SIZE)
{
throw new FileSizeLimitExceededException("not allowed upload upload", size, DEFAULT_MAX_SIZE);
}
}
}
4. Service と XML は書く価値がない
複数ファイルのパッケージ化と圧縮パッケージのダウンロード
1、html
<!-- 注意,这个文件的上传和下载功能一定要放在一个form里方便处理-->
<form class="form-horizontal m" id="form-checkCarPhoto-show" th:object="${CarPhoto}">
<input id="id" name="id" th:field="*{id}" type="hidden">
<!-- 单文件上传按钮-->
<input id="filePath" name="filePath" class="form-control" type="file">
<a class="btn btn-success btn-xs " href="#" onclick="uploadFile()"><i class="fa fa-edit"></i>单文件上传</a>
<!-- 多文件打包下载按钮-->
<a class="btn btn-success btn-xs " href="#" onclick="downloadFile($('#id').val())"><i class="fa fa-edit"></i>全部下载</a>
</form>
2、JS
function downloadFile(value){
window.location.href = prefix + "/resource?id=" + value;
}
3、コントローラー
注: コレクションが空かどうかを判断するための isEmpty() と ==null の違いは、次の 2 つの方法で使用できます。
一:if(list!=null&&!list.isEmpty())
二:CollectionUtils.isEmpty()
詳細は記事「セットが空かどうかを判断する場合の isEmpty() と ==null の違い」を参照してください。
/**
* 本地资源通用下载
*/
@GetMapping("/resource")
@ResponseBody
public void resourceDownload(Integer id, HttpServletRequest request, HttpServletResponse response)
throws Exception
{
// 用id查照片列表
List<CarPhoto> photos = carPhotoService.selectCarPhotoListByCid(id);
//判断照片列表是否为空,注意:这样两种判断是为了避免空指针异常
if(photos == null || photos.isEmpty())
{
throw new ServiceException("0", "此条车检信息没有照片可以下载!");
}
// 用id查车检信息
CarCheck carCheck = carCheckService.selectCarCheckById(id);
DateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
// 时间格式化
String strdate = dateformat.format(carCheck.getCreateTime());
// 压缩包名字拼一拼
String zipName = carCheck.getDriverName() + '_'
+ carCheck.getCarStr() + '_'
+ strdate + '_'
+ "车检照片.zip";
// 下面就是百度搜来的压缩包操作了
ZipOutputStream zos = null;
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(zipName, "UTF-8"));
zos = new ZipOutputStream(response.getOutputStream());
downloadTolocal(zos, photos);
}
/**
* 本地资源压缩为zip
*/
private void downloadTolocal(ZipOutputStream zos, List<CarPhoto> photos) throws IOException {
InputStream input = null;
// 本地资源路径
String localPath = Global.getProfile() + "check/";
String downloadPath = "";
for (CarPhoto photo : photos) {
downloadPath = localPath + photo.getPhotoUrl();
File file = new File(downloadPath);
// 一个文件对应一个ZipEntry
ZipEntry zipEntry = new ZipEntry(file.getName());
input = new FileInputStream(file);
zos.putNextEntry(zipEntry);
IOUtils.copy(input, zos);
}
zos.close();
input.close();
}
4. 設定 -- 設定ファイルをローカルの場所にアップロードおよびダウンロードします (これもめまいがします)
package com.bloodmanage.framework.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.bloodmanage.common.config.Global;
/**
* 通用配置
*
* @author xing
*/
@Configuration
public class ResourcesConfig implements WebMvcConfigurer
{
/**
* 首页地址
*/
@Value("${shiro.user.indexUrl}")
private String indexUrl;
/**
* 默认首页的设置,当输入域名是可以自动跳转到默认指定的网页
*/
@Override
public void addViewControllers(ViewControllerRegistry registry)
{
registry.addViewController("/").setViewName("forward:" + indexUrl);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
/** 文件上传路径 */
registry.addResourceHandler("/profile/**").addResourceLocations("file:///" + Global.getAvatarPath());
registry.addResourceHandler("/check/**").addResourceLocations("file:///" + Global.getProfile() + "check/");
/** swagger配置 */
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}