pioneer
2 years ago
commit
c72c3d671b
15 changed files with 978 additions and 0 deletions
@ -0,0 +1,6 @@
|
||||
# open-JSD-10257 |
||||
|
||||
JSD-10257 excel加密文件导入自动解密导出\ |
||||
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ |
||||
仅作为开发者学习参考使用!禁止用于任何商业用途!\ |
||||
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【pioneer】处理。 |
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><plugin> |
||||
<id>com.fr.plugin.xx.ygkj.encode</id> |
||||
<main-package>com.hzdatalink.gsdes</main-package> |
||||
<name><![CDATA[云谷加密]]></name> |
||||
<active>yes</active> |
||||
<version>1.4</version> |
||||
<env-version>10.0</env-version> |
||||
<jartime>2018-07-31</jartime> |
||||
<vendor>fr.open</vendor> |
||||
<description><![CDATA[云谷加密解密]]></description> |
||||
<change-notes><![CDATA[ |
||||
[2022-06-05]【1.0】初始化插件。<br/> |
||||
[2022-06-20]【1.1】增加导入解密。<br/> |
||||
[2022-06-21]【1.2】增加填报导入支持。<br/> |
||||
[2022-06-21]【1.3】保留解密文件。<br/> |
||||
[2022-07-29]【1.4】兼容标记导入。<br/> |
||||
]]></change-notes> |
||||
<extra-report> |
||||
<ExportExtensionProcessor class="com.hzdatalink.gsdes.EncodeExportExtensionProvider"/> |
||||
</extra-report> |
||||
<extra-decision> |
||||
<GlobalRequestFilterProvider class="com.hzdatalink.gsdes.filter.GlobalFilter"/> |
||||
</extra-decision> |
||||
<function-recorder class="com.hzdatalink.gsdes.EncodeExportExtensionProvider"/> |
||||
</plugin> |
@ -0,0 +1,9 @@
|
||||
package com.hzdatalink.gsdes; |
||||
|
||||
/** |
||||
* @author xx |
||||
* @date 2020/11/20 |
||||
*/ |
||||
public class Constants { |
||||
public static final String PLUGIN_ID = "com.fr.plugin.xx.ygkj.encode"; |
||||
} |
@ -0,0 +1,39 @@
|
||||
package com.hzdatalink.gsdes; |
||||
|
||||
import com.fr.intelli.record.Focus; |
||||
import com.fr.intelli.record.Original; |
||||
import com.fr.io.collection.ExportCollection; |
||||
import com.fr.io.exporter.AppExporter; |
||||
import com.fr.plugin.context.PluginContexts; |
||||
import com.fr.plugin.transform.FunctionRecorder; |
||||
import com.fr.record.analyzer.EnableMetrics; |
||||
import com.fr.stable.fun.Authorize; |
||||
import com.fr.web.core.ReportSessionIDInfor; |
||||
import com.fr.web.core.reserve.DefaultExportExtension; |
||||
import com.hzdatalink.gsdes.export.EncryptExporter; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
|
||||
/** |
||||
* @Author xx |
||||
* @Date 2021/11/23 |
||||
* @Description |
||||
**/ |
||||
@FunctionRecorder |
||||
@Authorize(callSignKey = Constants.PLUGIN_ID) |
||||
@EnableMetrics |
||||
public class EncodeExportExtensionProvider extends DefaultExportExtension { |
||||
|
||||
@Override |
||||
@Focus(id = Constants.PLUGIN_ID, text = "xx加密", source = Original.PLUGIN) |
||||
public ExportCollection createCollection(HttpServletRequest req, HttpServletResponse res, |
||||
ReportSessionIDInfor info, String format, String filename, boolean isEmbed) throws Exception { |
||||
ExportCollection collection = super.createCollection(req, res, info, format, filename, isEmbed); |
||||
AppExporter exporter = collection.getExporter(); |
||||
if (PluginContexts.currentContext().isAvailable()) { |
||||
collection.setExporter(new EncryptExporter(exporter)); |
||||
} |
||||
return collection; |
||||
} |
||||
} |
@ -0,0 +1,226 @@
|
||||
// GS-EDS加解密接口包,注意:不可修改包名!
|
||||
package com.hzdatalink.gsdes; |
||||
|
||||
import com.fr.log.FineLoggerFactory; |
||||
|
||||
public class FileOperation { |
||||
// DEMO命令行程序入口
|
||||
public static void main(String[] args) { |
||||
if (args.length == 0) { |
||||
System.out.println("请在命令行传入测试目标文件路径."); |
||||
return; |
||||
} |
||||
|
||||
// 测试文件
|
||||
String fileName = args[0]; |
||||
System.out.println(String.format("开始测试文件加解密: %s.", fileName)); |
||||
|
||||
testFileEncDec(fileName); |
||||
testFileInfo(fileName); |
||||
|
||||
try { |
||||
Thread.sleep(1000); |
||||
} catch (InterruptedException e) { |
||||
} |
||||
} |
||||
|
||||
// 文件加密
|
||||
public static Result encodeFile(String srcFileName, // 源文件名
|
||||
String dstFileName // 目标文件名
|
||||
) { |
||||
return jniEncodeFile(srcFileName, dstFileName); |
||||
} |
||||
|
||||
// 文件解密
|
||||
public static Result decodeFile(String srcFileName, // 源文件名
|
||||
String dstFileName // 目标文件名
|
||||
) { |
||||
return jniDecodeFile(srcFileName, dstFileName); |
||||
} |
||||
|
||||
// 判断文件是否加密函数声明
|
||||
public static IsFileEncryptedResult isFileEncrypted(String fileName // 文件名
|
||||
) { |
||||
return jniIsFileEncrypted(fileName); |
||||
} |
||||
|
||||
// 获取文件信息函数声明
|
||||
public static GetFileInfoResult getFileInfo(String fileName // 文件名
|
||||
) { |
||||
return jniGetFileInfo(fileName); |
||||
} |
||||
|
||||
// 获取标密文件信息
|
||||
public static GetFileCLIInfoResult getFileCLIInfo(String fileName // 文件名
|
||||
) { |
||||
return jniGetFileCLIInfo(fileName); |
||||
} |
||||
|
||||
// 设置加密文件信息
|
||||
public static Result setFileInfo(String fileName, // 文件名
|
||||
int userOID, // 文件所属用户OID
|
||||
int orgOID, // 文件所属组织ID
|
||||
int clID, // 文件密级
|
||||
int fileId // 文件ID
|
||||
) { |
||||
return jniSetFileInfo(fileName, userOID, orgOID, clID, fileId); |
||||
} |
||||
|
||||
// 设置标密文件信息
|
||||
public static Result setFileCLIInfo(String fileName, // 文件名
|
||||
int userOID, // 文件所属用户OID
|
||||
int orgOID, // 文件所属组织ID
|
||||
int clID, // 文件密级
|
||||
int fileId, // 文件ID
|
||||
int sp, // 文件保密期限
|
||||
int cliTime, // 文件标密时间
|
||||
String fileUUID // 文件UUID
|
||||
) { |
||||
return jniSetFileCLIInfo(fileName, userOID, orgOID, clID, fileId, sp, cliTime, fileUUID); |
||||
} |
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 加载libGsDes.so
|
||||
static { |
||||
String os = System.getProperty("os.name"); |
||||
//Windows操作系统
|
||||
if (os != null && os.toLowerCase().startsWith("windows")) { |
||||
FineLoggerFactory.getLogger().info("current system is win"); |
||||
System.loadLibrary("gsedsapi"); |
||||
} else if (os != null && os.toLowerCase().startsWith("linux")) { |
||||
FineLoggerFactory.getLogger().info("current system is linux"); |
||||
System.loadLibrary("GsDes"); |
||||
} else { //其它操作系统
|
||||
FineLoggerFactory.getLogger().info("not support system"); |
||||
} |
||||
} |
||||
|
||||
// 文件加密函数声明
|
||||
public static native Result jniEncodeFile(String srcFileName, // 源文件名
|
||||
String dstFileName // 目标文件名
|
||||
); |
||||
|
||||
// 文件解密函数声明
|
||||
public static native Result jniDecodeFile(String srcFileName, // 源文件名
|
||||
String dstFileName // 目标文件名
|
||||
); |
||||
|
||||
// 判断文件是否加密函数声明
|
||||
public static native IsFileEncryptedResult jniIsFileEncrypted(String fileName // 文件名
|
||||
); |
||||
|
||||
// 获取文件信息函数声明
|
||||
public static native GetFileInfoResult jniGetFileInfo(String fileName // 文件名
|
||||
); |
||||
|
||||
// 获取标密文件信息
|
||||
public static native GetFileCLIInfoResult jniGetFileCLIInfo(String fileName // 文件名
|
||||
); |
||||
|
||||
// 设置加密文件信息
|
||||
public static native Result jniSetFileInfo(String fileName, // 文件名
|
||||
int userOID, // 文件所属用户OID
|
||||
int orgOID, // 文件所属组织ID
|
||||
int clID, // 文件密级
|
||||
int fileId // 文件ID
|
||||
); |
||||
|
||||
// 设置标密文件信息
|
||||
public static native Result jniSetFileCLIInfo(String fileName, // 文件名
|
||||
int userOID, // 文件所属用户OID
|
||||
int orgOID, // 文件所属组织ID
|
||||
int clID, // 文件密级
|
||||
int fileId, // 文件ID
|
||||
int sp, // 文件保密期限
|
||||
int cliTime, // 文件标密时间
|
||||
String fileUUID // 文件UUID
|
||||
); |
||||
|
||||
private static void testFileEncDec(String fileName) { |
||||
Result result; |
||||
|
||||
// 解密文件
|
||||
result = decodeFile(fileName, fileName); |
||||
if (result.getSucceeded()) { |
||||
System.out.println("解密文件成功."); |
||||
} else { |
||||
System.out.println(String.format("解密文件失败, %s", result.getMessage())); |
||||
} |
||||
|
||||
// 加密文件
|
||||
result = encodeFile(fileName, fileName); |
||||
if (result.getSucceeded()) { |
||||
System.out.println("加密文件成功."); |
||||
} else { |
||||
System.out.println(String.format("加密文件失败, %s", result.getMessage())); |
||||
return; |
||||
} |
||||
|
||||
// 校验文件是否加密
|
||||
IsFileEncryptedResult isEnc = isFileEncrypted(fileName); |
||||
if (isEnc.getSucceeded()) { |
||||
System.out.println(String.format("检查文件是否加密成功, 文件%s.", (isEnc.getEncrypted() ? "已加密" : "未加密"))); |
||||
} else { |
||||
System.out.println(String.format("检查文件是否加密失败, %s", isEnc.getMessage())); |
||||
return; |
||||
} |
||||
|
||||
// 解密文件
|
||||
result = decodeFile(fileName, fileName); |
||||
if (result.getSucceeded()) { |
||||
System.out.println("解密文件成功."); |
||||
} else { |
||||
System.out.println(String.format("解密文件失败, %s", result.getMessage())); |
||||
} |
||||
} |
||||
|
||||
private static void testFileInfo(String fileName) { |
||||
// 加密文件
|
||||
Result result = encodeFile(fileName, fileName); |
||||
if (result.getSucceeded()) { |
||||
System.out.println("加密文件成功."); |
||||
} else { |
||||
System.out.println(String.format("加密文件失败, %s", result.getMessage())); |
||||
return; |
||||
} |
||||
|
||||
// 设置文件信息
|
||||
result = setFileInfo(fileName, 1026, 6, 5, 0); |
||||
if (result.getSucceeded()) { |
||||
System.out.println("设置文件信息成功."); |
||||
} else { |
||||
System.out.println(String.format("设置文件信息失败, %s", result.getMessage())); |
||||
} |
||||
|
||||
// 获取文件信息
|
||||
GetFileInfoResult fileInfo = getFileInfo(fileName); |
||||
if (fileInfo.getSucceeded()) { |
||||
System.out.println(String.format("获取文件信息成功, 文件%s, User:%d, Org:%d, cl:%d, fileid:%d.", |
||||
(fileInfo.getEncrypted() ? "已加密" : "未加密"), fileInfo.getUserOID(), fileInfo.getOrgOID(), |
||||
fileInfo.getCLID(), fileInfo.getFileID())); |
||||
} else { |
||||
System.out.println(String.format("获取文件信息失败, %s", fileInfo.getMessage())); |
||||
} |
||||
|
||||
// 获取标密文件信息
|
||||
GetFileCLIInfoResult fileCliInfo = getFileCLIInfo(fileName); |
||||
if (fileCliInfo.getSucceeded()) { |
||||
System.out.println(String.format( |
||||
"获取标密文件信息成功, 文件%s, User:%d, Org:%d, cl:%d, sp:%d, cliTime:%d, fileUuid:%s.", |
||||
(fileCliInfo.getEncrypted() ? "已加密" : "未加密"), fileCliInfo.getUserOID(), fileCliInfo.getOrgOID(), |
||||
fileCliInfo.getCLID(), fileCliInfo.getSP(), fileCliInfo.getCLITime(), fileCliInfo.getFileUUID())); |
||||
} else { |
||||
System.out.println(String.format("获取标密文件信息失败, %s", fileCliInfo.getMessage())); |
||||
} |
||||
|
||||
// 设置标密文件信息
|
||||
result = setFileCLIInfo(fileName, // 文件名
|
||||
fileCliInfo.getUserOID(), fileCliInfo.getOrgOID(), fileCliInfo.getCLID(), fileCliInfo.getFileId(), |
||||
fileCliInfo.getSP(), fileCliInfo.getCLITime(), fileCliInfo.getFileUUID()); |
||||
if (result.getSucceeded()) { |
||||
System.out.println("设置文件信息成功."); |
||||
} else { |
||||
System.out.println(String.format("设置文件信息失败, %s", result.getMessage())); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,71 @@
|
||||
// GS-EDS加解密接口包,注意:不可修改包名!
|
||||
package com.hzdatalink.gsdes; |
||||
|
||||
// GetFileCLIInfo 函数返回结果
|
||||
public class GetFileCLIInfoResult { |
||||
|
||||
private String message; // 是否成功
|
||||
private boolean succeeded; // 失败信息
|
||||
private boolean encrypted; // 文件是否加密
|
||||
private int userOID; // 文件所属用户OID
|
||||
private int orgOID; // 文件所属组织ID
|
||||
private int clID; // 文件密级
|
||||
private short sp; // 文件保密期限
|
||||
private int cliTime; // 文件标密时间
|
||||
private String fileUUID; // 文件UUID
|
||||
private int fileID; // 文件ID
|
||||
|
||||
public GetFileCLIInfoResult() { |
||||
this.succeeded = false; |
||||
} |
||||
|
||||
// 是否成功
|
||||
public boolean getSucceeded() { |
||||
return succeeded; |
||||
} |
||||
|
||||
// 失败信息
|
||||
public String getMessage() { |
||||
return message; |
||||
} |
||||
|
||||
// 文件是否加密
|
||||
public boolean getEncrypted() { |
||||
return encrypted; |
||||
} |
||||
|
||||
// 文件所属用户OID
|
||||
public int getUserOID() { |
||||
return userOID; |
||||
} |
||||
|
||||
// 文件所属组织ID
|
||||
public int getOrgOID() { |
||||
return orgOID; |
||||
} |
||||
|
||||
// 文件密级
|
||||
public int getCLID() { |
||||
return clID; |
||||
} |
||||
|
||||
// 文件ID
|
||||
public int getFileId() { |
||||
return fileID; |
||||
} |
||||
|
||||
// 文件保密期限
|
||||
public short getSP() { |
||||
return sp; |
||||
} |
||||
|
||||
// 文件标密时间
|
||||
public int getCLITime() { |
||||
return cliTime; |
||||
} |
||||
|
||||
// 文件UUID
|
||||
public String getFileUUID() { |
||||
return fileUUID; |
||||
} |
||||
} |
@ -0,0 +1,53 @@
|
||||
// GS-EDS加解密接口包,注意:不可修改包名!
|
||||
package com.hzdatalink.gsdes; |
||||
|
||||
// GetFileInfo 函数返回结果
|
||||
public class GetFileInfoResult { |
||||
|
||||
private String message; // 是否成功
|
||||
private boolean succeeded; // 失败信息
|
||||
private boolean encrypted; // 文件是否加密
|
||||
private int userOID; // 文件所属用户OID
|
||||
private int orgOID; // 文件所属组织ID
|
||||
private int clID; // 文件密级
|
||||
private int fileID; // 文件ID
|
||||
|
||||
public GetFileInfoResult() { |
||||
this.succeeded = false; |
||||
} |
||||
|
||||
// 是否成功
|
||||
public boolean getSucceeded() { |
||||
return succeeded; |
||||
} |
||||
|
||||
// 失败信息
|
||||
public String getMessage() { |
||||
return message; |
||||
} |
||||
|
||||
// 文件是否加密
|
||||
public boolean getEncrypted() { |
||||
return encrypted; |
||||
} |
||||
|
||||
// 文件所属用户OID
|
||||
public int getUserOID() { |
||||
return userOID; |
||||
} |
||||
|
||||
// 文件所属组织ID
|
||||
public int getOrgOID() { |
||||
return orgOID; |
||||
} |
||||
|
||||
// 文件密级
|
||||
public int getCLID() { |
||||
return clID; |
||||
} |
||||
|
||||
// 文件ID
|
||||
public int getFileID() { |
||||
return fileID; |
||||
} |
||||
} |
@ -0,0 +1,29 @@
|
||||
// GS-EDS加解密接口包,注意:不可修改包名!
|
||||
package com.hzdatalink.gsdes; |
||||
|
||||
// IsFileEncrypted 返回结果
|
||||
public class IsFileEncryptedResult { |
||||
|
||||
private String message; // 是否成功
|
||||
private boolean succeeded; // 失败信息
|
||||
private boolean encrypted; // 是否加密
|
||||
|
||||
public IsFileEncryptedResult() { |
||||
this.succeeded = false; |
||||
} |
||||
|
||||
// 是否成功
|
||||
public boolean getSucceeded() { |
||||
return succeeded; |
||||
} |
||||
|
||||
// 失败信息
|
||||
public String getMessage() { |
||||
return message; |
||||
} |
||||
|
||||
// 是否加密
|
||||
public boolean getEncrypted() { |
||||
return encrypted; |
||||
} |
||||
} |
@ -0,0 +1,23 @@
|
||||
// GS-EDS加解密接口包,注意:不可修改包名!
|
||||
package com.hzdatalink.gsdes; |
||||
|
||||
// 通用返回结果
|
||||
public class Result { |
||||
|
||||
private String message; // 是否成功
|
||||
private boolean succeeded; // 失败信息
|
||||
|
||||
public Result() { |
||||
this.succeeded = false; |
||||
} |
||||
|
||||
// 是否成功
|
||||
public boolean getSucceeded() { |
||||
return succeeded; |
||||
} |
||||
|
||||
// 失败信息
|
||||
public String getMessage() { |
||||
return message; |
||||
} |
||||
} |
@ -0,0 +1,63 @@
|
||||
package com.hzdatalink.gsdes.bean; |
||||
|
||||
import com.fr.third.jodd.io.StreamUtil; |
||||
|
||||
import javax.servlet.ReadListener; |
||||
import javax.servlet.ServletInputStream; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletRequestWrapper; |
||||
import java.io.BufferedReader; |
||||
import java.io.ByteArrayInputStream; |
||||
import java.io.IOException; |
||||
import java.io.InputStreamReader; |
||||
|
||||
/** |
||||
* @author xx |
||||
* @date 2020/11/20 |
||||
*/ |
||||
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper { |
||||
private BufferedReader br; |
||||
private byte[] body; |
||||
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException { |
||||
super(request); |
||||
//this.br = request.getReader();
|
||||
body = StreamUtil.readBytes(request.getInputStream()); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public BufferedReader getReader() throws IOException { |
||||
return new BufferedReader(new InputStreamReader(getInputStream())); |
||||
} |
||||
|
||||
@Override |
||||
public ServletInputStream getInputStream() throws IOException { |
||||
final ByteArrayInputStream bais = new ByteArrayInputStream(body); |
||||
return new ServletInputStream() { |
||||
|
||||
@Override |
||||
public boolean isFinished() { |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isReady() { |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public void setReadListener(ReadListener readListener) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public int read() throws IOException { |
||||
return bais.read(); |
||||
} |
||||
}; |
||||
} |
||||
|
||||
public void setBody(byte[] body) { |
||||
this.body = body; |
||||
} |
||||
} |
@ -0,0 +1,85 @@
|
||||
package com.hzdatalink.gsdes.export; |
||||
|
||||
import com.fr.general.CommonIOUtils; |
||||
import com.fr.io.exporter.AppExporter; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.main.workbook.ResultWorkBook; |
||||
import com.fr.page.PageSetCreator; |
||||
import com.fr.page.PageSetProvider; |
||||
import com.fr.web.core.ReportRepositoryDeal; |
||||
import com.hzdatalink.gsdes.FileOperation; |
||||
import com.hzdatalink.gsdes.util.FileUtil; |
||||
|
||||
import java.io.*; |
||||
|
||||
/** |
||||
* @Author xx |
||||
* @Date 2021/11/23 |
||||
* @Description |
||||
**/ |
||||
public class EncryptExporter implements AppExporter { |
||||
|
||||
private AppExporter original; |
||||
|
||||
public EncryptExporter(AppExporter original) { |
||||
this.original = original; |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void export(OutputStream out, ResultWorkBook book) throws Exception { |
||||
ByteArrayOutputStream encryptOutputStream = new ByteArrayOutputStream(); |
||||
original.export(encryptOutputStream, book); |
||||
this.encrypt(encryptOutputStream.toByteArray(),out); |
||||
} |
||||
|
||||
@Override |
||||
public void export(OutputStream out, PageSetProvider pageSet) throws Exception { |
||||
ByteArrayOutputStream encryptOutputStream = new ByteArrayOutputStream(); |
||||
original.export(encryptOutputStream, pageSet); |
||||
this.encrypt(encryptOutputStream.toByteArray(),out); |
||||
} |
||||
|
||||
@Override |
||||
public void export(OutputStream out, ResultWorkBook book, PageSetCreator creator, ReportRepositoryDeal repo, int[] sheets) throws Exception { |
||||
ByteArrayOutputStream encryptOutputStream = new ByteArrayOutputStream(); |
||||
original.export(encryptOutputStream, book, creator, repo, sheets); |
||||
this.encrypt(encryptOutputStream.toByteArray(),out); |
||||
} |
||||
|
||||
@Override |
||||
public void export(OutputStream out, ResultWorkBook book, PageSetProvider pageSet, ReportRepositoryDeal repo, int[] sheets) throws Exception { |
||||
ByteArrayOutputStream encryptOutputStream = new ByteArrayOutputStream(); |
||||
original.export(encryptOutputStream, book, pageSet, repo, sheets); |
||||
this.encrypt(encryptOutputStream.toByteArray(),out); |
||||
} |
||||
|
||||
@Override |
||||
public void setVersion(Object o) { |
||||
original.setVersion(o); |
||||
} |
||||
|
||||
private void encrypt(byte[] bytes,OutputStream outputStream) throws IOException { |
||||
FileOutputStream fileOutputStream = null; |
||||
try { |
||||
File tempFile = FileUtil.createTempFile(); |
||||
File encodeFile = FileUtil.createTempFile(); |
||||
fileOutputStream = new FileOutputStream(tempFile); |
||||
fileOutputStream.write(bytes); |
||||
fileOutputStream.flush(); |
||||
FileOperation.encodeFile(tempFile.getAbsolutePath(), encodeFile.getAbsolutePath()); |
||||
byte[] encodeByte = CommonIOUtils.inputStream2Bytes(new FileInputStream(encodeFile)); |
||||
tempFile.deleteOnExit(); |
||||
encodeFile.deleteOnExit(); |
||||
outputStream.write(encodeByte); |
||||
outputStream.flush(); |
||||
outputStream.close(); |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} finally { |
||||
if (fileOutputStream != null) { |
||||
fileOutputStream.close(); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,104 @@
|
||||
package com.hzdatalink.gsdes.export; |
||||
|
||||
import com.fr.general.CommonIOUtils; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.hzdatalink.gsdes.FileOperation; |
||||
import com.hzdatalink.gsdes.util.FileUtil; |
||||
|
||||
import javax.servlet.ServletOutputStream; |
||||
import javax.servlet.WriteListener; |
||||
import java.io.*; |
||||
|
||||
/** |
||||
* @Author xx |
||||
* @Date 2021/11/23 |
||||
* @Description |
||||
**/ |
||||
public class EncryptOutputStream extends ServletOutputStream { |
||||
|
||||
private OutputStream original = null; |
||||
private boolean closed = false; |
||||
private ByteArrayOutputStream crypt = new ByteArrayOutputStream(); |
||||
|
||||
public EncryptOutputStream(OutputStream original) { |
||||
this.original = original; |
||||
} |
||||
|
||||
/** |
||||
* 实际加密的代码就在这里实现了 |
||||
* |
||||
* @param bytes |
||||
* @return |
||||
*/ |
||||
private byte[] encrypt(byte[] bytes) throws IOException { |
||||
FileOutputStream fileOutputStream = null; |
||||
try { |
||||
File tempFile = FileUtil.createTempFile(); |
||||
File encodeFile = FileUtil.createTempFile(); |
||||
fileOutputStream = new FileOutputStream(tempFile); |
||||
fileOutputStream.write(bytes); |
||||
fileOutputStream.flush(); |
||||
FileOperation.encodeFile(tempFile.getAbsolutePath(), encodeFile.getAbsolutePath()); |
||||
byte[] encodeByte = CommonIOUtils.inputStream2Bytes(new FileInputStream(encodeFile)); |
||||
tempFile.deleteOnExit(); |
||||
encodeFile.deleteOnExit(); |
||||
return encodeByte; |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} finally { |
||||
if (fileOutputStream != null) { |
||||
fileOutputStream.close(); |
||||
} |
||||
} |
||||
return bytes; |
||||
} |
||||
|
||||
@Override |
||||
public void write(int b) throws IOException { |
||||
if (closed) { |
||||
throw new IOException("Cannot write to a closed output stream"); |
||||
} |
||||
crypt.write(b); |
||||
} |
||||
|
||||
@Override |
||||
public void close() throws IOException { |
||||
if (!closed) { |
||||
byte[] bytes = crypt.toByteArray(); |
||||
bytes = encrypt(bytes); |
||||
original.write(bytes); |
||||
original.flush(); |
||||
original.close(); |
||||
closed = true; |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void flush() throws IOException { |
||||
crypt.flush(); |
||||
} |
||||
|
||||
@Override |
||||
public void write(byte[] data) throws IOException { |
||||
write(data, 0, data.length); |
||||
} |
||||
|
||||
@Override |
||||
public void write(byte[] data, int off, int len) throws IOException { |
||||
if (closed) { |
||||
throw new IOException("Cannot write to a closed output stream"); |
||||
} |
||||
crypt.write(data, off, len); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isReady() { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public void setWriteListener(WriteListener listener) { |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,115 @@
|
||||
package com.hzdatalink.gsdes.filter; |
||||
|
||||
import com.fr.base.ServerConfig; |
||||
import com.fr.base.core.IgnoreBytesInputStream; |
||||
import com.fr.base.core.ParseResult; |
||||
import com.fr.base.core.PostParseUtils; |
||||
import com.fr.general.CommonIOUtils; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.third.org.apache.commons.io.IOUtils; |
||||
import com.fr.web.utils.WebUtils; |
||||
import com.hzdatalink.gsdes.FileOperation; |
||||
import com.hzdatalink.gsdes.IsFileEncryptedResult; |
||||
import com.hzdatalink.gsdes.bean.BodyReaderHttpServletRequestWrapper; |
||||
import com.hzdatalink.gsdes.util.FileUtil; |
||||
|
||||
import javax.servlet.FilterChain; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.*; |
||||
|
||||
/** |
||||
* @author xx |
||||
* @date 2020/11/20 |
||||
*/ |
||||
public class DecodeFilter { |
||||
private static final byte[] NEW_LINE_BYTES = new byte[]{13, 10}; |
||||
private static final byte[] BOUNDARY_END = new byte[]{45, 45}; |
||||
|
||||
private static final String TMP_PATH = System.getProperty("java.io.tmpdir"); |
||||
|
||||
public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) { |
||||
try { |
||||
FineLoggerFactory.getLogger().info("decode request uri: {}", req.getRequestURI()); |
||||
BodyReaderHttpServletRequestWrapper wrapper = new BodyReaderHttpServletRequestWrapper(req); |
||||
InputStream inputStream = wrapper.getInputStream(); |
||||
ParseResult parseResult = PostParseUtils.parse(inputStream, req.getCharacterEncoding()); |
||||
InputStream fileDecorator = new IgnoreBytesInputStream(inputStream, this.concat(this.concat(NEW_LINE_BYTES, parseResult.getBoundary().getBytes()), BOUNDARY_END)); |
||||
String filename = WebUtils.getHTTPRequestParameter(req, "filename"); |
||||
File file = saveTmp(fileDecorator, filename); |
||||
FineLoggerFactory.getLogger().info("record file to {}", file.getPath()); |
||||
byte[] bytes = null; |
||||
IsFileEncryptedResult encode = FileOperation.isFileEncrypted(file.getAbsolutePath()); |
||||
FineLoggerFactory.getLogger().info("isFileEncrypted res is {}", encode.getSucceeded()); |
||||
if (encode != null && encode.getEncrypted()) { |
||||
FineLoggerFactory.getLogger().info("current file is encode file"); |
||||
File decodeFile = FileUtil.createTempFile(); |
||||
FineLoggerFactory.getLogger().info("decode file path is {}",decodeFile.getAbsolutePath()); |
||||
FileOperation.decodeFile(file.getAbsolutePath(), decodeFile.getAbsolutePath()); |
||||
bytes = CommonIOUtils.inputStream2Bytes(new FileInputStream(decodeFile)); |
||||
decodeFile.deleteOnExit(); |
||||
} |
||||
if (bytes == null) { |
||||
FineLoggerFactory.getLogger().info("current file is not decode"); |
||||
} else { |
||||
FineLoggerFactory.getLogger().info("decode file byte size is {}", bytes.length); |
||||
byte[] body = null; |
||||
String character = req.getCharacterEncoding(); |
||||
if (StringUtils.isNotEmpty(character)) { |
||||
body = handleBody(bytes, parseResult, req.getCharacterEncoding()); |
||||
} else { |
||||
body = handleBody(bytes, parseResult, ServerConfig.getInstance().getServerCharset()); |
||||
} |
||||
wrapper.setBody(body); |
||||
} |
||||
file.delete(); |
||||
FineLoggerFactory.getLogger().info("delete temp file"); |
||||
filterChain.doFilter(wrapper, res); |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
} |
||||
|
||||
private File saveTmp(InputStream input, String filename) throws IOException { |
||||
File file = FileUtil.createTempFile(); |
||||
try { |
||||
FileOutputStream outputStream = new FileOutputStream(file.getPath()); |
||||
IOUtils.copyLarge(input, outputStream); |
||||
FineLoggerFactory.getLogger().info("save tmp file path is {}", file.getPath()); |
||||
} catch (IOException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
return file; |
||||
} |
||||
|
||||
|
||||
private byte[] concat(byte[] a, byte[] b) { |
||||
byte[] c = new byte[a.length + b.length]; |
||||
System.arraycopy(a, 0, c, 0, a.length); |
||||
System.arraycopy(b, 0, c, a.length, b.length); |
||||
return c; |
||||
} |
||||
|
||||
private byte[] handleBody(byte[] body, ParseResult parseResult, String charsetName) throws UnsupportedEncodingException { |
||||
byte[] newBody; |
||||
byte[] start; |
||||
byte[] end; |
||||
StringBuilder stringBuilder = new StringBuilder(); |
||||
stringBuilder.append(parseResult.getBoundary()).append("\r\n") |
||||
.append("Content-Disposition:").append(parseResult.getDispline()) |
||||
.append("; name=\"").append(parseResult.getFieldName()) |
||||
.append("\"; filename=\"").append(parseResult.getFileName()).append("\"\r\n") |
||||
.append("Content-Type: ").append(parseResult.getMime()).append("/").append(parseResult.getSubMime()).append("\r\n").append("\r\n"); |
||||
start = stringBuilder.toString().getBytes(charsetName); |
||||
StringBuilder stringBuilder1 = new StringBuilder(); |
||||
stringBuilder1.append("\r\n").append(parseResult.getBoundary()).append("--\r\n"); |
||||
end = stringBuilder1.toString().getBytes(charsetName); |
||||
// newBody = this.concat(this.concat(("------WebKitFormBoundary6c2DUJvlVKG0I1po\r\n" +
|
||||
// "Content-Disposition: form-data; name=\"FileData\"; filename=\"1.xlsx\"\r\n" +
|
||||
// "Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\r\n" +
|
||||
// "\r\n").getBytes(charsetName), body), ("\r\n------WebKitFormBoundary6c2DUJvlVKG0I1po--\r\n").getBytes(charsetName));
|
||||
newBody = this.concat(this.concat(start, body), end); |
||||
return newBody; |
||||
} |
||||
} |
@ -0,0 +1,94 @@
|
||||
package com.hzdatalink.gsdes.filter; |
||||
|
||||
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.plugin.context.PluginContexts; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.web.utils.WebUtils; |
||||
|
||||
import javax.servlet.FilterChain; |
||||
import javax.servlet.ServletException; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.IOException; |
||||
|
||||
/** |
||||
* @author xx |
||||
* @date 2020/11/20 |
||||
*/ |
||||
public class GlobalFilter extends AbstractGlobalRequestFilterProvider { |
||||
@Override |
||||
public String filterName() { |
||||
return "gsdes"; |
||||
} |
||||
|
||||
@Override |
||||
public String[] urlPatterns() { |
||||
if (PluginContexts.currentContext().isAvailable()) { |
||||
return new String[]{ |
||||
"/*" |
||||
}; |
||||
} else { |
||||
return new String[]{"/neverbeused"}; |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) { |
||||
if (isDecode(req)) { |
||||
new DecodeFilter().doFilter(req, res, filterChain); |
||||
return; |
||||
} |
||||
|
||||
try { |
||||
filterChain.doFilter(req, res); |
||||
} catch (IOException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||
} catch (ServletException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||
} |
||||
} |
||||
|
||||
private boolean isDecode(HttpServletRequest req) { |
||||
if (req.getRequestURI().endsWith("attach/upload")) { |
||||
return true; |
||||
} |
||||
if (req.getRequestURI().endsWith("/dataset/upload")) { |
||||
return true; |
||||
} |
||||
String op = WebUtils.getHTTPRequestParameter(req, "op"); |
||||
String cmd = WebUtils.getHTTPRequestParameter(req, "cmd"); |
||||
if (StringUtils.equals("fr_attach", op) && StringUtils.equals("ah_upload", cmd)) { |
||||
return true; |
||||
} |
||||
if (StringUtils.equals("fr_write", op) && StringUtils.equals("imp_w_excel_data", cmd)) { |
||||
return true; |
||||
} |
||||
if (StringUtils.equals("fr_mark_excel", op) && StringUtils.equals("cache_excel", cmd)) { |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
private boolean isEncode(HttpServletRequest req) { |
||||
if (req.getRequestURI().endsWith("/report/data/export")) { |
||||
return true; |
||||
} |
||||
if (req.getRequestURI().endsWith("/report/data/global/export/pdf")) { |
||||
return true; |
||||
} |
||||
if (req.getRequestURI().endsWith("/report/data/global/export/excel")) { |
||||
return true; |
||||
} |
||||
String op = WebUtils.getHTTPRequestParameter(req, "op"); |
||||
String cmd = WebUtils.getHTTPRequestParameter(req, "cmd"); |
||||
if (StringUtils.equals("fr_attach", op) && StringUtils.equals("ah_download", cmd)) { |
||||
return true; |
||||
} |
||||
if (StringUtils.equals("customcommit", op) && StringUtils.equals("downloadfile", cmd)) { |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,36 @@
|
||||
package com.hzdatalink.gsdes.util; |
||||
|
||||
import java.io.File; |
||||
import java.io.IOException; |
||||
import java.util.UUID; |
||||
|
||||
/** |
||||
* @author xx |
||||
* @date 2020/11/20 |
||||
*/ |
||||
public class FileUtil { |
||||
|
||||
/** |
||||
* 创建临时文件 |
||||
* |
||||
* @return java.io.File |
||||
**/ |
||||
public static File createTempFile() throws IOException { |
||||
return File.createTempFile("tmp" + UUID.randomUUID().toString(), null);//创建一个临时文件
|
||||
} |
||||
|
||||
/** |
||||
* 删除文件 |
||||
* |
||||
* @param file |
||||
* @return boolean |
||||
* @author Zhanying |
||||
**/ |
||||
public static boolean deleteFile(File file) { |
||||
boolean flag = file.exists() && file.isFile() && file.delete(); |
||||
// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
|
||||
return flag; |
||||
} |
||||
|
||||
|
||||
} |
Loading…
Reference in new issue