From 486c09b24acc987e4c1ff56bf988c562c9666f37 Mon Sep 17 00:00:00 2001 From: chenkailing <632104866@qq.com> Date: Sun, 27 Dec 2020 01:43:50 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E4=BB=B6url=E9=87=87=E7=94=A8base64?= =?UTF-8?q?=E5=8A=A0encodeURI=E5=8F=8C=E9=87=8D=E7=BC=96=E7=A0=81=EF=BC=8C?= =?UTF-8?q?=E5=BD=BB=E5=BA=95=E8=A7=A3=E5=86=B3=E5=90=84=E7=A7=8D=E5=A5=87?= =?UTF-8?q?=E8=91=A9=E6=96=87=E4=BB=B6=E5=90=8D=E5=AF=BC=E8=87=B4=E7=9A=84?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/config/freemarker_implicit.ftl | 1 + .../main/java/cn/keking/hutool/HexUtil.java | 388 ------------------ .../main/java/cn/keking/hutool/StrUtil.java | 283 ------------- .../java/cn/keking/hutool/URLEncoder.java | 232 ----------- .../main/java/cn/keking/hutool/URLUtil.java | 74 ---- .../cn/keking/service/FileHandlerService.java | 53 +-- .../service/impl/CadFilePreviewImpl.java | 12 +- .../service/impl/CompressFilePreviewImpl.java | 6 +- .../service/impl/MediaFilePreviewImpl.java | 8 +- .../service/impl/OfficeFilePreviewImpl.java | 6 +- .../service/impl/PdfFilePreviewImpl.java | 13 +- .../service/impl/PictureFilePreviewImpl.java | 8 +- .../service/impl/SimTextFilePreviewImpl.java | 8 +- .../java/cn/keking/utils/DownloadUtils.java | 34 +- .../main/java/cn/keking/utils/WebUtils.java | 60 +++ .../keking/web/controller/FileController.java | 10 +- .../controller/OnlinePreviewController.java | 18 +- .../cn/keking/web/filter/BaseUrlFilter.java | 2 +- server/src/main/resources/web/compress.ftl | 7 +- server/src/main/resources/web/index.ftl | 7 +- 20 files changed, 113 insertions(+), 1117 deletions(-) delete mode 100644 server/src/main/java/cn/keking/hutool/HexUtil.java delete mode 100644 server/src/main/java/cn/keking/hutool/StrUtil.java delete mode 100644 server/src/main/java/cn/keking/hutool/URLEncoder.java delete mode 100644 server/src/main/java/cn/keking/hutool/URLUtil.java create mode 100644 server/src/main/java/cn/keking/utils/WebUtils.java diff --git a/server/src/main/config/freemarker_implicit.ftl b/server/src/main/config/freemarker_implicit.ftl index 44f27e84..ace6f553 100644 --- a/server/src/main/config/freemarker_implicit.ftl +++ b/server/src/main/config/freemarker_implicit.ftl @@ -1,5 +1,6 @@ [#ftl] [#-- @implicitly included --] +[#-- @ftlvariable name="baseUrl" type="java.lang.String" --] [#-- @ftlvariable name="imgUrls" type="String" --] [#-- @ftlvariable name="textData" type="java.lang.String" --] [#-- @ftlvariable name="xmlContent" type="java.lang.String" --] diff --git a/server/src/main/java/cn/keking/hutool/HexUtil.java b/server/src/main/java/cn/keking/hutool/HexUtil.java deleted file mode 100644 index 34d75f8d..00000000 --- a/server/src/main/java/cn/keking/hutool/HexUtil.java +++ /dev/null @@ -1,388 +0,0 @@ -package cn.keking.hutool; - -import java.awt.*; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; - -/** - * 十六进制(简写为hex或下标16)在数学中是一种逢16进1的进位制,一般用数字0到9和字母A到F表示(其中:A~F即10~15)。
- * 例如十进制数57,在二进制写作111001,在16进制写作39。
- * 像java,c这样的语言为了区分十六进制和十进制数值,会在十六进制数的前面加上 0x,比如0x20是十进制的32,而不是十进制的20
- *

- * 参考:https://my.oschina.net/xinxingegeya/blog/287476 - * - * @author Looly - */ -public class HexUtil { - - /** - * 用于建立十六进制字符的输出的小写字符数组 - */ - private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - /** - * 用于建立十六进制字符的输出的大写字符数组 - */ - private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - - /** - * 判断给定字符串是否为16进制数
- * 如果是,需要使用对应数字类型对象的decode方法解码
- * 例如:{@code Integer.decode}方法解码int类型的16进制数字 - * - * @param value 值 - * @return 是否为16进制 - */ - public static boolean isHexNumber(String value) { - final int index = (value.startsWith("-") ? 1 : 0); - if (value.startsWith("0x", index) || value.startsWith("0X", index) || value.startsWith("#", index)) { - try { - Long.decode(value); - } catch (NumberFormatException e) { - return false; - } - return true; - } else { - return false; - } - } - - // ---------------------------------------------------------------------------------------------------- encode - - /** - * 将字节数组转换为十六进制字符数组 - * - * @param data byte[] - * @return 十六进制char[] - */ - public static char[] encodeHex(byte[] data) { - return encodeHex(data, true); - } - - /** - * 将字节数组转换为十六进制字符数组 - * - * @param str 字符串 - * @param charset 编码 - * @return 十六进制char[] - */ - public static char[] encodeHex(String str, Charset charset) { - return encodeHex(StrUtil.bytes(str, charset), true); - } - - /** - * 将字节数组转换为十六进制字符数组 - * - * @param data byte[] - * @param toLowerCase true 传换成小写格式 , false 传换成大写格式 - * @return 十六进制char[] - */ - public static char[] encodeHex(byte[] data, boolean toLowerCase) { - return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER); - } - - /** - * 将字节数组转换为十六进制字符串 - * - * @param data byte[] - * @return 十六进制String - */ - public static String encodeHexStr(byte[] data) { - return encodeHexStr(data, true); - } - - /** - * 将字节数组转换为十六进制字符串,结果为小写 - * - * @param data 被编码的字符串 - * @param charset 编码 - * @return 十六进制String - */ - public static String encodeHexStr(String data, Charset charset) { - return encodeHexStr(StrUtil.bytes(data, charset), true); - } - - /** - * 将字节数组转换为十六进制字符串,结果为小写,默认编码是UTF-8 - * - * @param data 被编码的字符串 - * @return 十六进制String - */ - public static String encodeHexStr(String data) { - return encodeHexStr(data, StandardCharsets.UTF_8); - } - - /** - * 将字节数组转换为十六进制字符串 - * - * @param data byte[] - * @param toLowerCase true 传换成小写格式 , false 传换成大写格式 - * @return 十六进制String - */ - public static String encodeHexStr(byte[] data, boolean toLowerCase) { - return encodeHexStr(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER); - } - - // ---------------------------------------------------------------------------------------------------- decode - - /** - * 将十六进制字符数组转换为字符串,默认编码UTF-8 - * - * @param hexStr 十六进制String - * @return 字符串 - */ - public static String decodeHexStr(String hexStr) { - return decodeHexStr(hexStr, StandardCharsets.UTF_8); - } - - /** - * 将十六进制字符数组转换为字符串 - * - * @param hexStr 十六进制String - * @param charset 编码 - * @return 字符串 - */ - public static String decodeHexStr(String hexStr, Charset charset) { - if (StrUtil.isEmpty(hexStr)) { - return hexStr; - } - return decodeHexStr(hexStr.toCharArray(), charset); - } - - /** - * 将十六进制字符数组转换为字符串 - * - * @param hexData 十六进制char[] - * @param charset 编码 - * @return 字符串 - */ - public static String decodeHexStr(char[] hexData, Charset charset) { - return StrUtil.str(decodeHex(hexData), charset); - } - - /** - * 将十六进制字符数组转换为字节数组 - * - * @param hexData 十六进制char[] - * @return byte[] - * @throws RuntimeException 如果源十六进制字符数组是一个奇怪的长度,将抛出运行时异常 - */ - public static byte[] decodeHex(char[] hexData) { - - int len = hexData.length; - - if ((len & 0x01) != 0) { - throw new RuntimeException("Odd number of characters."); - } - - byte[] out = new byte[len >> 1]; - - // two characters form the hex value. - for (int i = 0, j = 0; j < len; i++) { - int f = toDigit(hexData[j], j) << 4; - j++; - f = f | toDigit(hexData[j], j); - j++; - out[i] = (byte) (f & 0xFF); - } - - return out; - } - - /** - * 将十六进制字符串解码为byte[] - * - * @param hexStr 十六进制String - * @return byte[] - */ - public static byte[] decodeHex(String hexStr) { - if (StrUtil.isEmpty(hexStr)) { - return null; - } - return decodeHex(hexStr.toCharArray()); - } - - // ---------------------------------------------------------------------------------------- Color - - /** - * 将{@link Color}编码为Hex形式 - * - * @param color {@link Color} - * @return Hex字符串 - * @since 3.0.8 - */ - public static String encodeColor(Color color) { - return encodeColor(color, "#"); - } - - /** - * 将{@link Color}编码为Hex形式 - * - * @param color {@link Color} - * @param prefix 前缀字符串,可以是#、0x等 - * @return Hex字符串 - * @since 3.0.8 - */ - public static String encodeColor(Color color, String prefix) { - final StringBuilder builder = new StringBuilder(prefix); - String colorHex; - colorHex = Integer.toHexString(color.getRed()); - if (1 == colorHex.length()) { - builder.append('0'); - } - builder.append(colorHex); - colorHex = Integer.toHexString(color.getGreen()); - if (1 == colorHex.length()) { - builder.append('0'); - } - builder.append(colorHex); - colorHex = Integer.toHexString(color.getBlue()); - if (1 == colorHex.length()) { - builder.append('0'); - } - builder.append(colorHex); - return builder.toString(); - } - - /** - * 将Hex颜色值转为 - * - * @param hexColor 16进制颜色值,可以以#开头,也可以用0x开头 - * @return {@link Color} - * @since 3.0.8 - */ - public static Color decodeColor(String hexColor) { - return Color.decode(hexColor); - } - - /** - * 将指定int值转换为Unicode字符串形式,常用于特殊字符(例如汉字)转Unicode形式
- * 转换的字符串如果u后不足4位,则前面用0填充,例如: - * - *

-	 * '我' =》\u4f60
-	 * 
- * - * @param value int值,也可以是char - * @return Unicode表现形式 - */ - public static String toUnicodeHex(int value) { - final StringBuilder builder = new StringBuilder(6); - - builder.append("\\u"); - String hex = toHex(value); - int len = hex.length(); - if (len < 4) { - builder.append("0000", 0, 4 - len);// 不足4位补0 - } - builder.append(hex); - - return builder.toString(); - } - - /** - * 将指定char值转换为Unicode字符串形式,常用于特殊字符(例如汉字)转Unicode形式
- * 转换的字符串如果u后不足4位,则前面用0填充,例如: - * - *
-	 * '我' =》\u4f60
-	 * 
- * - * @param ch char值 - * @return Unicode表现形式 - * @since 4.0.1 - */ - public static String toUnicodeHex(char ch) { - return "\\u" +// - DIGITS_LOWER[(ch >> 12) & 15] +// - DIGITS_LOWER[(ch >> 8) & 15] +// - DIGITS_LOWER[(ch >> 4) & 15] +// - DIGITS_LOWER[(ch) & 15]; - } - - /** - * 转为16进制字符串 - * - * @param value int值 - * @return 16进制字符串 - * @since 4.4.1 - */ - public static String toHex(int value) { - return Integer.toHexString(value); - } - - /** - * 转为16进制字符串 - * - * @param value int值 - * @return 16进制字符串 - * @since 4.4.1 - */ - public static String toHex(long value) { - return Long.toHexString(value); - } - - /** - * 将byte值转为16进制并添加到{@link StringBuilder}中 - * - * @param builder {@link StringBuilder} - * @param b byte - * @param toLowerCase 是否使用小写 - * @since 4.4.1 - */ - public static void appendHex(StringBuilder builder, byte b, boolean toLowerCase) { - final char[] toDigits = toLowerCase ? DIGITS_LOWER : DIGITS_UPPER; - - int high = (b & 0xf0) >>> 4;//高位 - int low = b & 0x0f;//低位 - builder.append(toDigits[high]); - builder.append(toDigits[low]); - } - - // ---------------------------------------------------------------------------------------- Private method start - - /** - * 将字节数组转换为十六进制字符串 - * - * @param data byte[] - * @param toDigits 用于控制输出的char[] - * @return 十六进制String - */ - private static String encodeHexStr(byte[] data, char[] toDigits) { - return new String(encodeHex(data, toDigits)); - } - - /** - * 将字节数组转换为十六进制字符数组 - * - * @param data byte[] - * @param toDigits 用于控制输出的char[] - * @return 十六进制char[] - */ - private static char[] encodeHex(byte[] data, char[] toDigits) { - final int len = data.length; - final char[] out = new char[len << 1];//len*2 - // two characters from the hex value. - for (int i = 0, j = 0; i < len; i++) { - out[j++] = toDigits[(0xF0 & data[i]) >>> 4];// 高位 - out[j++] = toDigits[0x0F & data[i]];// 低位 - } - return out; - } - - /** - * 将十六进制字符转换成一个整数 - * - * @param ch 十六进制char - * @param index 十六进制字符在字符数组中的位置 - * @return 一个整数 - * @throws RuntimeException 当ch不是一个合法的十六进制字符时,抛出运行时异常 - */ - private static int toDigit(char ch, int index) { - int digit = Character.digit(ch, 16); - if (digit == -1) { - throw new RuntimeException("Illegal hexadecimal character " + ch + " at index " + index); - } - return digit; - } - // ---------------------------------------------------------------------------------------- Private method end -} \ No newline at end of file diff --git a/server/src/main/java/cn/keking/hutool/StrUtil.java b/server/src/main/java/cn/keking/hutool/StrUtil.java deleted file mode 100644 index 91d62c5b..00000000 --- a/server/src/main/java/cn/keking/hutool/StrUtil.java +++ /dev/null @@ -1,283 +0,0 @@ -package cn.keking.hutool; - -import java.nio.charset.Charset; - -/** - * 字符串工具类 - * - * @author xiaoleilu - * - */ -public class StrUtil { - - public static final String EMPTY = ""; - - /** - * 是否空白符
- * 空白符包括空格、制表符、全角空格和不间断空格
- * - * @see Character#isWhitespace(int) - * @see Character#isSpaceChar(int) - * @param c 字符 - * @return 是否空白符 - * @since 4.0.10 - */ - public static boolean isBlankChar(int c) { - return Character.isWhitespace(c) || Character.isSpaceChar(c) || c == '\ufeff' || c == '\u202a'; - } - - /** - * 是否空白符
- * 空白符包括空格、制表符、全角空格和不间断空格
- * - * @param c 字符 - * @return 是否空白符 - * @see Character#isWhitespace(int) - * @see Character#isSpaceChar(int) - * @since 4.0.10 - */ - public static boolean isBlankChar(char c) { - return isBlankChar((int) c); - } - - /** - * 字符串是否为空白 空白的定义如下:
- * 1、为null
- * 2、为不可见字符(如空格)
- * 3、""
- * - * @param str 被检测的字符串 - * @return 是否为空 - */ - public static boolean isBlank(CharSequence str) { - int length; - - if ((str == null) || ((length = str.length()) == 0)) { - return true; - } - - for (int i = 0; i < length; i++) { - // 只要有一个非空字符即为非空字符串 - if (false == isBlankChar(str.charAt(i))) { - return false; - } - } - - return true; - } - - /** - * 字符串是否为空,空的定义如下:
- * 1、为null
- * 2、为""
- * - * @param str 被检测的字符串 - * @return 是否为空 - */ - public static boolean isEmpty(CharSequence str) { - return str == null || str.length() == 0; - } - - /** - * 编码字符串 - * - * @param str 字符串 - * @param charset 字符集,如果此字段为空,则解码的结果取决于平台 - * @return 编码后的字节码 - */ - public static byte[] bytes(CharSequence str, Charset charset) { - if (str == null) { - return null; - } - - if (null == charset) { - return str.toString().getBytes(); - } - return str.toString().getBytes(charset); - } - - /** - * {@link CharSequence} 转为字符串,null安全 - * - * @param cs {@link CharSequence} - * @return 字符串 - */ - public static String str(CharSequence cs) { - return null == cs ? null : cs.toString(); - } - - /** - * 解码字节码 - * - * @param data 字符串 - * @param charset 字符集,如果此字段为空,则解码的结果取决于平台 - * @return 解码后的字符串 - */ - public static String str(byte[] data, Charset charset) { - if (data == null) { - return null; - } - - if (null == charset) { - return new String(data); - } - return new String(data, charset); - } - - /** - * 改进JDK subString
- * index从0开始计算,最后一个字符为-1
- * 如果from和to位置一样,返回 ""
- * 如果from或to为负数,则按照length从后向前数位置,如果绝对值大于字符串长度,则from归到0,to归到length
- * 如果经过修正的index中from大于to,则互换from和to example:
- * abcdefgh 2 3 =》 c
- * abcdefgh 2 -3 =》 cde
- * - * @param str String - * @param fromIndex 开始的index(包括) - * @param toIndex 结束的index(不包括) - * @return 字串 - */ - public static String sub(CharSequence str, int fromIndex, int toIndex) { - if (isEmpty(str)) { - return str(str); - } - int len = str.length(); - - if (fromIndex < 0) { - fromIndex = len + fromIndex; - if (fromIndex < 0) { - fromIndex = 0; - } - } else if (fromIndex > len) { - fromIndex = len; - } - - if (toIndex < 0) { - toIndex = len + toIndex; - if (toIndex < 0) { - toIndex = len; - } - } else if (toIndex > len) { - toIndex = len; - } - - if (toIndex < fromIndex) { - int tmp = fromIndex; - fromIndex = toIndex; - toIndex = tmp; - } - - if (fromIndex == toIndex) { - return EMPTY; - } - - return str.toString().substring(fromIndex, toIndex); - } - - /** - * 切割指定位置之前部分的字符串 - * - * @param string 字符串 - * @param toIndex 切割到的位置(不包括) - * @return 切割后的剩余的前半部分字符串 - */ - public static String subPre(CharSequence string, int toIndex) { - return sub(string, 0, toIndex); - } - - /** - * 切割指定位置之后部分的字符串 - * - * @param string 字符串 - * @param fromIndex 切割开始的位置(包括) - * @return 切割后后剩余的后半部分字符串 - */ - public static String subSuf(CharSequence string, int fromIndex) { - if (isEmpty(string)) { - return null; - } - return sub(string, fromIndex, string.length()); - } - - /** - * 指定范围内查找指定字符 - * - * @param str 字符串 - * @param searchChar 被查找的字符 - * @param start 起始位置,如果小于0,从0开始查找 - * @param end 终止位置,如果超过str.length()则默认查找到字符串末尾 - * @return 位置 - */ - public static int indexOf(final CharSequence str, char searchChar, int start, int end) { - final int len = str.length(); - if (start < 0 || start > len) { - start = 0; - } - if (end > len || end < 0) { - end = len; - } - for (int i = start; i < end; i++) { - if (str.charAt(i) == searchChar) { - return i; - } - } - return -1; - } - - /** - * 指定范围内查找指定字符 - * - * @param str 字符串 - * @param searchChar 被查找的字符 - * @param start 起始位置,如果小于0,从0开始查找 - * @return 位置 - */ - public static int indexOf(final CharSequence str, char searchChar, int start) { - if (str instanceof String) { - return ((String) str).indexOf(searchChar, start); - } else { - return indexOf(str, searchChar, start, -1); - } - } - - /** - * 指定范围内查找指定字符 - * - * @param str 字符串 - * @param searchChar 被查找的字符 - * @return 位置 - */ - public static int indexOf(final CharSequence str, char searchChar) { - return indexOf(str, searchChar, 0); - } - - /** - * 如果字符串是null,则返回指定默认字符串,否则返回字符串本身。 - * - *
-	 * nullToDefault(null, "default")  = "default"
-	 * nullToDefault("", "default")    = ""
-	 * nullToDefault("  ", "default")  = "  "
-	 * nullToDefault("bat", "default") = "bat"
-	 * 
- * - * @param str 要转换的字符串 - * @param defaultStr 默认字符串 - * - * @return 字符串本身或指定的默认字符串 - */ - public static String nullToDefault(CharSequence str, String defaultStr) { - return (str == null) ? defaultStr : str.toString(); - } - - /** - * 当给定字符串为null时,转换为Empty - * - * @param str 被转换的字符串 - * @return 转换后的字符串 - */ - public static String nullToEmpty(CharSequence str) { - return nullToDefault(str, EMPTY); - } -} diff --git a/server/src/main/java/cn/keking/hutool/URLEncoder.java b/server/src/main/java/cn/keking/hutool/URLEncoder.java deleted file mode 100644 index ccb2b92a..00000000 --- a/server/src/main/java/cn/keking/hutool/URLEncoder.java +++ /dev/null @@ -1,232 +0,0 @@ -package cn.keking.hutool; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Serializable; -import java.nio.charset.Charset; -import java.util.BitSet; - -/** - * URL编码,数据内容的类型是 application/x-www-form-urlencoded。 - * - *
- * 1.字符"a"-"z","A"-"Z","0"-"9",".","-","*",和"_" 都不会被编码;
- * 2.将空格转换为%20 ;
- * 3.将非文本内容转换成"%xy"的形式,xy是两位16进制的数值;
- * 4.在每个 name=value 对之间放置 & 符号。
- * 
- * - * @author looly, - * - */ -public class URLEncoder implements Serializable{ - private static final long serialVersionUID = 1L; - - // --------------------------------------------------------------------------------------------- Static method start - /** - * 默认{@link URLEncoder}
- * 默认的编码器针对URI路径编码,定义如下: - * - *
-	 * pchar = unreserved(不处理) / pct-encoded / sub-delims(子分隔符) / ":" / "@"
-	 * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
-	 * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
-	 * 
- */ - public static final URLEncoder DEFAULT = createDefault(); - - /** - * 用于查询语句的{@link URLEncoder}
- * 编码器针对URI路径编码,定义如下: - * - *
-	 * 0x20 ' ' =》 '+' 
-	 * 0x2A, 0x2D, 0x2E, 0x30 to 0x39, 0x41 to 0x5A, 0x5F, 0x61 to 0x7A as-is 
-	 * '*', '-', '.', '0' to '9', 'A' to 'Z', '_', 'a' to 'z' Also '=' and '&' 不编码
-	 * 其它编码为 %nn 形式
-	 * 
- * - * 详细见:https://www.w3.org/TR/html5/forms.html#application/x-www-form-urlencoded-encoding-algorithm - */ - public static final URLEncoder QUERY = createQuery(); - - /** - * 创建默认{@link URLEncoder}
- * 默认的编码器针对URI路径编码,定义如下: - * - *
-	 * pchar = unreserved(不处理) / pct-encoded / sub-delims(子分隔符) / ":" / "@"
-	 * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
-	 * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
-	 * 
- * - * @return {@link URLEncoder} - */ - public static URLEncoder createDefault() { - final URLEncoder encoder = new URLEncoder(); - encoder.addSafeCharacter('-'); - encoder.addSafeCharacter('.'); - encoder.addSafeCharacter('_'); - encoder.addSafeCharacter('~'); - // Add the sub-delims - encoder.addSafeCharacter('!'); - encoder.addSafeCharacter('$'); - encoder.addSafeCharacter('&'); - encoder.addSafeCharacter('\''); - encoder.addSafeCharacter('('); - encoder.addSafeCharacter(')'); - encoder.addSafeCharacter('*'); - encoder.addSafeCharacter('+'); - encoder.addSafeCharacter(','); - encoder.addSafeCharacter(';'); - encoder.addSafeCharacter('='); - // Add the remaining literals - encoder.addSafeCharacter(':'); - encoder.addSafeCharacter('@'); - // Add '/' so it isn't encoded when we encode a path - encoder.addSafeCharacter('/'); - - return encoder; - } - - /** - * 创建用于查询语句的{@link URLEncoder}
- * 编码器针对URI路径编码,定义如下: - * - *
-	 * 0x20 ' ' =》 '+' 
-	 * 0x2A, 0x2D, 0x2E, 0x30 to 0x39, 0x41 to 0x5A, 0x5F, 0x61 to 0x7A as-is 
-	 * '*', '-', '.', '0' to '9', 'A' to 'Z', '_', 'a' to 'z' Also '=' and '&' 不编码
-	 * 其它编码为 %nn 形式
-	 * 
- * - * 详细见:https://www.w3.org/TR/html5/forms.html#application/x-www-form-urlencoded-encoding-algorithm - * - * @return {@link URLEncoder} - */ - public static URLEncoder createQuery() { - final URLEncoder encoder = new URLEncoder(); - // Special encoding for space - encoder.setEncodeSpaceAsPlus(true); - // Alpha and digit are safe by default - // Add the other permitted characters - encoder.addSafeCharacter('*'); - encoder.addSafeCharacter('-'); - encoder.addSafeCharacter('.'); - encoder.addSafeCharacter('_'); - encoder.addSafeCharacter('='); - encoder.addSafeCharacter('&'); - - return encoder; - } - // --------------------------------------------------------------------------------------------- Static method end - - /** 存放安全编码 */ - private final BitSet safeCharacters; - /** 是否编码空格为+ */ - private boolean encodeSpaceAsPlus = false; - - /** - * 构造
- * - * [a-zA-Z0-9]默认不被编码 - */ - public URLEncoder() { - this(new BitSet(256)); - - for (char i = 'a'; i <= 'z'; i++) { - addSafeCharacter(i); - } - for (char i = 'A'; i <= 'Z'; i++) { - addSafeCharacter(i); - } - for (char i = '0'; i <= '9'; i++) { - addSafeCharacter(i); - } - } - - /** - * 构造 - * - * @param safeCharacters 安全字符,安全字符不被编码 - */ - private URLEncoder(BitSet safeCharacters) { - this.safeCharacters = safeCharacters; - } - - /** - * 增加安全字符
- * 安全字符不被编码 - * - * @param c 字符 - */ - public void addSafeCharacter(char c) { - safeCharacters.set(c); - } - - /** - * 移除安全字符
- * 安全字符不被编码 - * - * @param c 字符 - */ - public void removeSafeCharacter(char c) { - safeCharacters.clear(c); - } - - /** - * 是否将空格编码为+ - * - * @param encodeSpaceAsPlus 是否将空格编码为+ - */ - public void setEncodeSpaceAsPlus(boolean encodeSpaceAsPlus) { - this.encodeSpaceAsPlus = encodeSpaceAsPlus; - } - - /** - * 将URL中的字符串编码为%形式 - * - * @param path 需要编码的字符串 - * @param charset 编码 - * - * @return 编码后的字符串 - */ - public String encode(String path, Charset charset) { - - int maxBytesPerChar = 10; - final StringBuilder rewrittenPath = new StringBuilder(path.length()); - ByteArrayOutputStream buf = new ByteArrayOutputStream(maxBytesPerChar); - OutputStreamWriter writer = new OutputStreamWriter(buf, charset); - - int c; - for (int i = 0; i < path.length(); i++) { - c = path.charAt(i); - if (safeCharacters.get(c)) { - rewrittenPath.append((char) c); - } else if (encodeSpaceAsPlus && c == ' ') { - // 对于空格单独处理 - rewrittenPath.append('+'); - } else { - // convert to external encoding before hex conversion - try { - writer.write((char) c); - writer.flush(); - } catch (IOException e) { - buf.reset(); - continue; - } - - byte[] ba = buf.toByteArray(); - for (int j = 0; j < ba.length; j++) { - // Converting each byte in the buffer - byte toEncode = ba[j]; - rewrittenPath.append('%'); - HexUtil.appendHex(rewrittenPath, toEncode, false); - } - buf.reset(); - } - } - return rewrittenPath.toString(); - } -} diff --git a/server/src/main/java/cn/keking/hutool/URLUtil.java b/server/src/main/java/cn/keking/hutool/URLUtil.java deleted file mode 100644 index 80e1610e..00000000 --- a/server/src/main/java/cn/keking/hutool/URLUtil.java +++ /dev/null @@ -1,74 +0,0 @@ -package cn.keking.hutool; - -import java.nio.charset.StandardCharsets; - -/** - * 统一资源定位符相关工具类 - * - * @author xiaoleilu - * - */ -public class URLUtil { - - /** - * 标准化URL字符串,包括: - * - *
-	 * 1. 多个/替换为一个
-	 * 
- * - * @param url URL字符串 - * @return 标准化后的URL字符串 - */ - public static String normalize(String url) { - return normalize(url, false, false); - } - - /** - * 标准化URL字符串,包括: - * - *
-	 * 1. 多个/替换为一个
-	 * 
- * - * @param url URL字符串 - * @param isEncodeBody 是否对URL中body部分的中文和特殊字符做转义(不包括http:和/) - * @param isEncodeParam 是否对URL中参数部分的中文和特殊字符做转义 - * @return 标准化后的URL字符串 - * @since 4.4.1 - */ - public static String normalize(String url, boolean isEncodeBody, boolean isEncodeParam) { - if (StrUtil.isBlank(url)) { - return url; - } - final int sepIndex = url.indexOf("://"); - String pre; - String body; - if (sepIndex > 0) { - pre = StrUtil.subPre(url, sepIndex + 3); - body = StrUtil.subSuf(url, sepIndex + 3); - } else { - pre = "http://"; - body = url; - } - - final int paramsSepIndex = StrUtil.indexOf(body, '?'); - String params = null; - if (paramsSepIndex > 0) { - params = StrUtil.subSuf(body, paramsSepIndex + 1); - body = StrUtil.subPre(body, paramsSepIndex); - } - - // 去除开头的\或者/ - body = body.replaceAll("^[\\\\/]+", StrUtil.EMPTY); - // 替换多个\或/为单个/ - body = body.replace("\\", "/").replaceAll("//+", "/"); - if (isEncodeBody) { - body = URLEncoder.DEFAULT.encode(body, StandardCharsets.UTF_8); - if (params != null) { - params = "?" + URLEncoder.DEFAULT.encode(params, StandardCharsets.UTF_8); - } - } - return pre + body + StrUtil.nullToEmpty(params); - } -} \ No newline at end of file diff --git a/server/src/main/java/cn/keking/service/FileHandlerService.java b/server/src/main/java/cn/keking/service/FileHandlerService.java index 0ef434da..d6918d6f 100644 --- a/server/src/main/java/cn/keking/service/FileHandlerService.java +++ b/server/src/main/java/cn/keking/service/FileHandlerService.java @@ -4,13 +4,13 @@ import cn.keking.config.ConfigConstants; import cn.keking.model.FileAttribute; import cn.keking.model.FileType; import cn.keking.service.cache.CacheService; +import cn.keking.utils.WebUtils; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest; import java.io.*; import java.nio.charset.StandardCharsets; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -189,55 +189,6 @@ public class FileHandlerService { return fileName.substring(fileName.lastIndexOf(".") + 1); } - /** - * 获取url中的参数 - * - * @param url url - * @param name 参数名 - * @return 参数值 - */ - public String getUrlParameterReg(String url, String name) { - Map mapRequest = new HashMap<>(); - String strUrlParam = truncateUrlPage(url); - if (strUrlParam == null) { - return ""; - } - //每个键值为一组 - String[] arrSplit = strUrlParam.split("[&]"); - for (String strSplit : arrSplit) { - String[] arrSplitEqual = strSplit.split("[=]"); - //解析出键值 - if (arrSplitEqual.length > 1) { - //正确解析 - mapRequest.put(arrSplitEqual[0], arrSplitEqual[1]); - } else if (!arrSplitEqual[0].equals("")) { - //只有参数没有值,不加入 - mapRequest.put(arrSplitEqual[0], ""); - } - } - return mapRequest.get(name); - } - - /** - * 去掉url中的路径,留下请求参数部分 - * - * @param strURL url地址 - * @return url请求参数部分 - */ - private String truncateUrlPage(String strURL) { - String strAllParam = null; - strURL = strURL.trim(); - String[] arrSplit = strURL.split("[?]"); - if (strURL.length() > 1) { - if (arrSplit.length > 1) { - if (arrSplit[1] != null) { - strAllParam = arrSplit[1]; - } - } - } - return strAllParam; - } - /** * 获取文件属性 * @@ -249,7 +200,7 @@ public class FileHandlerService { String suffix; FileType type; String fileName; - String fullFileName = this.getUrlParameterReg(url, "fullfilename"); + String fullFileName = WebUtils.getUrlParameterReg(url, "fullfilename"); if (StringUtils.hasText(fullFileName)) { fileName = fullFileName; type = this.typeFromFileName(fullFileName); diff --git a/server/src/main/java/cn/keking/service/impl/CadFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/CadFilePreviewImpl.java index 2d7d0557..e16c3a64 100644 --- a/server/src/main/java/cn/keking/service/impl/CadFilePreviewImpl.java +++ b/server/src/main/java/cn/keking/service/impl/CadFilePreviewImpl.java @@ -23,19 +23,11 @@ import static cn.keking.service.impl.OfficeFilePreviewImpl.getPreviewType; public class CadFilePreviewImpl implements FilePreview { private final FileHandlerService fileHandlerService; - - private final DownloadUtils downloadUtils; - private final CadUtils cadUtils; - private final PdfUtils pdfUtils; - public CadFilePreviewImpl(FileHandlerService fileHandlerService, - DownloadUtils downloadUtils, - CadUtils cadUtils, - PdfUtils pdfUtils) { + public CadFilePreviewImpl(FileHandlerService fileHandlerService, CadUtils cadUtils, PdfUtils pdfUtils) { this.fileHandlerService = fileHandlerService; - this.downloadUtils = downloadUtils; this.cadUtils = cadUtils; this.pdfUtils = pdfUtils; @@ -58,7 +50,7 @@ public class CadFilePreviewImpl implements FilePreview { // 判断之前是否已转换过,如果转换过,直接返回,否则执行转换 if (!fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) { String filePath; - ReturnResponse response = downloadUtils.downLoad(fileAttribute, null); + ReturnResponse response = DownloadUtils.downLoad(fileAttribute, null); if (0 != response.getCode()) { model.addAttribute("fileType", suffix); model.addAttribute("msg", response.getMsg()); diff --git a/server/src/main/java/cn/keking/service/impl/CompressFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/CompressFilePreviewImpl.java index 3f28d810..e351844f 100644 --- a/server/src/main/java/cn/keking/service/impl/CompressFilePreviewImpl.java +++ b/server/src/main/java/cn/keking/service/impl/CompressFilePreviewImpl.java @@ -19,12 +19,10 @@ import org.springframework.util.StringUtils; public class CompressFilePreviewImpl implements FilePreview { private final FileHandlerService fileHandlerService; - private final DownloadUtils downloadUtils; private final CompressFileReader compressFileReader; - public CompressFilePreviewImpl(FileHandlerService fileHandlerService, DownloadUtils downloadUtils, CompressFileReader compressFileReader) { + public CompressFilePreviewImpl(FileHandlerService fileHandlerService, CompressFileReader compressFileReader) { this.fileHandlerService = fileHandlerService; - this.downloadUtils = downloadUtils; this.compressFileReader = compressFileReader; } @@ -35,7 +33,7 @@ public class CompressFilePreviewImpl implements FilePreview { String fileTree = null; // 判断文件名是否存在(redis缓存读取) if (!StringUtils.hasText(fileHandlerService.getConvertedFile(fileName)) || !ConfigConstants.isCacheEnabled()) { - ReturnResponse response = downloadUtils.downLoad(fileAttribute, fileName); + ReturnResponse response = DownloadUtils.downLoad(fileAttribute, fileName); if (0 != response.getCode()) { model.addAttribute("fileType", suffix); model.addAttribute("msg", response.getMsg()); diff --git a/server/src/main/java/cn/keking/service/impl/MediaFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/MediaFilePreviewImpl.java index c02a5ea6..d978042a 100644 --- a/server/src/main/java/cn/keking/service/impl/MediaFilePreviewImpl.java +++ b/server/src/main/java/cn/keking/service/impl/MediaFilePreviewImpl.java @@ -17,13 +17,9 @@ import org.springframework.ui.Model; @Service public class MediaFilePreviewImpl implements FilePreview { - private final DownloadUtils downloadUtils; - private final FileHandlerService fileHandlerService; - public MediaFilePreviewImpl(DownloadUtils downloadUtils, - FileHandlerService fileHandlerService) { - this.downloadUtils = downloadUtils; + public MediaFilePreviewImpl(FileHandlerService fileHandlerService) { this.fileHandlerService = fileHandlerService; } @@ -31,7 +27,7 @@ public class MediaFilePreviewImpl implements FilePreview { public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) { // 不是http开头,浏览器不能直接访问,需下载到本地 if (url != null && !url.toLowerCase().startsWith("http")) { - ReturnResponse response = downloadUtils.downLoad(fileAttribute, fileAttribute.getName()); + ReturnResponse response = DownloadUtils.downLoad(fileAttribute, fileAttribute.getName()); if (0 != response.getCode()) { model.addAttribute("fileType", fileAttribute.getSuffix()); model.addAttribute("msg", response.getMsg()); diff --git a/server/src/main/java/cn/keking/service/impl/OfficeFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/OfficeFilePreviewImpl.java index 76044bc8..dcbbd694 100644 --- a/server/src/main/java/cn/keking/service/impl/OfficeFilePreviewImpl.java +++ b/server/src/main/java/cn/keking/service/impl/OfficeFilePreviewImpl.java @@ -24,13 +24,11 @@ public class OfficeFilePreviewImpl implements FilePreview { private final FileHandlerService fileHandlerService; private final PdfUtils pdfUtils; - private final DownloadUtils downloadUtils; private final OfficeToPdfService officeToPdfService; - public OfficeFilePreviewImpl(FileHandlerService fileHandlerService, PdfUtils pdfUtils, DownloadUtils downloadUtils, OfficeToPdfService officeToPdfService) { + public OfficeFilePreviewImpl(FileHandlerService fileHandlerService, PdfUtils pdfUtils, OfficeToPdfService officeToPdfService) { this.fileHandlerService = fileHandlerService; this.pdfUtils = pdfUtils; - this.downloadUtils = downloadUtils; this.officeToPdfService = officeToPdfService; } @@ -51,7 +49,7 @@ public class OfficeFilePreviewImpl implements FilePreview { // 判断之前是否已转换过,如果转换过,直接返回,否则执行转换 if (!fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) { String filePath; - ReturnResponse response = downloadUtils.downLoad(fileAttribute, null); + ReturnResponse response = DownloadUtils.downLoad(fileAttribute, null); if (0 != response.getCode()) { model.addAttribute("fileType", suffix); model.addAttribute("msg", response.getMsg()); diff --git a/server/src/main/java/cn/keking/service/impl/PdfFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/PdfFilePreviewImpl.java index 69f5e588..b0f1bf93 100644 --- a/server/src/main/java/cn/keking/service/impl/PdfFilePreviewImpl.java +++ b/server/src/main/java/cn/keking/service/impl/PdfFilePreviewImpl.java @@ -21,19 +21,12 @@ import java.util.List; public class PdfFilePreviewImpl implements FilePreview { private final FileHandlerService fileHandlerService; - private final PdfUtils pdfUtils; - - private final DownloadUtils downloadUtils; - private static final String FILE_DIR = ConfigConstants.getFileDir(); - public PdfFilePreviewImpl(FileHandlerService fileHandlerService, - PdfUtils pdfUtils, - DownloadUtils downloadUtils) { + public PdfFilePreviewImpl(FileHandlerService fileHandlerService, PdfUtils pdfUtils) { this.fileHandlerService = fileHandlerService; this.pdfUtils = pdfUtils; - this.downloadUtils = downloadUtils; } @Override @@ -47,7 +40,7 @@ public class PdfFilePreviewImpl implements FilePreview { if (OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_ALL_IMAGES.equals(officePreviewType)) { //当文件不存在时,就去下载 if (!fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) { - ReturnResponse response = downloadUtils.downLoad(fileAttribute, fileName); + ReturnResponse response = DownloadUtils.downLoad(fileAttribute, fileName); if (0 != response.getCode()) { model.addAttribute("fileType", suffix); model.addAttribute("msg", response.getMsg()); @@ -76,7 +69,7 @@ public class PdfFilePreviewImpl implements FilePreview { // 不是http开头,浏览器不能直接访问,需下载到本地 if (url != null && !url.toLowerCase().startsWith("http")) { if (!fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) { - ReturnResponse response = downloadUtils.downLoad(fileAttribute, pdfName); + ReturnResponse response = DownloadUtils.downLoad(fileAttribute, pdfName); if (0 != response.getCode()) { model.addAttribute("fileType", suffix); model.addAttribute("msg", response.getMsg()); diff --git a/server/src/main/java/cn/keking/service/impl/PictureFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/PictureFilePreviewImpl.java index 68760951..11631676 100644 --- a/server/src/main/java/cn/keking/service/impl/PictureFilePreviewImpl.java +++ b/server/src/main/java/cn/keking/service/impl/PictureFilePreviewImpl.java @@ -20,12 +20,8 @@ public class PictureFilePreviewImpl implements FilePreview { private final FileHandlerService fileHandlerService; - private final DownloadUtils downloadUtils; - - public PictureFilePreviewImpl(FileHandlerService fileHandlerService, - DownloadUtils downloadUtils) { + public PictureFilePreviewImpl(FileHandlerService fileHandlerService) { this.fileHandlerService = fileHandlerService; - this.downloadUtils = downloadUtils; } @Override @@ -39,7 +35,7 @@ public class PictureFilePreviewImpl implements FilePreview { } // 不是http开头,浏览器不能直接访问,需下载到本地 if (url != null && !url.toLowerCase().startsWith("http")) { - ReturnResponse response = downloadUtils.downLoad(fileAttribute, null); + ReturnResponse response = DownloadUtils.downLoad(fileAttribute, null); if (0 != response.getCode()) { model.addAttribute("fileType", fileAttribute.getSuffix()); model.addAttribute("msg", response.getMsg()); 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 2d9684e7..10d7b65d 100644 --- a/server/src/main/java/cn/keking/service/impl/SimTextFilePreviewImpl.java +++ b/server/src/main/java/cn/keking/service/impl/SimTextFilePreviewImpl.java @@ -23,16 +23,10 @@ public class SimTextFilePreviewImpl implements FilePreview { public static final String TEXT_TYPE = "textType"; public static final String DEFAULT_TEXT_TYPE = "simText"; - private final DownloadUtils downloadUtils; - - public SimTextFilePreviewImpl(DownloadUtils downloadUtils) { - this.downloadUtils = downloadUtils; - } - @Override public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) { String fileName = fileAttribute.getName(); - ReturnResponse response = downloadUtils.downLoad(fileAttribute, fileName); + ReturnResponse response = DownloadUtils.downLoad(fileAttribute, fileName); if (0 != response.getCode()) { model.addAttribute("msg", response.getMsg()); model.addAttribute("fileType", fileAttribute.getSuffix()); diff --git a/server/src/main/java/cn/keking/utils/DownloadUtils.java b/server/src/main/java/cn/keking/utils/DownloadUtils.java index e158b7de..b46cac82 100644 --- a/server/src/main/java/cn/keking/utils/DownloadUtils.java +++ b/server/src/main/java/cn/keking/utils/DownloadUtils.java @@ -1,14 +1,11 @@ package cn.keking.utils; import cn.keking.config.ConfigConstants; -import cn.keking.hutool.URLUtil; import cn.keking.model.FileAttribute; import cn.keking.model.FileType; import cn.keking.model.ReturnResponse; -import cn.keking.service.FileHandlerService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; import java.io.*; import java.net.*; @@ -18,27 +15,20 @@ import java.util.UUID; /** * @author yudian-it */ -@Component public class DownloadUtils { private final static Logger logger = LoggerFactory.getLogger(DownloadUtils.class); - private final String fileDir = ConfigConstants.getFileDir(); + private static final String fileDir = ConfigConstants.getFileDir(); private static final String URL_PARAM_FTP_USERNAME = "ftp.username"; private static final String URL_PARAM_FTP_PASSWORD = "ftp.password"; private static final String URL_PARAM_FTP_CONTROL_ENCODING = "ftp.control.encoding"; - private final FileHandlerService fileHandlerService; - - public DownloadUtils(FileHandlerService fileHandlerService) { - this.fileHandlerService = fileHandlerService; - } - /** * @param fileAttribute fileAttribute * @param fileName 文件名 * @return 本地文件绝对路径 */ - public ReturnResponse downLoad(FileAttribute fileAttribute, String fileName) { + public static ReturnResponse downLoad(FileAttribute fileAttribute, String fileName) { String urlStr = fileAttribute.getUrl(); String type = fileAttribute.getSuffix(); ReturnResponse response = new ReturnResponse<>(0, "下载成功!!!", ""); @@ -60,9 +50,9 @@ public class DownloadUtils { OutputStream os = new FileOutputStream(realPath); saveBytesToOutStream(bytes, os); } else if (url.getProtocol() != null && "ftp".equalsIgnoreCase(url.getProtocol())) { - String ftpUsername = fileHandlerService.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_USERNAME); - String ftpPassword = fileHandlerService.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_PASSWORD); - String ftpControlEncoding = fileHandlerService.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_CONTROL_ENCODING); + String ftpUsername = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_USERNAME); + String ftpPassword = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_PASSWORD); + String ftpControlEncoding = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_CONTROL_ENCODING); FtpUtils.download(fileAttribute.getUrl(), realPath, ftpUsername, ftpPassword, ftpControlEncoding); } else { response.setCode(1); @@ -72,7 +62,7 @@ public class DownloadUtils { response.setContent(realPath); response.setMsg(fileName); if (FileType.simText.equals(fileAttribute.getType())) { - this.convertTextPlainFileCharsetToUtf8(realPath); + convertTextPlainFileCharsetToUtf8(realPath); } return response; } catch (IOException e) { @@ -88,10 +78,10 @@ public class DownloadUtils { } } - public byte[] getBytesFromUrl(String urlStr) throws IOException { + public static byte[] getBytesFromUrl(String urlStr) throws IOException { InputStream is = getInputStreamFromUrl(urlStr); if (is == null) { - urlStr = URLUtil.normalize(urlStr, true, true); + // urlStr = URLUtil.normalize(urlStr, true, true); is = getInputStreamFromUrl(urlStr); if (is == null) { logger.error("文件下载异常:url:{}", urlStr); @@ -101,12 +91,12 @@ public class DownloadUtils { return getBytesFromStream(is); } - public void saveBytesToOutStream(byte[] b, OutputStream os) throws IOException { + public static void saveBytesToOutStream(byte[] b, OutputStream os) throws IOException { os.write(b); os.close(); } - private InputStream getInputStreamFromUrl(String urlStr) { + private static InputStream getInputStreamFromUrl(String urlStr) { try { URL url = new URL(urlStr); URLConnection connection = url.openConnection(); @@ -120,7 +110,7 @@ public class DownloadUtils { } } - private byte[] getBytesFromStream(InputStream is) throws IOException { + private static byte[] getBytesFromStream(InputStream is) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; @@ -139,7 +129,7 @@ public class DownloadUtils { * * @param filePath 文件路径 */ - private void convertTextPlainFileCharsetToUtf8(String filePath) throws IOException { + private static void convertTextPlainFileCharsetToUtf8(String filePath) throws IOException { File sourceFile = new File(filePath); if (sourceFile.exists() && sourceFile.isFile() && sourceFile.canRead()) { String encoding = FileUtils.getFileEncode(filePath); diff --git a/server/src/main/java/cn/keking/utils/WebUtils.java b/server/src/main/java/cn/keking/utils/WebUtils.java new file mode 100644 index 00000000..1f7e6946 --- /dev/null +++ b/server/src/main/java/cn/keking/utils/WebUtils.java @@ -0,0 +1,60 @@ +package cn.keking.utils; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author : kl + * create : 2020-12-27 1:30 上午 + **/ +public class WebUtils { + /** + * 获取url中的参数 + * + * @param url url + * @param name 参数名 + * @return 参数值 + */ + public static String getUrlParameterReg(String url, String name) { + Map mapRequest = new HashMap<>(); + String strUrlParam = truncateUrlPage(url); + if (strUrlParam == null) { + return ""; + } + //每个键值为一组 + String[] arrSplit = strUrlParam.split("[&]"); + for (String strSplit : arrSplit) { + String[] arrSplitEqual = strSplit.split("[=]"); + //解析出键值 + if (arrSplitEqual.length > 1) { + //正确解析 + mapRequest.put(arrSplitEqual[0], arrSplitEqual[1]); + } else if (!arrSplitEqual[0].equals("")) { + //只有参数没有值,不加入 + mapRequest.put(arrSplitEqual[0], ""); + } + } + return mapRequest.get(name); + } + + + /** + * 去掉url中的路径,留下请求参数部分 + * + * @param strURL url地址 + * @return url请求参数部分 + */ + private static String truncateUrlPage(String strURL) { + String strAllParam = null; + strURL = strURL.trim(); + String[] arrSplit = strURL.split("[?]"); + if (strURL.length() > 1) { + if (arrSplit.length > 1) { + if (arrSplit[1] != null) { + strAllParam = arrSplit[1]; + } + } + } + return strAllParam; + } +} 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 58779c42..e6279135 100644 --- a/server/src/main/java/cn/keking/web/controller/FileController.java +++ b/server/src/main/java/cn/keking/web/controller/FileController.java @@ -52,8 +52,8 @@ public class FileController { return new ObjectMapper().writeValueAsString(new ReturnResponse(1, "存在同名文件,请先删除原有文件再次上传", null)); } File outFile = new File(fileDir + demoPath); - if (!outFile.exists()) { - outFile.mkdirs(); + if (!outFile.exists() && !outFile.mkdirs()) { + logger.error("创建文件夹【{}】失败,请检查目录权限!",fileDir + demoPath); } logger.info("上传文件:{}", fileDir + demoPath + fileName); try(InputStream in = file.getInputStream(); OutputStream out = new FileOutputStream(fileDir + demoPath + fileName)) { @@ -72,8 +72,8 @@ public class FileController { } File file = new File(fileDir + demoPath + fileName); logger.info("删除文件:{}", file.getAbsolutePath()); - if (file.exists()) { - file.delete(); + if (file.exists() && !file.delete()) { + logger.error("删除文件【{}】失败,请检查目录权限!",file.getPath()); } return new ObjectMapper().writeValueAsString(new ReturnResponse(0, "SUCCESS", null)); } @@ -84,7 +84,7 @@ public class FileController { File file = new File(fileDir + demoPath); if (file.exists()) { Arrays.stream(Objects.requireNonNull(file.listFiles())).forEach(file1 -> { - Map fileName = new HashMap(); + Map fileName = new HashMap<>(); fileName.put("fileName", demoDir + "/" + file1.getName()); list.add(fileName); }); 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 ef3a67f9..1108f678 100644 --- a/server/src/main/java/cn/keking/web/controller/OnlinePreviewController.java +++ b/server/src/main/java/cn/keking/web/controller/OnlinePreviewController.java @@ -7,10 +7,12 @@ import cn.keking.service.FilePreviewFactory; import cn.keking.service.cache.CacheService; import cn.keking.utils.DownloadUtils; import cn.keking.service.FileHandlerService; +import com.thoughtworks.xstream.core.util.Base64JavaUtilCodec; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import org.springframework.util.Base64Utils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @@ -33,22 +35,20 @@ public class OnlinePreviewController { private final FilePreviewFactory previewFactory; private final CacheService cacheService; private final FileHandlerService fileHandlerService; - private final DownloadUtils downloadUtils; - public OnlinePreviewController(FilePreviewFactory filePreviewFactory, FileHandlerService fileHandlerService, CacheService cacheService, DownloadUtils downloadUtils) { + public OnlinePreviewController(FilePreviewFactory filePreviewFactory, FileHandlerService fileHandlerService, CacheService cacheService) { this.previewFactory = filePreviewFactory; this.fileHandlerService = fileHandlerService; this.cacheService = cacheService; - this.downloadUtils = downloadUtils; } - @RequestMapping(value = "/onlinePreview") public String onlinePreview(String url, Model model, HttpServletRequest req) { - FileAttribute fileAttribute = fileHandlerService.getFileAttribute(url,req); + String fileUrl = new String(Base64Utils.decodeFromString(url)); + FileAttribute fileAttribute = fileHandlerService.getFileAttribute(fileUrl,req); FilePreview filePreview = previewFactory.get(fileAttribute); - logger.info("预览文件url:{},previewType:{}", url, fileAttribute.getType()); - return filePreview.filePreviewHandle(url, model, fileAttribute); + logger.info("预览文件url:{},previewType:{}", fileUrl, fileAttribute.getType()); + return filePreview.filePreviewHandle(fileUrl, model, fileAttribute); } @RequestMapping(value = "/picturesPreview") @@ -78,8 +78,8 @@ public class OnlinePreviewController { public void getCorsFile(String urlPath, HttpServletResponse response) { logger.info("下载跨域pdf文件url:{}", urlPath); try { - byte[] bytes = downloadUtils.getBytesFromUrl(urlPath); - downloadUtils.saveBytesToOutStream(bytes, response.getOutputStream()); + byte[] bytes = DownloadUtils.getBytesFromUrl(urlPath); + DownloadUtils.saveBytesToOutStream(bytes, response.getOutputStream()); } catch (IOException e) { logger.error("下载跨域pdf文件异常,url:{}", urlPath, e); } diff --git a/server/src/main/java/cn/keking/web/filter/BaseUrlFilter.java b/server/src/main/java/cn/keking/web/filter/BaseUrlFilter.java index 166b3306..1b2b61a2 100644 --- a/server/src/main/java/cn/keking/web/filter/BaseUrlFilter.java +++ b/server/src/main/java/cn/keking/web/filter/BaseUrlFilter.java @@ -38,7 +38,7 @@ public class BaseUrlFilter implements Filter { pathBuilder.append(request.getScheme()).append("://").append(request.getServerName()).append(":") .append(request.getServerPort()).append(((HttpServletRequest) request).getContextPath()).append("/"); String baseUrlTmp = ConfigConstants.getBaseUrl(); - if (baseUrlTmp != null && !ConfigConstants.DEFAULT_BASE_URL.equals(baseUrlTmp.toLowerCase())) { + if (baseUrlTmp != null && !ConfigConstants.DEFAULT_BASE_URL.equalsIgnoreCase(baseUrlTmp)) { if (!baseUrlTmp.endsWith("/")) { baseUrlTmp = baseUrlTmp.concat("/"); } diff --git a/server/src/main/resources/web/compress.ftl b/server/src/main/resources/web/compress.ftl index cfae2837..d94ff9a0 100644 --- a/server/src/main/resources/web/compress.ftl +++ b/server/src/main/resources/web/compress.ftl @@ -38,8 +38,11 @@ + + + @@ -36,14 +37,14 @@ 成功实现:
 var url = 'http://127.0.0.1:8080/file/test.txt'; //要预览文件的访问地址
-window.open('http://127.0.0.1:8012/onlinePreview?url='+encodeURIComponent(url));
+window.open('http://127.0.0.1:8012/onlinePreview?url='+encodeURIComponent(base64Encode(url)));
                     
新增多图片同时预览功能,接口如下:
 var fileUrl =url1+"|"+"url2";//多文件使用“|”字符隔开
-window.open('http://127.0.0.1:8012/picturesPreview?urls='+encodeURIComponent(fileUrl));
+window.open('http://127.0.0.1:8012/picturesPreview?urls='+encodeURIComponent(base64Encode(fileUrl)));
                     
@@ -195,7 +196,7 @@ window.open('http://127.0.0.1:8012/picturesPreview?urls='+encodeURIComponent(fil }).on('pre-body.bs.table', function (e,data) { // 每个data添加一列用来操作 $(data).each(function (index, item) { - item.action = "预览" + + item.action = "预览" + "删除"; }); return data;