文件下载加解密

This commit is contained in:
梁琦涛
2023-11-27 13:10:23 +08:00
parent 021426ba4a
commit 12e8a8f419
5 changed files with 168 additions and 21 deletions
@@ -21,7 +21,7 @@ import java.util.Objects;
* @version 1.0 * @version 1.0
* @date 2023/11/24 11:36 * @date 2023/11/24 11:36
*/ */
//@Component @Component
public class ContentCachingWrapperFilter extends OncePerRequestFilter implements Ordered { public class ContentCachingWrapperFilter extends OncePerRequestFilter implements Ordered {
@Override @Override
@@ -40,7 +40,7 @@ public class DownloadInterceptor implements HandlerInterceptor{
*/ */
@Override @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
// downloadDecryptFileService.downloadDecryptFile(request,response,handler); downloadDecryptFileService.downloadDecryptFile(request,response,handler,"1");
} }
/** /**
@@ -48,6 +48,6 @@ public class DownloadInterceptor implements HandlerInterceptor{
*/ */
@Override @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
// downloadDecryptFileService.downloadDecryptFile(request,response,handler); downloadDecryptFileService.downloadDecryptFile(request,response,handler,null);
} }
} }
@@ -0,0 +1,117 @@
package com.jero.modules.docking.download.dto;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
/**
* @author lqt
* @version 1.0
* @date 2023/11/27 11:12
*/
public class MultipartFileDto implements MultipartFile {
private final String name;
private String originalFilename;
private String contentType;
private final byte[] content ;
/**
* Create a new MultipartFileDto with the given content.
*
* @param name the name of the file
* @param content the content of the file
*/
public MultipartFileDto(String name, byte[] content) {
this(name, "", null, content);
}
/**
* Create a new MultipartFileDto with the given content.
*
* @param name the name of the file
* @param contentStream the content of the file as stream
* @throws IOException if reading from the stream failed
*/
public MultipartFileDto(String name, InputStream contentStream) throws IOException {
this(name, "", null, FileCopyUtils.copyToByteArray(contentStream));
}
/**
* Create a new MultipartFileDto with the given content.
*
* @param name the name of the file
* @param originalFilename the original filename (as on the client's machine)
* @param contentType the content type (if known)
* @param content the content of the file
*/
public MultipartFileDto(String name, String originalFilename, String contentType, byte[] content) {
this.name = name;
this.originalFilename = (originalFilename != null ? originalFilename : "");
this.contentType = contentType;
this.content = (content != null ? content : new byte[0]);
}
/**
* Create a new MultipartFileDto with the given content.
*
* @param name the name of the file
* @param originalFilename the original filename (as on the client's machine)
* @param contentType the content type (if known)
* @param contentStream the content of the file as stream
* @throws IOException if reading from the stream failed
*/
public MultipartFileDto(String name, String originalFilename, String contentType, InputStream contentStream)
throws IOException {
this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream));
}
@Override
public String getName() {
return this.name;
}
@Override
public String getOriginalFilename() {
return this.originalFilename;
}
@Override
public String getContentType() {
return this.contentType;
}
@Override
public boolean isEmpty() {
return (this.content.length == 0);
}
@Override
public long getSize() {
return this.content.length;
}
@Override
public byte[] getBytes() throws IOException {
return this.content;
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(this.content);
}
@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
FileCopyUtils.copy(this.content, dest);
}
}
@@ -17,7 +17,8 @@ public interface DownloadDecryptFileService {
* @param request * @param request
* @param response * @param response
* @param handler * @param handler
* @param type 1 为直接返回文件流,其他为modelandview
* @return void * @return void
*/ */
void downloadDecryptFile(HttpServletRequest request, HttpServletResponse response, Object handler); void downloadDecryptFile(HttpServletRequest request, HttpServletResponse response, Object handler,String type);
} }
@@ -4,6 +4,7 @@ import com.jero.common.api.vo.ResultCommon;
import com.jero.common.exception.JeroBootException; import com.jero.common.exception.JeroBootException;
import com.jero.common.system.vo.LoginUser; import com.jero.common.system.vo.LoginUser;
import com.jero.modules.docking.download.config.ContentCachingWrapperFilter; import com.jero.modules.docking.download.config.ContentCachingWrapperFilter;
import com.jero.modules.docking.download.dto.MultipartFileDto;
import com.jero.modules.docking.download.service.DownloadDecryptFileService; import com.jero.modules.docking.download.service.DownloadDecryptFileService;
import com.jero.modules.docking.utils.IntekeyUtils; import com.jero.modules.docking.utils.IntekeyUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -27,10 +28,12 @@ import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.UUID;
/** /**
* @author lqt * @author lqt
@@ -86,25 +89,27 @@ public class DownloadDecryptFileServiceImpl implements DownloadDecryptFileServic
@Override @Override
public void downloadDecryptFile(HttpServletRequest request, HttpServletResponse response, Object handler) { public void downloadDecryptFile(HttpServletRequest request, HttpServletResponse response, Object handler,String type) {
// 判断返回值是否为文件流,否则其他接口返回值会变更成字符串,导致前端无法解析 // 判断返回值是否为文件流,否则其他接口返回值会变更成字符串,导致前端无法解析
HandlerMethod handlerMethod = (HandlerMethod) handler; HandlerMethod handlerMethod = (HandlerMethod) handler;
String responseBody = null; InputStream responseBody = null;
try { try {
String returnType = handlerMethod.getMethod().getReturnType().getName(); String returnType = handlerMethod.getMethod().getReturnType().getName();
if(!Objects.equals(returnType,"void") && !Objects.equals(returnType,"org.springframework.web.servlet.ModelAndView")){ if(!Objects.equals(returnType,"void") && !Objects.equals(returnType,"org.springframework.web.servlet.ModelAndView")){
return; return;
} }
responseBody = ContentCachingWrapperFilter.getResponseBody(response); if(Objects.equals(returnType,"void") && !Objects.equals(type,"1")){
if(StringUtils.isBlank(responseBody)){ return;
throw new JeroBootException(ResultCommon.ERROR);
} }
} catch (IOException e) { ContentCachingResponseWrapper wrapper = WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
if (wrapper != null) {
responseBody = wrapper.getContentInputStream();
}
} catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
throw new JeroBootException(ResultCommon.ERROR); throw new JeroBootException(ResultCommon.ERROR);
} }
MultipartFile file = getMultipartFile(responseBody, response);
MultipartFile file = getMultipartFile(responseBody);
// 访问路径 // 访问路径
String str = request.getRequestURI(); String str = request.getRequestURI();
@@ -114,22 +119,30 @@ public class DownloadDecryptFileServiceImpl implements DownloadDecryptFileServic
if(b){ if(b){
// 预览,进行解密 // 预览,进行解密
writeFile(response, file, null); decryptFile(response, file, null);
}else if(b1){ }else if(b1){
// 下载文件 先解密,判断组织域,加密 // 下载文件 先解密,判断组织域,加密
writeFile(response, file, null); decryptFile(response, file, null);
int scope = getScope(); int scope = getScope();
// 加密 // 加密
writeFile(response, file, scope); encryptFile(response, file, scope);
}else{ }else{
// excel 判断组织域,加密 // excel 判断组织域,加密
int scope = getScope(); int scope = getScope();
// 加密 // 加密
writeFile(response, file, scope); encryptFile(response, file, scope);
} }
} }
private void writeFile(HttpServletResponse response, MultipartFile file, Integer scope) { private void decryptFile(HttpServletResponse response, MultipartFile file, Integer scope) {
try (InputStream is = IntekeyUtils.DecryptFile(decryptUrl, decryptAppCode, decryptSecretKey, scope, file)) {
writeResponse(response, is);
} catch (Exception e) {
throw new JeroBootException(ResultCommon.ERROR);
}
}
private void encryptFile(HttpServletResponse response, MultipartFile file, Integer scope) {
try (InputStream is = IntekeyUtils.DecryptFile(encryptUrl, encryptAppCode, encryptSecretKey, scope, file)) { try (InputStream is = IntekeyUtils.DecryptFile(encryptUrl, encryptAppCode, encryptSecretKey, scope, file)) {
writeResponse(response, is); writeResponse(response, is);
} catch (Exception e) { } catch (Exception e) {
@@ -138,10 +151,25 @@ public class DownloadDecryptFileServiceImpl implements DownloadDecryptFileServic
} }
@NotNull @NotNull
private MultipartFile getMultipartFile(String responseBody) { private MultipartFile getMultipartFile(InputStream responseBody,HttpServletResponse response) {
MultipartFile file; MultipartFile file;
try (InputStream inputStream = new ByteArrayInputStream(responseBody.getBytes(StandardCharsets.UTF_8))){ try {
file = new MockMultipartFile(ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream); String contentType = response.getContentType();
String fileName = "";
String headerField = response.getHeader("Content-Disposition");
if (!StringUtils.isBlank(headerField) || headerField.contains("fileName=") || headerField.contains("filename=")){
String name = "";
if(headerField.contains("fileName=")){
name = "fileName";
}else{
name = "filename";
}
fileName = headerField.substring(headerField.lastIndexOf(name + "=") + 9);
}else {
fileName = UUID.randomUUID().toString();
}
file = new MockMultipartFile(ContentType.APPLICATION_OCTET_STREAM.toString(),fileName,contentType, responseBody);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
throw new JeroBootException(ResultCommon.ERROR); throw new JeroBootException(ResultCommon.ERROR);
@@ -152,7 +180,7 @@ public class DownloadDecryptFileServiceImpl implements DownloadDecryptFileServic
private boolean isBoolean(String str, List<String> viewUrl) { private boolean isBoolean(String str, List<String> viewUrl) {
boolean b = false; boolean b = false;
for (String s : viewUrl) { for (String s : viewUrl) {
if (s.contains(str)) { if (str.contains(s)) {
b = true; b = true;
break; break;
} }
@@ -179,6 +207,7 @@ public class DownloadDecryptFileServiceImpl implements DownloadDecryptFileServic
} }
private void writeResponse(HttpServletResponse response,InputStream is) { private void writeResponse(HttpServletResponse response,InputStream is) {
response.resetBuffer();
try (OutputStream outputStream = response.getOutputStream()) { try (OutputStream outputStream = response.getOutputStream()) {
byte[] buf = new byte[1024]; byte[] buf = new byte[1024];
int len; int len;