diff --git a/server/src/main/java/cn/keking/service/impl/SimTextFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/SimTextFilePreviewImpl.java index aeacc8e3..5efc2123 100644 --- a/server/src/main/java/cn/keking/service/impl/SimTextFilePreviewImpl.java +++ b/server/src/main/java/cn/keking/service/impl/SimTextFilePreviewImpl.java @@ -48,8 +48,7 @@ public class SimTextFilePreviewImpl implements FilePreview { private String textData(String baseUrll) throws IOException { File file = new File(baseUrll); if(!file.exists() || file.length() == 0) { - String line=""; - return line; + return ""; }else { String charset = EncodingDetects.getJavaEncode(baseUrll); System.out.println(charset); diff --git a/server/src/main/java/cn/keking/service/impl/TiffFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/TiffFilePreviewImpl.java index db8a1fba..560f1f02 100644 --- a/server/src/main/java/cn/keking/service/impl/TiffFilePreviewImpl.java +++ b/server/src/main/java/cn/keking/service/impl/TiffFilePreviewImpl.java @@ -8,6 +8,8 @@ import cn.keking.utils.ConvertPicUtil; import cn.keking.utils.DownloadUtils; import cn.keking.utils.WebUtils; import cn.keking.web.filter.BaseUrlFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.ui.Model; import org.springframework.util.StringUtils; @@ -18,12 +20,15 @@ import java.util.List; /** * tiff 图片文件处理 + * * @author kl (http://kailing.pub) * @since 2021/2/8 */ @Service public class TiffFilePreviewImpl implements FilePreview { + private final static Logger logger = LoggerFactory.getLogger(TiffFilePreviewImpl.class); + private final PictureFilePreviewImpl pictureFilePreview; private static final String INITIALIZE_MEMORY_SIZE = "initializeMemorySize"; //默认初始化 50MB 内存 @@ -43,25 +48,25 @@ public class TiffFilePreviewImpl implements FilePreview { tifPreviewType = tifOnLinePreviewType; } - if("tif".equalsIgnoreCase(tifPreviewType)){ + if ("tif".equalsIgnoreCase(tifPreviewType)) { - pictureFilePreview.filePreviewHandle(url,model,fileAttribute); - String fileSize = WebUtils.getUrlParameterReg(url,INITIALIZE_MEMORY_SIZE); - if(StringUtils.hasText(fileSize)){ - model.addAttribute(INITIALIZE_MEMORY_SIZE,fileSize); - }else { - model.addAttribute(INITIALIZE_MEMORY_SIZE,Long.toString(INITIALIZE_MEMORY_SIZE_VALUE_DEFAULT)); + pictureFilePreview.filePreviewHandle(url, model, fileAttribute); + String fileSize = WebUtils.getUrlParameterReg(url, INITIALIZE_MEMORY_SIZE); + if (StringUtils.hasText(fileSize)) { + model.addAttribute(INITIALIZE_MEMORY_SIZE, fileSize); + } else { + model.addAttribute(INITIALIZE_MEMORY_SIZE, Long.toString(INITIALIZE_MEMORY_SIZE_VALUE_DEFAULT)); } return TIFF_FILE_PREVIEW_PAGE; - }else if("jpg".equalsIgnoreCase(tifPreviewType) || "pdf".equalsIgnoreCase(tifPreviewType)){ + } else if ("jpg".equalsIgnoreCase(tifPreviewType) || "pdf".equalsIgnoreCase(tifPreviewType)) { String inputFileName = url.substring(url.lastIndexOf("/") + 1); String inputFileNamePrefix = inputFileName.substring(0, inputFileName.lastIndexOf(".")); String strLocalTif = fileDir + inputFileName; File fileTiff = new File(strLocalTif); // 如果本地不存在这个tif文件,则下载 - if(!fileTiff.exists()){ + if (!fileTiff.exists()) { ReturnResponse response = DownloadUtils.downLoad(fileAttribute, inputFileName); if (response.isFailure()) { return NOT_SUPPORTED_FILE_PAGE; @@ -69,22 +74,23 @@ public class TiffFilePreviewImpl implements FilePreview { } String baseUrl = BaseUrlFilter.getBaseUrl(); - if("pdf".equalsIgnoreCase(tifPreviewType)){ + if ("pdf".equalsIgnoreCase(tifPreviewType)) { // 以PDF模式预览的过程 File filePdf = new File(fileDir + inputFileNamePrefix + ".pdf"); // 如果本地不存在对应的pdf,则调用转换过程。否则直接用现有的pdf文件 - if(!filePdf.exists()){ + if (!filePdf.exists()) { filePdf = ConvertPicUtil.convertTif2Pdf(strLocalTif, fileDir + inputFileNamePrefix + ".pdf"); } // 如果pdf已经存在,则将url路径加入到对象中,返回给页面 - if(filePdf.exists()){ + assert filePdf != null; + if (filePdf.exists()) { String pdfUrl = baseUrl + inputFileNamePrefix + ".pdf"; model.addAttribute("pdfUrl", pdfUrl); return PDF_FILE_PREVIEW_PAGE; } - }else{ + } else { // 以JPG模式预览的过程 String strJpgFilePathName = fileDir + inputFileNamePrefix + ".jpg"; // 将tif转换为jpg,返回转换后的文件路径、文件名的list @@ -92,7 +98,7 @@ public class TiffFilePreviewImpl implements FilePreview { // 将返回页面的图片url的list对象 List listImageUrls = new ArrayList<>(); // 循环,拼装url的list对象 - for(String strJpg : listPic2Jpg){ + for (String strJpg : listPic2Jpg) { listImageUrls.add(baseUrl + strJpg); } @@ -101,8 +107,8 @@ public class TiffFilePreviewImpl implements FilePreview { } // 转换后的tif没用了,可以删掉了 - if(fileTiff.exists()){ - fileTiff.delete(); + if (fileTiff.exists() && !fileTiff.delete()) { + logger.error("{} 清理失败", strLocalTif); } return PICTURE_FILE_PREVIEW_PAGE; diff --git a/server/src/main/java/cn/keking/utils/ConvertPicUtil.java b/server/src/main/java/cn/keking/utils/ConvertPicUtil.java index 708723f7..701c42f4 100644 --- a/server/src/main/java/cn/keking/utils/ConvertPicUtil.java +++ b/server/src/main/java/cn/keking/utils/ConvertPicUtil.java @@ -27,6 +27,7 @@ public class ConvertPicUtil { /** * Tif 转 JPG。 + * * @param strInputFile 输入文件的路径和文件名 * @param strOutputFile 输出文件的路径和文件名 * @return boolean 是否转换成功 @@ -60,8 +61,8 @@ public class ConvertPicUtil { int intTifCount = imageDecoder.getNumPages(); logger.info("该tif文件共有【" + intTifCount + "】页"); - String strJpgPath = ""; - String strJpgUrl = ""; + String strJpgPath; + String strJpgUrl; if (intTifCount == 1) { // 如果是单页tif文件,则转换的目标文件夹就在指定的位置 strJpgPath = strOutputFile.substring(0, strOutputFile.lastIndexOf("/")); @@ -72,17 +73,17 @@ public class ConvertPicUtil { // 处理目标文件夹,如果不存在则自动创建 File fileJpgPath = new File(strJpgPath); - if (!fileJpgPath.exists()) { - fileJpgPath.mkdirs(); + if (!fileJpgPath.exists() && !fileJpgPath.mkdirs()) { + logger.error("{} 创建失败", strJpgPath); } // 循环,处理每页tif文件,转换为jpg for (int i = 0; i < intTifCount; i++) { - String strJpg = ""; - if(intTifCount == 1){ + String strJpg; + if (intTifCount == 1) { strJpg = strJpgPath + "/" + strFilePrefix + ".jpg"; strJpgUrl = strFilePrefix + ".jpg"; - }else{ + } else { strJpg = strJpgPath + "/" + i + ".jpg"; strJpgUrl = strFilePrefix + "/" + i + ".jpg"; } @@ -90,7 +91,7 @@ public class ConvertPicUtil { File fileJpg = new File(strJpg); // 如果文件不存在,则生成 - if(!fileJpg.exists()){ + if (!fileJpg.exists()) { RenderedImage renderedImage = imageDecoder.decodeAsRenderedImage(i); ParameterBlock pb = new ParameterBlock(); pb.addSource(renderedImage); @@ -102,7 +103,7 @@ public class ConvertPicUtil { renderedOp.dispose(); logger.info("每页分别保存至: " + fileJpg.getCanonicalPath()); - }else{ + } else { logger.info("JPG文件已存在: " + fileJpg.getCanonicalPath()); } @@ -118,21 +119,19 @@ public class ConvertPicUtil { try { fileSeekStream.close(); } catch (IOException e) { + logger.error(e.getMessage(), e); } - fileSeekStream = null; } } } - /** * 将Jpg图片转换为Pdf文件 * * @param strJpgFile 输入的jpg的路径和文件名 * @param strPdfFile 输出的pdf的路径和文件名 - * @return */ - public static File convertJpg2Pdf(String strJpgFile, String strPdfFile) { + public static void convertJpg2Pdf(String strJpgFile, String strPdfFile) { Document document = new Document(); // 设置文档页边距 document.setMargins(0, 0, 0, 0); @@ -157,23 +156,18 @@ public class ConvertPicUtil { document.add(image); } catch (Exception ioe) { ioe.printStackTrace(); - return null; } finally { //关闭文档 document.close(); try { + assert fos != null; fos.flush(); fos.close(); - - File filePDF = new File(strPdfFile); - return filePDF; } catch (IOException e) { e.printStackTrace(); } } - - return null; } @@ -182,7 +176,7 @@ public class ConvertPicUtil { * * @param strTifFile 输入的tif的路径和文件名 * @param strPdfFile 输出的pdf的路径和文件名 - * @return + * @return File */ public static File convertTif2Pdf(String strTifFile, String strPdfFile) { try { @@ -198,16 +192,16 @@ public class ConvertPicUtil { Image image; File filePDF; - if(intPages == 1){ + if (intPages == 1) { String strJpg = strTifFile.substring(0, strTifFile.lastIndexOf(".")) + ".jpg"; File fileJpg = new File(strJpg); List listPic2Jpg = convertTif2Jpg(strTifFile, strJpg); - if(listPic2Jpg != null && fileJpg.exists()){ - filePDF = convertJpg2Pdf(strJpg, strPdfFile); + if (listPic2Jpg != null && fileJpg.exists()) { + convertJpg2Pdf(strJpg, strPdfFile); } - }else{ + } else { for (int i = 1; i <= intPages; i++) { image = TiffImage.getTiffImage(rafa, i); // 设置页面宽高与图片一致 @@ -229,7 +223,7 @@ public class ConvertPicUtil { return filePDF; } catch (Exception e) { - System.out.println(e.toString()); + logger.error(e.getMessage(), e); } return null; } diff --git a/server/src/main/java/cn/keking/web/controller/FileController.java b/server/src/main/java/cn/keking/web/controller/FileController.java index 7fce8449..d1e9ec68 100644 --- a/server/src/main/java/cn/keking/web/controller/FileController.java +++ b/server/src/main/java/cn/keking/web/controller/FileController.java @@ -1,26 +1,33 @@ package cn.keking.web.controller; import cn.keking.config.ConfigConstants; +import cn.keking.model.ReturnResponse; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; - -import cn.keking.model.ReturnResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.StreamUtils; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; - -import java.io.*; -import java.nio.charset.StandardCharsets; -import java.util.*; import org.springframework.web.util.HtmlUtils; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + /** - * * @author yudian-it * @date 2017/12/1 */ @@ -33,7 +40,7 @@ public class FileController { private final String demoDir = "demo"; private final String demoPath = demoDir + File.separator; - @RequestMapping(value = "fileUpload", method = RequestMethod.POST) + @PostMapping("/fileUpload") public String fileUpload(@RequestParam("file") MultipartFile file) throws JsonProcessingException { if (ConfigConstants.getFileUploadDisable()) { return new ObjectMapper().writeValueAsString(ReturnResponse.failure("文件传接口已禁用")); @@ -41,8 +48,9 @@ public class FileController { // 获取文件名 String fileName = file.getOriginalFilename(); //判断是否为IE浏览器的文件名,IE浏览器下文件名会带有盘符信息 - + // escaping dangerous characters to prevent XSS + assert fileName != null; fileName = HtmlUtils.htmlEscape(fileName, StandardCharsets.UTF_8.name()); // Check for Unix-style path @@ -51,7 +59,7 @@ public class FileController { int winSep = fileName.lastIndexOf('\\'); // Cut off at latest possible point int pos = (Math.max(winSep, unixSep)); - if (pos != -1) { + if (pos != -1) { fileName = fileName.substring(pos + 1); } // 判断是否存在同名文件 @@ -60,10 +68,10 @@ public class FileController { } File outFile = new File(fileDir + demoPath); if (!outFile.exists() && !outFile.mkdirs()) { - logger.error("创建文件夹【{}】失败,请检查目录权限!",fileDir + demoPath); + logger.error("创建文件夹【{}】失败,请检查目录权限!", fileDir + demoPath); } logger.info("上传文件:{}", fileDir + demoPath + fileName); - try(InputStream in = file.getInputStream(); OutputStream out = new FileOutputStream(fileDir + demoPath + fileName)) { + try (InputStream in = file.getInputStream(); OutputStream out = new FileOutputStream(fileDir + demoPath + fileName)) { StreamUtils.copy(in, out); return new ObjectMapper().writeValueAsString(ReturnResponse.success(null)); } catch (IOException e) { @@ -72,7 +80,7 @@ public class FileController { } } - @RequestMapping(value = "deleteFile", method = RequestMethod.GET) + @GetMapping("/deleteFile") public String deleteFile(String fileName) throws JsonProcessingException { if (fileName.contains("/")) { fileName = fileName.substring(fileName.lastIndexOf("/") + 1); @@ -80,12 +88,12 @@ public class FileController { File file = new File(fileDir + demoPath + fileName); logger.info("删除文件:{}", file.getAbsolutePath()); if (file.exists() && !file.delete()) { - logger.error("删除文件【{}】失败,请检查目录权限!",file.getPath()); + logger.error("删除文件【{}】失败,请检查目录权限!", file.getPath()); } return new ObjectMapper().writeValueAsString(ReturnResponse.success()); } - @RequestMapping(value = "listFiles", method = RequestMethod.GET) + @GetMapping("/listFiles") public String getFiles() throws JsonProcessingException { List> list = new ArrayList<>(); File file = new File(fileDir + demoPath); diff --git a/server/src/main/java/cn/keking/web/controller/IndexController.java b/server/src/main/java/cn/keking/web/controller/IndexController.java index 41262e0f..0946efb5 100644 --- a/server/src/main/java/cn/keking/web/controller/IndexController.java +++ b/server/src/main/java/cn/keking/web/controller/IndexController.java @@ -1,8 +1,7 @@ package cn.keking.web.controller; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.GetMapping; /** * 页面跳转 @@ -12,12 +11,12 @@ import org.springframework.web.bind.annotation.RequestMethod; @Controller public class IndexController { - @RequestMapping(value = "/index", method = RequestMethod.GET) + @GetMapping( "/index") public String go2Index(){ return "index"; } - @RequestMapping(value = "/", method = RequestMethod.GET) + @GetMapping( "/") public String root() { return "redirect:/index"; } diff --git a/server/src/main/java/cn/keking/web/controller/OnlinePreviewController.java b/server/src/main/java/cn/keking/web/controller/OnlinePreviewController.java index 1848cada..0855dca0 100644 --- a/server/src/main/java/cn/keking/web/controller/OnlinePreviewController.java +++ b/server/src/main/java/cn/keking/web/controller/OnlinePreviewController.java @@ -16,8 +16,7 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.util.StringUtils; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.util.HtmlUtils; @@ -53,7 +52,7 @@ public class OnlinePreviewController { this.otherFilePreview = otherFilePreview; } - @RequestMapping(value = "/onlinePreview") + @GetMapping( "/onlinePreview") public String onlinePreview(String url, Model model, HttpServletRequest req) { String fileUrl; try { @@ -69,7 +68,7 @@ public class OnlinePreviewController { return filePreview.filePreviewHandle(fileUrl, model, fileAttribute); } - @RequestMapping(value = "/picturesPreview") + @GetMapping( "/picturesPreview") public String picturesPreview(String urls, Model model, HttpServletRequest req) throws UnsupportedEncodingException { String fileUrls; try { @@ -104,15 +103,16 @@ public class OnlinePreviewController { * @param urlPath url * @param response response */ - @RequestMapping(value = "/getCorsFile", method = RequestMethod.GET) + @GetMapping("/getCorsFile") public void getCorsFile(String urlPath, HttpServletResponse response) { try { urlPath = new String(Base64.decodeBase64(urlPath), StandardCharsets.UTF_8); } catch (Exception ex) { - logger.error(String.format(BASE64_DECODE_ERROR_MSG, urlPath, ex)); + logger.error(String.format(BASE64_DECODE_ERROR_MSG, urlPath),ex); return; } - if (urlPath == null || urlPath.toLowerCase().startsWith("file:") || urlPath.toLowerCase().startsWith("file%3") || !urlPath.toLowerCase().startsWith("http")) { + if (urlPath.toLowerCase().startsWith("file:") || urlPath.toLowerCase().startsWith("file%3") + || !urlPath.toLowerCase().startsWith("http")) { logger.info("读取跨域文件异常,可能存在非法访问,urlPath:{}", urlPath); return; } @@ -132,7 +132,7 @@ public class OnlinePreviewController { * * @param url 请编码后在入队 */ - @RequestMapping("/addTask") + @GetMapping("/addTask") @ResponseBody public String addQueueTask(String url) { logger.info("添加转码队列url:{}", url); diff --git a/server/src/main/java/cn/keking/web/filter/TrustHostFilter.java b/server/src/main/java/cn/keking/web/filter/TrustHostFilter.java index fc26c3cd..31784cd1 100644 --- a/server/src/main/java/cn/keking/web/filter/TrustHostFilter.java +++ b/server/src/main/java/cn/keking/web/filter/TrustHostFilter.java @@ -2,16 +2,16 @@ package cn.keking.web.filter; import cn.keking.config.ConfigConstants; import cn.keking.utils.WebUtils; -import org.apache.commons.lang3.StringUtils; -import org.springframework.core.io.ClassPathResource; -import org.springframework.util.Base64Utils; -import org.springframework.util.FileCopyUtils; - -import javax.servlet.*; import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; import java.nio.charset.StandardCharsets; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import org.springframework.core.io.ClassPathResource; +import org.springframework.util.FileCopyUtils; /** * @author chenjh