From 12e8a8f4197dc866f64024c3fa56bcb6e7fbd4e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E7=90=A6=E6=B6=9B?= Date: Mon, 27 Nov 2023 13:10:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E4=BB=B6=E4=B8=8B=E8=BD=BD=E5=8A=A0?= =?UTF-8?q?=E8=A7=A3=E5=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/ContentCachingWrapperFilter.java | 2 +- .../download/config/DownloadInterceptor.java | 4 +- .../download/dto/MultipartFileDto.java | 117 ++++++++++++++++++ .../service/DownloadDecryptFileService.java | 3 +- .../impl/DownloadDecryptFileServiceImpl.java | 63 +++++++--- 5 files changed, 168 insertions(+), 21 deletions(-) create mode 100644 laws-modules-docking/src/main/java/com/jero/modules/docking/download/dto/MultipartFileDto.java diff --git a/laws-modules-docking/src/main/java/com/jero/modules/docking/download/config/ContentCachingWrapperFilter.java b/laws-modules-docking/src/main/java/com/jero/modules/docking/download/config/ContentCachingWrapperFilter.java index a179947a..9d73ddac 100644 --- a/laws-modules-docking/src/main/java/com/jero/modules/docking/download/config/ContentCachingWrapperFilter.java +++ b/laws-modules-docking/src/main/java/com/jero/modules/docking/download/config/ContentCachingWrapperFilter.java @@ -21,7 +21,7 @@ import java.util.Objects; * @version 1.0 * @date 2023/11/24 11:36 */ -//@Component +@Component public class ContentCachingWrapperFilter extends OncePerRequestFilter implements Ordered { @Override diff --git a/laws-modules-docking/src/main/java/com/jero/modules/docking/download/config/DownloadInterceptor.java b/laws-modules-docking/src/main/java/com/jero/modules/docking/download/config/DownloadInterceptor.java index 0b235658..d5a300c9 100644 --- a/laws-modules-docking/src/main/java/com/jero/modules/docking/download/config/DownloadInterceptor.java +++ b/laws-modules-docking/src/main/java/com/jero/modules/docking/download/config/DownloadInterceptor.java @@ -40,7 +40,7 @@ public class DownloadInterceptor implements HandlerInterceptor{ */ @Override 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 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); } } diff --git a/laws-modules-docking/src/main/java/com/jero/modules/docking/download/dto/MultipartFileDto.java b/laws-modules-docking/src/main/java/com/jero/modules/docking/download/dto/MultipartFileDto.java new file mode 100644 index 00000000..fc14023f --- /dev/null +++ b/laws-modules-docking/src/main/java/com/jero/modules/docking/download/dto/MultipartFileDto.java @@ -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); + + } +} diff --git a/laws-modules-docking/src/main/java/com/jero/modules/docking/download/service/DownloadDecryptFileService.java b/laws-modules-docking/src/main/java/com/jero/modules/docking/download/service/DownloadDecryptFileService.java index e6ae8a8a..65d4d176 100644 --- a/laws-modules-docking/src/main/java/com/jero/modules/docking/download/service/DownloadDecryptFileService.java +++ b/laws-modules-docking/src/main/java/com/jero/modules/docking/download/service/DownloadDecryptFileService.java @@ -17,7 +17,8 @@ public interface DownloadDecryptFileService { * @param request * @param response * @param handler + * @param type 1 为直接返回文件流,其他为modelandview * @return void */ - void downloadDecryptFile(HttpServletRequest request, HttpServletResponse response, Object handler); + void downloadDecryptFile(HttpServletRequest request, HttpServletResponse response, Object handler,String type); } diff --git a/laws-modules-docking/src/main/java/com/jero/modules/docking/download/service/impl/DownloadDecryptFileServiceImpl.java b/laws-modules-docking/src/main/java/com/jero/modules/docking/download/service/impl/DownloadDecryptFileServiceImpl.java index 4e688f13..5e7cb2c4 100644 --- a/laws-modules-docking/src/main/java/com/jero/modules/docking/download/service/impl/DownloadDecryptFileServiceImpl.java +++ b/laws-modules-docking/src/main/java/com/jero/modules/docking/download/service/impl/DownloadDecryptFileServiceImpl.java @@ -4,6 +4,7 @@ import com.jero.common.api.vo.ResultCommon; import com.jero.common.exception.JeroBootException; import com.jero.common.system.vo.LoginUser; 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.utils.IntekeyUtils; import lombok.extern.slf4j.Slf4j; @@ -27,10 +28,12 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; import java.util.Objects; +import java.util.UUID; /** * @author lqt @@ -86,25 +89,27 @@ public class DownloadDecryptFileServiceImpl implements DownloadDecryptFileServic @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; - String responseBody = null; + InputStream responseBody = null; try { String returnType = handlerMethod.getMethod().getReturnType().getName(); if(!Objects.equals(returnType,"void") && !Objects.equals(returnType,"org.springframework.web.servlet.ModelAndView")){ return; } - responseBody = ContentCachingWrapperFilter.getResponseBody(response); - if(StringUtils.isBlank(responseBody)){ - throw new JeroBootException(ResultCommon.ERROR); + if(Objects.equals(returnType,"void") && !Objects.equals(type,"1")){ + return; } - } catch (IOException e) { + ContentCachingResponseWrapper wrapper = WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class); + if (wrapper != null) { + responseBody = wrapper.getContentInputStream(); + } + } catch (Exception e) { e.printStackTrace(); throw new JeroBootException(ResultCommon.ERROR); } - - MultipartFile file = getMultipartFile(responseBody); + MultipartFile file = getMultipartFile(responseBody, response); // 访问路径 String str = request.getRequestURI(); @@ -114,22 +119,30 @@ public class DownloadDecryptFileServiceImpl implements DownloadDecryptFileServic if(b){ // 预览,进行解密 - writeFile(response, file, null); + decryptFile(response, file, null); }else if(b1){ // 下载文件 先解密,判断组织域,加密 - writeFile(response, file, null); + decryptFile(response, file, null); int scope = getScope(); // 加密 - writeFile(response, file, scope); + encryptFile(response, file, scope); }else{ // excel 判断组织域,加密 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)) { writeResponse(response, is); } catch (Exception e) { @@ -138,10 +151,25 @@ public class DownloadDecryptFileServiceImpl implements DownloadDecryptFileServic } @NotNull - private MultipartFile getMultipartFile(String responseBody) { + private MultipartFile getMultipartFile(InputStream responseBody,HttpServletResponse response) { MultipartFile file; - try (InputStream inputStream = new ByteArrayInputStream(responseBody.getBytes(StandardCharsets.UTF_8))){ - file = new MockMultipartFile(ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream); + try { + 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) { e.printStackTrace(); throw new JeroBootException(ResultCommon.ERROR); @@ -152,7 +180,7 @@ public class DownloadDecryptFileServiceImpl implements DownloadDecryptFileServic private boolean isBoolean(String str, List viewUrl) { boolean b = false; for (String s : viewUrl) { - if (s.contains(str)) { + if (str.contains(s)) { b = true; break; } @@ -179,6 +207,7 @@ public class DownloadDecryptFileServiceImpl implements DownloadDecryptFileServic } private void writeResponse(HttpServletResponse response,InputStream is) { + response.resetBuffer(); try (OutputStream outputStream = response.getOutputStream()) { byte[] buf = new byte[1024]; int len;