diff --git a/hutool-core/src/main/java/cn/hutool/core/text/SpecialSymbolUtil.java b/hutool-core/src/main/java/cn/hutool/core/text/SpecialSymbolUtil.java new file mode 100644 index 000000000..968b62ffa --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/text/SpecialSymbolUtil.java @@ -0,0 +1,100 @@ +package cn.hutool.core.text; + +import java.math.BigInteger; + +/** + * 符号工具类 + * @author dazer & neusoft + * @date 2021/3/26 12:21 + * 别名:Symbol or special signal or Special symbols + * 说明:获取常见的特殊符号,如:带圈数字、 + * + * {@link UnicodeUtil} + * @link 百度百科 https://baike.baidu.com/item/%E7%89%B9%E6%AE%8A%E5%AD%97%E7%AC%A6/112715?fr=aladdin + * @link 360百科 https://baike.so.com/doc/5408938-5646935.html + * @link 百科 https://www.baike.com/wikiid/3469869303298461399?prd=home_search&search_id=5bm572esa2k000&view_id=1takcxx7kjc000 + * @link coolsymbol https://coolsymbol.com/ + * @link 维基百科wikipedia https://en.wikipedia.org/wiki/List_of_Unicode_characters#Unicode_symbols + * + * @since 5.6.2 + */ +public class SpecialSymbolUtil { + public static final String UNICODE_START_CHAR = "\\u"; + private SpecialSymbolUtil(){} + + /** + * 获取带圈数字 /封闭式字母数字 ,从1-20,超过1-20报错 + * + * 0 1 2 3 4 5 6 7 8 9 A B C D E F + * U+246x ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ + * U+247x ⑰ ⑱ ⑲ ⑳ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ + * U+248x ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇ ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ + * U+249x ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛ ⒜ ⒝ ⒞ ⒟ + * U+24Ax ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ + * U+24Bx ⒰ ⒱ ⒲ ⒳ ⒴ ⒵ Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ + * U+24Cx Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ + * U+24Dx ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ + * U+24Ex ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ ⓪ ⓫ ⓬ ⓭ ⓮ ⓯ + * U+24Fx ⓰ ⓱ ⓲ ⓳ ⓴ ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿ + * @link Unicode_symbols https://en.wikipedia.org/wiki/List_of_Unicode_characters#Unicode_symbols + * @link Enclosed Alphanumerics https://en.wikipedia.org/wiki/Enclosed_Alphanumerics + * + * + * System.out.println(enclosedAlphanumericsStyle1ByInt(1)); + * System.out.println(enclosedAlphanumericsStyle1ByInt(2)); + * System.out.println(enclosedAlphanumericsStyle1ByInt(3)); + * System.out.println(enclosedAlphanumericsStyle1ByInt(4)); + * System.out.println(enclosedAlphanumericsStyle1ByInt(14)); + * System.out.println(enclosedAlphanumericsStyle1ByInt(18)); + * System.out.println(enclosedAlphanumericsStyle1ByInt(19)); + * System.out.println(enclosedAlphanumericsStyle1ByInt(20)); + * + * + * @param number 十进制数字,从1、-->10、11--->20 + * @return ①②③④⑤⑥⑦⑧⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳ + */ + public static String enclosedNumericsByInt(int number) { + if (number <= 0 || number > 20) { + throw new IllegalArgumentException("number取值范围是[1-20]的正整数,包含1和20"); + } + String start = "①"; + String unicodeStart = UnicodeUtil.toUnicode(start).substring(UNICODE_START_CHAR.length(), + UnicodeUtil.toUnicode(start).length() - 1); + // begin: U+246x的24 + String beginHex = unicodeStart.substring(0, 2); + // U+246x的6 + String middleHex = number >= 17 ? "7" : "6"; + // A + String endHex = Integer.toHexString(number >= 17 ? number - 17 : number - 1); + // U + 24 + 60 + String unicodeStr = UNICODE_START_CHAR + beginHex + middleHex + endHex; + return UnicodeUtil.toString(unicodeStr); + } + + /** + * 获取带圈字母 /封闭式字母 ,从a-z or A-Z + * 根据字符 获取 Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ + * + * System.out.println(encloseAlphabetByChar( 'A')); + * System.out.println(encloseAlphabetByChar( 'a')); + * System.out.println(encloseAlphabetByChar( 'z')); + * System.out.println(encloseAlphabetByChar( 'Z')) + * + * @author dazer + * @param letter 字母,不区分大小写,'a'、'b'、'c'、'd'...'x'、'y'、'z'; 'A'、'B'...'Z' + * @date 2021/3/26 18:10 + */ + public static String encloseAlphabetByChar(char letter) { + if (!(letter >= 'a' && letter <= 'z' || letter >= 'A' && letter <= 'Z')) { + throw new IllegalArgumentException("number取值范围是[a-z]、[A-Z]的字符"); + } + // \u24b6 + String start = "Ⓐ"; + String hexStr = UnicodeUtil.toUnicode(start).substring(UNICODE_START_CHAR.length()); + int difference = letter >= 'a' && letter <= 'z' ? (letter - (int)'a') : (letter - (int)'A'); + String hex = new BigInteger(hexStr, 16).add(new BigInteger(String.valueOf(difference), 10)).toString(16); + // + String unicodeStr = UNICODE_START_CHAR + hex; + return UnicodeUtil.toString(unicodeStr); + } +} diff --git a/hutool-extra/src/main/java/cn/hutool/extra/servlet/ServletUtil.java b/hutool-extra/src/main/java/cn/hutool/extra/servlet/ServletUtil.java index 5a2e83ecb..cc61981ef 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/servlet/ServletUtil.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/servlet/ServletUtil.java @@ -43,7 +43,7 @@ import java.util.Map; /** * Servlet相关工具类封装 - * + * * @author looly * @since 3.2.0 */ @@ -60,7 +60,7 @@ public class ServletUtil { // --------------------------------------------------------- getParam start /** * 获得所有请求参数 - * + * * @param request 请求对象{@link ServletRequest} * @return Map */ @@ -71,7 +71,7 @@ public class ServletUtil { /** * 获得所有请求参数 - * + * * @param request 请求对象{@link ServletRequest} * @return Map */ @@ -86,7 +86,7 @@ public class ServletUtil { /** * 获取请求体
* 调用该方法后,getParam方法将失效 - * + * * @param request {@link ServletRequest} * @return 获得请求体 * @since 4.0.2 @@ -102,7 +102,7 @@ public class ServletUtil { /** * 获取请求体byte[]
* 调用该方法后,getParam方法将失效 - * + * * @param request {@link ServletRequest} * @return 获得请求体byte[] * @since 4.0.2 @@ -119,7 +119,7 @@ public class ServletUtil { // --------------------------------------------------------- fillBean start /** * ServletRequest 参数转Bean - * + * * @param Bean类型 * @param request ServletRequest * @param bean Bean @@ -159,7 +159,7 @@ public class ServletUtil { /** * ServletRequest 参数转Bean - * + * * @param Bean类型 * @param request {@link ServletRequest} * @param bean Bean @@ -172,7 +172,7 @@ public class ServletUtil { /** * ServletRequest 参数转Bean - * + * * @param Bean类型 * @param request ServletRequest * @param beanClass Bean Class @@ -186,10 +186,10 @@ public class ServletUtil { /** * 获取客户端IP - * + * *

* 默认检测的Header: - * + * *

 	 * 1、X-Forwarded-For
 	 * 2、X-Real-IP
@@ -201,7 +201,7 @@ public class ServletUtil {
 	 * otherHeaderNames参数用于自定义检测的Header
* 需要注意的是,使用此方法获取的客户IP地址必须在Http服务器(例如Nginx)中配置头信息,否则容易造成IP伪造。 *

- * + * * @param request 请求对象{@link HttpServletRequest} * @param otherHeaderNames 其他自定义头文件,通常在Http服务器(例如Nginx)中配置 * @return IP地址 @@ -214,15 +214,15 @@ public class ServletUtil { return getClientIPByHeader(request, headers); } - + /** * 获取客户端IP - * + * *

* headerNames参数用于自定义检测的Header
* 需要注意的是,使用此方法获取的客户IP地址必须在Http服务器(例如Nginx)中配置头信息,否则容易造成IP伪造。 *

- * + * * @param request 请求对象{@link HttpServletRequest} * @param headerNames 自定义头,通常在Http服务器(例如Nginx)中配置 * @return IP地址 @@ -243,7 +243,7 @@ public class ServletUtil { /** * 获得MultiPart表单内容,多用于获得上传的文件 在同一次请求中,此方法只能被执行一次! - * + * * @param request {@link ServletRequest} * @return MultipartFormData * @throws IORuntimeException IO异常 @@ -257,7 +257,7 @@ public class ServletUtil { * 获得multipart/form-data 表单内容
* 包括文件和普通表单数据
* 在同一次请求中,此方法只能被执行一次! - * + * * @param request {@link ServletRequest} * @param uploadSetting 上传文件的设定,包括最大文件大小、保存在内存的边界大小、临时目录、扩展名限定等 * @return MultiPart表单 @@ -278,28 +278,28 @@ public class ServletUtil { // --------------------------------------------------------- Header start /** * 获取请求所有的头(header)信息 - * + * * @param request 请求对象{@link HttpServletRequest} * @return header值 * @since 4.6.2 */ public static Map getHeaderMap(HttpServletRequest request) { final Map headerMap = new HashMap<>(); - + final Enumeration names = request.getHeaderNames(); String name; while (names.hasMoreElements()) { name = names.nextElement(); headerMap.put(name, request.getHeader(name)); } - + return headerMap; } - - + + /** * 忽略大小写获得请求header中的信息 - * + * * @param request 请求对象{@link HttpServletRequest} * @param nameIgnoreCase 忽略大小写头信息的KEY * @return header值 @@ -316,10 +316,10 @@ public class ServletUtil { return null; } - + /** * 获得请求header中的信息 - * + * * @param request 请求对象{@link HttpServletRequest} * @param name 头信息的KEY * @param charsetName 字符集 @@ -331,7 +331,7 @@ public class ServletUtil { /** * 获得请求header中的信息 - * + * * @param request 请求对象{@link HttpServletRequest} * @param name 头信息的KEY * @param charset 字符集 @@ -348,7 +348,7 @@ public class ServletUtil { /** * 客户浏览器是否为IE - * + * * @param request 请求对象{@link HttpServletRequest} * @return 客户浏览器是否为IE */ @@ -364,7 +364,7 @@ public class ServletUtil { /** * 是否为GET请求 - * + * * @param request 请求对象{@link HttpServletRequest} * @return 是否为GET请求 */ @@ -374,7 +374,7 @@ public class ServletUtil { /** * 是否为POST请求 - * + * * @param request 请求对象{@link HttpServletRequest} * @return 是否为POST请求 */ @@ -384,7 +384,7 @@ public class ServletUtil { /** * 是否为Multipart类型表单,此类型表单用于文件上传 - * + * * @param request 请求对象{@link HttpServletRequest} * @return 是否为Multipart类型表单,此类型表单用于文件上传 */ @@ -404,7 +404,7 @@ public class ServletUtil { // --------------------------------------------------------- Cookie start /** * 获得指定的Cookie - * + * * @param httpServletRequest {@link HttpServletRequest} * @param name cookie名 * @return Cookie对象 @@ -415,7 +415,7 @@ public class ServletUtil { /** * 将cookie封装到Map里面 - * + * * @param httpServletRequest {@link HttpServletRequest} * @return Cookie map */ @@ -433,7 +433,7 @@ public class ServletUtil { /** * 设定返回给客户端的Cookie - * + * * @param response 响应对象{@link HttpServletResponse} * @param cookie Servlet Cookie对象 */ @@ -443,7 +443,7 @@ public class ServletUtil { /** * 设定返回给客户端的Cookie - * + * * @param response 响应对象{@link HttpServletResponse} * @param name Cookie名 * @param value Cookie值 @@ -454,7 +454,7 @@ public class ServletUtil { /** * 设定返回给客户端的Cookie - * + * * @param response 响应对象{@link HttpServletResponse} * @param name cookie名 * @param value cookie值 @@ -476,7 +476,7 @@ public class ServletUtil { * 设定返回给客户端的Cookie
* Path: "/"
* No Domain - * + * * @param response 响应对象{@link HttpServletResponse} * @param name cookie名 * @param value cookie值 @@ -490,7 +490,7 @@ public class ServletUtil { // --------------------------------------------------------- Response start /** * 获得PrintWriter - * + * * @param response 响应对象{@link HttpServletResponse} * @return 获得PrintWriter * @throws IORuntimeException IO异常 @@ -505,7 +505,7 @@ public class ServletUtil { /** * 返回数据给客户端 - * + * * @param response 响应对象{@link HttpServletResponse} * @param text 返回的内容 * @param contentType 返回的类型 @@ -526,7 +526,7 @@ public class ServletUtil { /** * 返回文件给客户端 - * + * * @param response 响应对象{@link HttpServletResponse} * @param file 写出的文件对象 * @since 4.1.15 @@ -545,10 +545,21 @@ public class ServletUtil { /** * 返回数据给客户端 - * + * * @param response 响应对象{@link HttpServletResponse} * @param in 需要返回客户端的内容 * @param contentType 返回的类型 + * 如: + * 1、application/pdf、 + * 2、application/vnd.ms-excel、 + * 3、application/msword、 + * 4、application/vnd.ms-powerpoint + * docx、xlsx 这种 office 2007 格式 设置 MIME;网页里面docx 文件是没问题,但是下载下来了之后就变成doc格式了 + * https://blog.csdn.net/cyh2260629/article/details/73824760 + * 5、MIME_EXCELX_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + * 6、MIME_PPTX_TYPE = "application/vnd.openxmlformats-officedocument.presentationml.presentation"; + * 7、MIME_WORDX_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; + * 8、MIME_STREAM_TYPE = "application/octet-stream;charset=utf-8"; #原始字节流 * @param fileName 文件名 * @since 4.1.15 */ @@ -561,7 +572,7 @@ public class ServletUtil { /** * 返回数据给客户端 - * + * * @param response 响应对象{@link HttpServletResponse} * @param in 需要返回客户端的内容 * @param contentType 返回的类型 @@ -573,7 +584,7 @@ public class ServletUtil { /** * 返回数据给客户端 - * + * * @param response 响应对象{@link HttpServletResponse} * @param in 需要返回客户端的内容 */ @@ -583,7 +594,7 @@ public class ServletUtil { /** * 返回数据给客户端 - * + * * @param response 响应对象{@link HttpServletResponse} * @param in 需要返回客户端的内容 * @param bufferSize 缓存大小 @@ -603,7 +614,7 @@ public class ServletUtil { /** * 设置响应的Header - * + * * @param response 响应对象{@link HttpServletResponse} * @param name 名 * @param value 值,可以是String,Date, int diff --git a/hutool-extra/src/test/java/cn/hutool/extra/servlet/ServletUtilTest.java b/hutool-extra/src/test/java/cn/hutool/extra/servlet/ServletUtilTest.java new file mode 100644 index 000000000..3946869f5 --- /dev/null +++ b/hutool-extra/src/test/java/cn/hutool/extra/servlet/ServletUtilTest.java @@ -0,0 +1,30 @@ +package cn.hutool.extra.servlet; + +import org.junit.Test; + +import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; + +/** + * ServletUtil工具类测试 + * @author dazer + * @date 2021/3/24 15:02 + * @see ServletUtil + */ +public class ServletUtilTest { + @Test + public void writeTest() { + HttpServletResponse response = null; + byte[] bytes = new String("地球是我们共同的家园,需要大家珍惜.").getBytes(StandardCharsets.UTF_8); + + //下载文件 + // 这里没法直接测试,直接写到这里,方便调用; + if (response != null) { + String fileName = "签名文件.pdf"; + String contentType = "application/pdf";// application/octet-stream、image/jpeg、image/gif + response.setCharacterEncoding(StandardCharsets.UTF_8.name()); // 必须设置否则乱码; 但是 safari乱码 + ServletUtil.write(response, new ByteArrayInputStream(bytes), contentType, fileName); + } + } +}