一、前端上传界面代码
<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 {@Resourceprivate 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.jarfile.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。