一、前端上传界面代码
<form action="/ajax/pluginJarInfo/fileUpload" id="jarUpload" method="post"
enctype="multipart/form-data">
<div class="uploadJarFile">
<input type="file" name="file" value="选择文件">
<input type="button" class="btn btn-success pull-right" value="上传" id="jar_submit">
</div>
</form>
注:enctype需要指定,指定为multipart/form-data;
二、js代码
此处是通过ajax来调用后端上传接口,代码如下
$("#jar_submit").click(function () {
var formData = new FormData($("#jarUpload")[0]);
var id = $("#pluginId").html();
formData.append("pluginId", id);
$.ajax({
url: "/ajax/pluginJarInfo/fileUpload",
type: "post",
data: formData,
dataType: "json",
processData: false,
contentType: false,
success: function (res) {
window.location.reload()
}
})
})
注:因为我后端上传接口有两个参数,一个是file,一个是pluginId。所以这里用formData进行了参数的封装。如果只有一个file参数,那么只需 var formData = new FormData($("#jarUpload")[0]);即可
三、后端controller代码
@RestController
@RequestMapping(value = "/ajax/pluginJarInfo")
public class AjaxPluginVersionInfoController {
@Resource
private PluginVersionInfoService pluginVersionInfoService;
@Value("${jar.store.path}") //这个是将jar包存放在服务端的路径,此处我配置的是"store/"
private String jarStorePath;
@PostMapping("/fileUpload")
public AjaxBaseResult fileUpload(@RequestParam(value = "file") MultipartFile file,
@RequestParam Integer pluginId)
throws IOException, HerculesException {
//获取上传文件的文件名称
String filename = file.getOriginalFilename();
//获取存储路径
String path = new File(jarStorePath).getAbsolutePath() + "/" + filename;
File dest = new File(path);
//判断这个存储路径是否存在,不存在就创建
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
//将jar包写入到服务端指定路径下,此处是store/XXX.jar
file.transferTo(dest);
//调用service将jar包上传到hdfs,pluginId是插件id可忽略,path是现在jar包所在服务端的路径
Integer id = pluginVersionInfoService.uploadJar(pluginId, path);
return AjaxBaseResult.success(id);
}
}
四、核心上传jar到hdfs代码在如下工具包内
package com.zdww.hercules.web.util;
import com.zdww.hercules.web.common.ErrorCode;
import com.zdww.hercules.web.constant.PluginJarConstant;
import com.zdww.hercules.web.exception.HerculesException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.log4j.Logger;
/**
* @author zhanguolin
* @PackageName:com.zgl.mybatis_test.util
* @className:PluginJarUtil
* @date 2020/10/13 10:30
* @Description
*/
public class PluginJarUtil {
private static final Logger logger = Logger.getLogger(PluginJarUtil.class);
/**
* hadoop的配置中心
*/
private static Configuration configuration;
/**
* 初始化hadoop配置
*
* @param defaultFs hdfs文件路径
*/
public static void init(String defaultFs) {
if (null == configuration) {
configuration = new Configuration();
configuration.set("fs.defaultFS", defaultFs);
//设置操作用户为root,否则可能在本地运行时会报没有权限
System.setProperty("HADOOP_USER_NAME", "root");
}
}
/**
* 上传jar包到hdfs
*
* @param filePath 待上传jar的路径
* @param outputPath 上传到hdfs的路径
*/
public static void uploadPluginJar(String filePath, String outputPath){
FileSystem fs = getFs();
try {
fs.copyFromLocalFile(new Path(filePath), new Path(outputPath));
} catch (IOException e) {
logger.error(String.format("upload `%s` jar is failed !", filePath));
} finally {
closeFs(fs);
}
}
/**
* 删除hdfs上的jar
*
* @param jarPath 待删除jar的路径
*/
public static void deletePluginJar(String jarPath) {
FileSystem fs = getFs();
try {
fs.delete(new Path(jarPath), Boolean.TRUE);
} catch (IOException e) {
logger.error(String.format("delete `%s` jar is failed !", jarPath));
} finally {
closeFs(fs);
}
}
/**
* 修改hdfs上的文件名称 此处简单实现了个重试的方法,重试三次
*
* @param oldName 待修改的名称
* @param newName 需要更换的名称
*/
public static void renamePluginJar(String oldName, String newName) {
FileSystem fs = getFs();
int retryCount = 0;
boolean flag = false;
while (retryCount < 3) {
try {
fs.rename(new Path(oldName), new Path(newName));
flag = true;
break;
} catch (IOException e) {
logger.error(String
.format("rename `%s` jar to `%s` is failed ! start retry `%d`", oldName,
newName,
retryCount));
}
retryCount++;
}
closeFs(fs);
}
/**
* 移动hdfs上的jar
*
* @param oldPath jar包之前所在的路径
* @param newPath 需要移动到的路径
*/
public static void movePluginJar(String oldPath, String newPath) {
renamePluginJar(oldPath, newPath);
}
/**
* 获取操作文件系统
*
* @return 文件系统
*/
private static FileSystem getFs() {
FileSystem fs = null;
try {
fs = FileSystem.get(configuration);
} catch (IOException e) {
logger.error("get fileSystem is failed !");
}
return fs;
}
/**
* 关闭文件流资源
*
* @param fs 文件系统
*/
private static void closeFs(FileSystem fs) {
try {
if (null != fs) {
fs.close();
}
} catch (IOException e) {
logger.error("close fileSystem is failed !");
}
}
}
五、小结
这片博客主要是记录下自己的笔记,有不对的可以指出。整个流程的实现思路是先将jar包上传到服务端指定的目录,再调如上四中的工具类将jar包上传到hdfs。