add methods

This commit is contained in:
Looly 2021-03-26 21:50:21 +08:00
parent 6a8e5d8b6c
commit 2484c82584
8 changed files with 163 additions and 172 deletions

View File

@ -1,100 +0,0 @@
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
*
* <code>
* 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));
* </code>
*
* @param number 十进制数字从1-->1011--->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
* 根据字符 获取
* <code>
* System.out.println(encloseAlphabetByChar( 'A'));
* System.out.println(encloseAlphabetByChar( 'a'));
* System.out.println(encloseAlphabetByChar( 'z'));
* System.out.println(encloseAlphabetByChar( 'Z'))
* </code>
* @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);
}
}

View File

@ -54,6 +54,30 @@ public class UnicodeUtil {
return sb.toString();
}
/**
* 字符编码为Unicode形式
*
* @param c 被编码的字符
* @return Unicode字符串
* @since 5.6.2
* @see HexUtil#toUnicodeHex(char)
*/
public static String toUnicode(char c) {
return HexUtil.toUnicodeHex(c);
}
/**
* 字符编码为Unicode形式
*
* @param c 被编码的字符
* @return Unicode字符串
* @since 5.6.2
* @see HexUtil#toUnicodeHex(int)
*/
public static String toUnicode(int c) {
return HexUtil.toUnicodeHex(c);
}
/**
* 字符串编码为Unicode形式
*

View File

@ -366,4 +366,47 @@ public class CharUtil {
public static int digit16(int b) {
return Character.digit(b, 16);
}
/**
* 将字母数字转换为带圈的字符
* <pre>
* '1' - '①'
* 'A' - 'Ⓐ'
* 'a' - 'ⓐ'
* </pre>
*
* @param c 被转换的字符如果字符不支持转换返回原字符
* @return 转换后的字符
* @since 5.6.2
*/
public static char toCloseChar(char c){
int result = c;
if(c >='1' && c <= '9'){
result = '①' + c - '1';
} else if(c >='A' && c <= 'Z'){
result = 'Ⓐ' + c - 'A';
} else if(c >='a' && c <= 'z'){
result = 'ⓐ' + c - 'a';
}
return (char) result;
}
/**
* [1-20]数字转换为带圈的字符
* <pre>
* 1 - '①'
* 12 - '⑫'
* 20 - '⑳'
* </pre>
*
* @param number 被转换的数字
* @return 转换后的字符
* @since 5.6.2
*/
public static char toCloseByNumber(int number){
if(number > 20){
throw new IllegalArgumentException("Number must be [1-20]");
}
return (char) ('①' + number - 1);
}
}

View File

@ -262,7 +262,7 @@ public class HexUtil {
* 转换的字符串如果u后不足4位则前面用0填充例如
*
* <pre>
* '' =\u4f60
* '' =\u4f60
* </pre>
*
* @param value int值也可以是char
@ -287,7 +287,7 @@ public class HexUtil {
* 转换的字符串如果u后不足4位则前面用0填充例如
*
* <pre>
* '我' =\u4f60
* '你' ='\u4f60'
* </pre>
*
* @param ch char值

View File

@ -38,4 +38,18 @@ public class CharUtilTest {
char a3 = '\u3000';
Assert.assertTrue(CharUtil.isBlankChar(a3));
}
@Test
public void toCloseCharTest(){
Assert.assertEquals('②', CharUtil.toCloseChar('2'));
Assert.assertEquals('Ⓜ', CharUtil.toCloseChar('M'));
Assert.assertEquals('ⓡ', CharUtil.toCloseChar('r'));
}
@Test
public void toCloseByNumberTest(){
Assert.assertEquals('②', CharUtil.toCloseByNumber(2));
Assert.assertEquals('⑫', CharUtil.toCloseByNumber(12));
Assert.assertEquals('⑳', CharUtil.toCloseByNumber(20));
}
}

View File

@ -58,6 +58,7 @@ public class ServletUtil {
public static final String METHOD_TRACE = "TRACE";
// --------------------------------------------------------- getParam start
/**
* 获得所有请求参数
*
@ -92,7 +93,7 @@ public class ServletUtil {
* @since 4.0.2
*/
public static String getBody(ServletRequest request) {
try(final BufferedReader reader = request.getReader()) {
try (final BufferedReader reader = request.getReader()) {
return IoUtil.read(reader);
} catch (IOException e) {
throw new IORuntimeException(e);
@ -117,6 +118,7 @@ public class ServletUtil {
// --------------------------------------------------------- getParam end
// --------------------------------------------------------- fillBean start
/**
* ServletRequest 参数转Bean
*
@ -133,17 +135,17 @@ public class ServletUtil {
@Override
public Object value(String key, Type valueType) {
String[] values = request.getParameterValues(key);
if(ArrayUtil.isEmpty(values)){
if (ArrayUtil.isEmpty(values)) {
values = request.getParameterValues(beanName + StrUtil.DOT + key);
if(ArrayUtil.isEmpty(values)){
if (ArrayUtil.isEmpty(values)) {
return null;
}
}
if(1 == values.length){
if (1 == values.length) {
// 单值表单直接返回这个值
return values[0];
}else{
} else {
// 多值表单返回数组
return values;
}
@ -207,7 +209,7 @@ public class ServletUtil {
* @return IP地址
*/
public static String getClientIP(HttpServletRequest request, String... otherHeaderNames) {
String[] headers = { "X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR" };
String[] headers = {"X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"};
if (ArrayUtil.isNotEmpty(otherHeaderNames)) {
headers = ArrayUtil.addAll(headers, otherHeaderNames);
}
@ -276,6 +278,7 @@ public class ServletUtil {
}
// --------------------------------------------------------- Header start
/**
* 获取请求所有的头header信息
*
@ -402,6 +405,7 @@ public class ServletUtil {
// --------------------------------------------------------- Header end
// --------------------------------------------------------- Cookie start
/**
* 获得指定的Cookie
*
@ -421,7 +425,7 @@ public class ServletUtil {
*/
public static Map<String, Cookie> readCookieMap(HttpServletRequest httpServletRequest) {
final Cookie[] cookies = httpServletRequest.getCookies();
if(ArrayUtil.isEmpty(cookies)){
if (ArrayUtil.isEmpty(cookies)) {
return MapUtil.empty();
}
@ -488,6 +492,7 @@ public class ServletUtil {
// --------------------------------------------------------- Cookie end
// --------------------------------------------------------- Response start
/**
* 获得PrintWriter
*
@ -624,7 +629,7 @@ public class ServletUtil {
response.setHeader(name, (String) value);
} else if (Date.class.isAssignableFrom(value.getClass())) {
response.setDateHeader(name, ((Date) value).getTime());
} else if (value instanceof Integer || "int".equals(value.getClass().getSimpleName().toLowerCase())) {
} else if (value instanceof Integer || "int".equalsIgnoreCase(value.getClass().getSimpleName())) {
response.setIntHeader(name, (int) value);
} else {
response.setHeader(name, value.toString());

View File

@ -1,5 +1,6 @@
package cn.hutool.extra.servlet;
import org.junit.Ignore;
import org.junit.Test;
import javax.servlet.http.HttpServletResponse;
@ -8,18 +9,22 @@ import java.nio.charset.StandardCharsets;
/**
* ServletUtil工具类测试
*
* @author dazer
* @date 2021/3/24 15:02
* @see ServletUtil
*/
public class ServletUtilTest {
@Test
@Ignore
public void writeTest() {
HttpServletResponse response = null;
byte[] bytes = new String("地球是我们共同的家园,需要大家珍惜.").getBytes(StandardCharsets.UTF_8);
byte[] bytes = "地球是我们共同的家园,需要大家珍惜.".getBytes(StandardCharsets.UTF_8);
//下载文件
// 这里没法直接测试直接写到这里方便调用
//noinspection ConstantConditions
if (response != null) {
String fileName = "签名文件.pdf";
String contentType = "application/pdf";// application/octet-streamimage/jpegimage/gif