怎样将压缩文件上传到服务器上
前言: 由于项目api是一台服务器,upload也是一台服务器,所以整体思路就是
1,先将zip上传到upload服务器
2,在upload服务器上解压zip。
3,在upload服务器上处理解压的文件(基本上都是json string)
4,通过接口调用将json string传入到接口中,进行数据库的操作
一、html
<input id="discoverImg" type="file" name="" class="layui-input">
<input type='button' class="layui-btn layui-btn-primary" onclick="getImg()" value='生成图片'></input>
二、JS
function getImg(){
var zipUpdate = $("#zipId")[0].files[0];
var formData = new FormData();
formData.append("zipFile",zipUpdate);
uploadZip(formData,callback);
}
function uploadZip(formData, callback){
$.ajax({
url : '/uploadZip',
method : 'POST',
async: false,
processData: false,
contentType:false,
data : formData,
success : function(result) {
callback(result)
}
})
}
function callback(result){
if(result.resultCode==1){
var emojiName = $(".emojiName").val();
// var emojiPath = $(".emojiPath").val();
var emojiProfile = $(".emojiProfile").val();
var emojiEveryName = $(".emojiEveryName").val();
var emojiPath = JSON.stringify(result.data);//将data转化成json String
Common.invoke({
path : '/add',
data : {
'zipName':emojiName,
'zipPath':emojiPath,//json String
'zipProfile': emojiProfile,
'nameStr' :emojiEveryName
},
successMsg : "",
errorMsg : "",
successCb : function(result) {
}
},
errorCb : function(result) {
}
});
}
}
三、Java、
//一下代码主要是组装访问upload的request和解析结果
public static Map getUploadZipPath(String domain,MultipartFile multipartFile){
String newUrl=null;
Map mapImags = new HashMap();
try {
// 换行符
final String newLine = "\r\n";
final String boundaryPrefix = "--";
// 定义数据分隔线
String BOUNDARY = "========7d4a6d158c9";
// 服务器的域名
URL url = new URL(domain+"/upload/UploadZipServlet");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 设置为POST情
conn.setRequestMethod("POST");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 设置请求头参数
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("Charsert", "UTF-8");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
OutputStream out = new DataOutputStream(conn.getOutputStream());
// 上传文件
String fileRealName = multipartFile.getOriginalFilename();//获得原始文件名;
StringBuilder sb = new StringBuilder();
sb.append(boundaryPrefix);
sb.append(BOUNDARY);
sb.append(newLine);
// 文件参数,photo参数名可以随意修改
sb.append("Content-Disposition: form-data;name=\"file\";filename=\"" + fileRealName + "\"" + newLine);
sb.append("Content-Type:application/octet-stream");
// 参数头设置完以后需要两个换行,然后才是参数内容
sb.append(newLine);
sb.append(newLine);
// 将参数头的数据写入到输出流中
out.write(sb.toString().getBytes());
// 数据输入流,用于读取文件数据
DataInputStream in = new DataInputStream(multipartFile.getInputStream());
byte[] bufferOut = new byte[1024];
int bytes = 0;
// 每次读1KB数据,并且将文件数据写入到输出流中
while ((bytes = in.read(bufferOut)) != -1) {
out.write(bufferOut, 0, bytes);
}
// 最后添加换行
out.write(newLine.getBytes());
in.close();
// 定义最后数据分隔线,即--加上BOUNDARY再加上--。
byte[] end_data = (newLine + boundaryPrefix + BOUNDARY + boundaryPrefix + newLine).getBytes();
// 写上结尾标识
out.write(end_data);
out.flush();
out.close();
// 定义BufferedReader输入流来读取URL的响应
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
JSONObject resultObj = JSON.parseObject(reader.readLine());
JSONObject resultData= resultObj.getJSONObject("data");
if(null == resultData)
throw new ServiceException("源文件不存在");
JSONArray imagesData = resultData.getJSONArray("images");
JSONArray imagesDataOthers = resultData.getJSONArray("zip");
List zipImags = Lists.newArrayList();
List zip = Lists.newArrayList();
if (imagesData.size() > 0){
for(int i = 0; i< imagesData.size(); i++){
JSONObject imageData = imagesData.getJSONObject(i);
String newUrlO = imageData.getString("oUrl");
String newUrlT = imageData.getString("tUrl");
System.out.println(" upload new Url =====>"+newUrlO);
System.out.println(" upload new Url =====>"+newUrlT);
newUrl = newUrlO + "," + newUrlT;
zipImags.add(newUrl);
}
mapImags.put("imags",zipImags);
}
if(imagesDataOthers.size()>0){
JSONObject imageDataOthers = imagesDataOthers.getJSONObject(0);
String newUrlOthers = imageDataOthers.getString("oUrl");
zip.add(newUrlOthers);
mapImags.put("zip",zip);
}
} catch (Exception e) {
System.out.println("发送POST请求出现异常!" + e);
e.printStackTrace();
}
return mapImags;
}
//以下主要是一个uploadZip的servlet,我传的是一些图片的zip压缩,而且图图片有压缩的也有原图。主要的步骤就是在下面,精华。。。。
@WebServlet("/upload/UploadZipServlet")
public class UploadZipServlet extends BaseServlet {
private static final long serialVersionUID = 1L;
public UploadZipServlet() {
super();
}
@Override
protected JMessage hander(HttpServletRequest request, HttpServletResponse response) {
long start = System.currentTimeMillis();
DiskFileItemFactory factory = new DiskFileItemFactory(1000 * 1024 * 1024, new File(getSystemConfig().getuTemp()));
ServletFileUpload fileUpload = new ServletFileUpload(factory);
List<FileItem> multipart = null;
JMessage jMessage = null;
int totalCount = 0;
long userId = 0;
double validTime = 0;
try {
multipart = fileUpload.parseRequest(request);
for (FileItem item : multipart) {
if (item.isFormField()) {
if ("validTime".equals(item.getFieldName())) {
try {
validTime = Double.valueOf(item.getString());
} catch (NumberFormatException e) {
validTime = new Double(-1);
}
}
if ("userId".equals(item.getFieldName())) {
userId = Long.parseLong(item.getString());
}
} else {
if (item.getSize() > 0) {
totalCount++;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
if (null == multipart) {
jMessage = new JMessage(1020101, "表单解析失败");
}
else if (0 == totalCount) {
jMessage = new JMessage(1010101, "缺少上传文件");
}
if (null != jMessage)
return jMessage;
jMessage = defHander(multipart, userId, validTime);
int successCount = jMessage.getIntValue("success");
jMessage.put("total", totalCount);
jMessage.put("failure", totalCount - successCount);
jMessage.put("time", System.currentTimeMillis() - start);
return jMessage;
}
protected JMessage defHander(List<FileItem> multipart, long userId, double validTime) {
JMessage jMessage = null;
int successCount = 0;
String oUrl = null;
String tUrl = null;
List<UploadItem> images = Lists.newArrayList();
List<UploadItem> audios = Lists.newArrayList();
List<UploadItem> videos = Lists.newArrayList();
List<UploadItem> others = Lists.newArrayList();
for (FileItem item : multipart) {
UploadItem uploadItem;
if (item.isFormField() || item.getSize() < 1)
continue;
String oFileName = item.getName();
String formatName = ConfigUtils.getFormatName(oFileName);
String newFileName = ConfigUtils.getName(oFileName);
String fileName;
if (!StringUtils.isEmpty(newFileName) && !newFileName.equals(oFileName)) {
fileName = 32 == newFileName.length() ? oFileName : Joiner.on("").join(UUID.randomUUID().toString().replace("-", ""), ".", formatName);
} else {
fileName = oFileName;
}
/*String fileName = 32 == ConfigUtils.getName(oFileName).length() ? oFileName : Joiner.on("").join(UUID.randomUUID().toString().replace("-", ""), ".", formatName);*/
FileType fileType = getFileType(formatName);
File[] uploadPath = ConfigUtils.getUploadPath(userId, fileType);
File oFile = new File(uploadPath[0], fileName);
File tFile = new File(uploadPath[1], fileName);
try {
FileUtils.transfer(item.getInputStream(), oFile);
successCount++;
oUrl = getUrl(oFile);
if(ConfigUtils.getSystemConfig().isOsStatus()){
if (oUrl.contains(ConfigUtils.getSystemConfig().getDomain())){
String urlNewName = oUrl.replace(ConfigUtils.getSystemConfig().getDomain(),"");
String oUrlNew = FileOSUtil.uploadFile(oFile,urlNewName);
log("UploadServlet uploadEd OBS Other oUrl"+oUrlNew);
if (oUrlNew != null){
oUrl = oUrlNew;
}
}
}
uploadItem = new UploadItem(oFileName, oUrl,(byte) 1, null);
ResourcesDBUtils.saveFileUrl(1, oUrl, -1);
others.add(uploadItem);
log("UploadServlet uploadEd " + oUrl);
try {
ZipInputStream ZinO=new ZipInputStream(new FileInputStream(oFile.getPath()));
BufferedInputStream BinO=new BufferedInputStream(ZinO);
String ParentO=uploadPath[0].toString(); //输出路径(文件夹目录)
File fout=null;
ZipEntry entryO;
try {
while ((entryO = ZinO.getNextEntry()) != null && !entryO.isDirectory()) {
fout = new File(ParentO, entryO.getName());
if (!fout.exists()) {
(new File(fout.getParent())).mkdirs();
}
FileOutputStream outO = new FileOutputStream(fout);
BufferedOutputStream BoutO = new BufferedOutputStream(outO);
int b;
while ((b = BinO.read()) != -1) {
BoutO.write(b);
}
BoutO.close();
outO.close();
System.out.println(fout + "解压成功");
FileInputStream fileInputStream = new FileInputStream(fout);
MultipartFile multipartFile = new MockMultipartFile(fout.getName(), fout.getName(), ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
images = uploadImg(images,multipartFile,userId,validTime);
}
BinO.close();
ZinO.close();
} catch (Exception e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
uploadItem = new UploadItem(oFileName, null, (byte) 0, e.getMessage());
others.add(uploadItem);
}
}
Map<String, Object> data = new HashMap<String, Object>();
data.put("zip", others);
data.put("images", images);
jMessage = new JMessage(1, null, data);
jMessage.put("success", successCount);
return jMessage;
}
protected List<UploadItem> uploadImg(List<UploadItem> images,MultipartFile file, long userId, double validTime) {
String oUrl = null;
String tUrl = null;
String oFileName = file.getName();
String formatName = ConfigUtils.getFormatName(oFileName);
String newFileName = ConfigUtils.getName(oFileName);
String imgName;
if (!StringUtils.isEmpty(newFileName) && !newFileName.equals(oFileName)) {
imgName = 32 == newFileName.length() ? oFileName : Joiner.on("").join(UUID.randomUUID().toString().replace("-", ""), ".", formatName);
} else {
imgName = oFileName;
}
FileType imgType = getFileType(formatName);
File[] uploadImgPath = ConfigUtils.getUploadPath(userId, imgType);
File oFile = new File(uploadImgPath[0], imgName);
File tFile = new File(uploadImgPath[1], imgName);
UploadItem uploadItem;
try {
FileUtils.transfer(file.getInputStream(), oFile, tFile, formatName);
oUrl = getUrl(oFile);
tUrl = getUrl(tFile);
if(ConfigUtils.getSystemConfig().isOsStatus()){
if (oUrl.contains(ConfigUtils.getSystemConfig().getDomain())){
String urlNewName = oUrl.replace(ConfigUtils.getSystemConfig().getDomain(),"");
String oUrlNew = FileOSUtil.uploadFile(oFile,urlNewName);
log("UploadServlet uploadEd OBS oUrl "+oUrlNew);
if (oUrlNew != null){
oUrl = oUrlNew;
}
}
if (tUrl.contains(ConfigUtils.getSystemConfig().getDomain())){
String urlNewName = tUrl.replace(ConfigUtils.getSystemConfig().getDomain(),"");
String urlNew = FileOSUtil.uploadFile(tFile,urlNewName);
log("UploadServlet uploadEd OBS tUrl "+urlNew);
if (urlNew != null){
tUrl = urlNew;
}
}
}
ResourcesDBUtils.saveFileUrl(1, oUrl, validTime);
ResourcesDBUtils.saveFileUrl(1, tUrl, validTime);
log("UploadServlet uploadEd " + oUrl);
log("UploadServlet uploadEd " + tUrl);
uploadItem = new UploadItem(oFileName, oUrl, tUrl, (byte) 1, null);
} catch (Exception e) {
e.printStackTrace();
uploadItem = new UploadItem(oFileName, null, (byte) 0, e.getMessage());
}
images.add(uploadItem);
return images;
}
}
还有一个类,就是进行数据库的处理的接口
首先将json string转化成json object,之后自己就可以解析啦。。。
JSONObject json = JSONObject.parseObject(zipPath);
Map map = (Map)json;
进来售后说会出现有的zip可以上传有的不可以,就查了一下问题,报错是java.lang.IllegalArgumentException: MALFORMED
所以查了一下,说是编码的问题导致解压不成功。
参考一个博客 https://blog.csdn.net/guying4875/article/details/81034022
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.BitSet;
/**
* @author 自动识别文件编码格式
*
*/
public class EncodeUtil {
private static Logger logger = LoggerFactory.getLogger(EncodeUtil.class);
private static int BYTE_SIZE = 8;
public static String CODE_UTF8 = "UTF-8";
public static String CODE_UTF8_BOM = "UTF-8_BOM";
public static String CODE_GBK = "GBK";
/**
* 通过文件全名称获取编码集名称
*
* @param fullFileName
* @param ignoreBom
* @return
* @throws Exception
*/
public static String getEncode(String fullFileName, boolean ignoreBom) throws Exception {
logger.debug("fullFileName ; {}", fullFileName);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fullFileName));
return getEncode(bis, ignoreBom);
}
/**
* 通过文件缓存流获取编码集名称,文件流必须为未曾
*
* @param bis
* @param ignoreBom 是否忽略utf-8 bom
* @return
* @throws Exception
*/
public static String getEncode(BufferedInputStream bis, boolean ignoreBom) throws Exception {
bis.mark(0);
String encodeType = "未识别";
byte[] head = new byte[3];
bis.read(head);
if (head[0] == -1 && head[1] == -2) {
encodeType = "UTF-16";
} else if (head[0] == -2 && head[1] == -1) {
encodeType = "Unicode";
} else if (head[0] == -17 && head[1] == -69 && head[2] == -65) { //带BOM
if (ignoreBom) {
encodeType = CODE_UTF8;
} else {
encodeType = CODE_UTF8_BOM;
}
} else if ("Unicode".equals(encodeType)) {
encodeType = "UTF-16";
} else if (isUTF8(bis)) {
encodeType = CODE_UTF8;
} else {
encodeType = CODE_GBK;
}
logger.info("result encode type : " + encodeType);
return encodeType;
}
/**
* 是否是无BOM的UTF8格式,不判断常规场景,只区分无BOM UTF8和GBK
*
* @param bis
* @return
*/
private static boolean isUTF8( BufferedInputStream bis) throws Exception {
bis.reset();
//读取第一个字节
int code = bis.read();
do {
BitSet bitSet = convert2BitSet(code);
//判断是否为单字节
if (bitSet.get(0)) {//多字节时,再读取N个字节
if (!checkMultiByte(bis, bitSet)) {//未检测通过,直接返回
return false;
}
} else {
//单字节时什么都不用做,再次读取字节
}
code = bis.read();
} while (code != -1);
return true;
}
/**
* 检测多字节,判断是否为utf8,已经读取了一个字节
*
* @param bis
* @param bitSet
* @return
*/
private static boolean checkMultiByte(BufferedInputStream bis, BitSet bitSet) throws Exception {
int count = getCountOfSequential(bitSet);
byte[] bytes = new byte[count - 1];//已经读取了一个字节,不能再读取
bis.read(bytes);
for (byte b : bytes) {
if (!checkUtf8Byte(b)) {
return false;
}
}
return true;
}
/**
* 检测单字节,判断是否为utf8
*
* @param b
* @return
*/
private static boolean checkUtf8Byte(byte b) throws Exception {
BitSet bitSet = convert2BitSet(b);
return bitSet.get(0) && !bitSet.get(1);
}
/**
* 检测bitSet中从开始有多少个连续的1
*
* @param bitSet
* @return
*/
private static int getCountOfSequential( BitSet bitSet) {
int count = 0;
for (int i = 0; i < BYTE_SIZE; i++) {
if (bitSet.get(i)) {
count++;
} else {
break;
}
}
return count;
}
/**
* 将整形转为BitSet
*
* @param code
* @return
*/
private static BitSet convert2BitSet(int code) {
BitSet bitSet = new BitSet(BYTE_SIZE);
for (int i = 0; i < BYTE_SIZE; i++) {
int tmp3 = code >> (BYTE_SIZE - i - 1);
int tmp2 = 0x1 & tmp3;
if (tmp2 == 1) {
bitSet.set(i);
}
}
return bitSet;
}
/**
* 将一指定编码的文件转换为另一编码的文件
*
* @param oldFullFileName
* @param oldCharsetName
* @param newFullFileName
* @param newCharsetName
*/
public static void convert(String oldFullFileName, String oldCharsetName, String newFullFileName, String newCharsetName) throws Exception {
logger.info("the old file name is : {}, The oldCharsetName is : {}", oldFullFileName, oldCharsetName);
logger.info("the new file name is : {}, The newCharsetName is : {}", newFullFileName, newCharsetName);
StringBuffer content = new StringBuffer();
BufferedReader bin = new BufferedReader(new InputStreamReader(new FileInputStream(oldFullFileName), oldCharsetName));
String line;
while ((line = bin.readLine()) != null) {
content.append(line);
content.append(System.getProperty("line.separator"));
}
newFullFileName = newFullFileName.replace("\\", "/");
File dir = new File(newFullFileName.substring(0, newFullFileName.lastIndexOf("/")));
if (!dir.exists()) {
dir.mkdirs();
}
Writer out = new OutputStreamWriter(new FileOutputStream(newFullFileName), newCharsetName);
out.write(content.toString());
}
}
String fileEncode = EncodeUtil.getEncode(oFile.getPath(),false);
ZipInputStream ZinO=new ZipInputStream(new FileInputStream(oFile.getPath()), Charset.forName(fileEncode));
最后解决。