This commit is contained in:
Looly 2025-10-27 00:31:51 +08:00
parent 3cd7435541
commit ac50c13f4f
115 changed files with 685 additions and 1129 deletions

View File

@ -65,7 +65,7 @@ public class DeepSeekServiceImpl extends BaseAIService implements DeepSeekServic
@Override @Override
public void chat(List<Message> messages, Consumer<String> callback) { public void chat(List<Message> messages, Consumer<String> callback) {
Map<String, Object> paramMap = buildChatStreamRequestBody(messages); Map<String, Object> paramMap = buildChatStreamRequestBody(messages);
ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback::accept), "deepseek-chat-sse").start(); ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback), "deepseek-chat-sse").start();
} }
@Override @Override

View File

@ -74,7 +74,7 @@ public class DoubaoServiceImpl extends BaseAIService implements DoubaoService {
@Override @Override
public void chat(final List<Message> messages, final Consumer<String> callback) { public void chat(final List<Message> messages, final Consumer<String> callback) {
final Map<String, Object> paramMap = buildChatStreamRequestBody(messages); final Map<String, Object> paramMap = buildChatStreamRequestBody(messages);
ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback::accept), "doubao-chat-sse").start(); ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback), "doubao-chat-sse").start();
} }
@Override @Override
@ -87,7 +87,7 @@ public class DoubaoServiceImpl extends BaseAIService implements DoubaoService {
@Override @Override
public void chatVision(final String prompt, final List<String> images, final String detail, final Consumer<String> callback) { public void chatVision(final String prompt, final List<String> images, final String detail, final Consumer<String> callback) {
final Map<String, Object> paramMap = buildChatVisionStreamRequestBody(prompt, images, detail); final Map<String, Object> paramMap = buildChatVisionStreamRequestBody(prompt, images, detail);
ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback::accept), "doubao-chatVision-sse").start(); ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback), "doubao-chatVision-sse").start();
} }
@Override @Override
@ -128,7 +128,7 @@ public class DoubaoServiceImpl extends BaseAIService implements DoubaoService {
@Override @Override
public void botsChat(final List<Message> messages, final Consumer<String> callback) { public void botsChat(final List<Message> messages, final Consumer<String> callback) {
final Map<String, Object> paramMap = buildBotsChatStreamRequestBody(messages); final Map<String, Object> paramMap = buildBotsChatStreamRequestBody(messages);
ThreadUtil.newThread(() -> sendPostStream(BOTS_CHAT, paramMap, callback::accept), "doubao-botsChat-sse").start(); ThreadUtil.newThread(() -> sendPostStream(BOTS_CHAT, paramMap, callback), "doubao-botsChat-sse").start();
} }
@Override @Override
@ -162,7 +162,7 @@ public class DoubaoServiceImpl extends BaseAIService implements DoubaoService {
@Override @Override
public void chatContext(final List<Message> messages, final String contextId, final Consumer<String> callback) { public void chatContext(final List<Message> messages, final String contextId, final Consumer<String> callback) {
final Map<String, Object> paramMap = buildChatContentStreamRequestBody(messages, contextId); final Map<String, Object> paramMap = buildChatContentStreamRequestBody(messages, contextId);
ThreadUtil.newThread(() -> sendPostStream(CHAT_CONTEXT, paramMap, callback::accept), "doubao-chatContext-sse").start(); ThreadUtil.newThread(() -> sendPostStream(CHAT_CONTEXT, paramMap, callback), "doubao-chatContext-sse").start();
} }
@Override @Override

View File

@ -67,7 +67,7 @@ public class GrokServiceImpl extends BaseAIService implements GrokService {
@Override @Override
public void chat(List<Message> messages, Consumer<String> callback) { public void chat(List<Message> messages, Consumer<String> callback) {
Map<String, Object> paramMap = buildChatStreamRequestBody(messages); Map<String, Object> paramMap = buildChatStreamRequestBody(messages);
ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback::accept), "grok-chat-sse").start(); ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback), "grok-chat-sse").start();
} }
@Override @Override
@ -80,7 +80,7 @@ public class GrokServiceImpl extends BaseAIService implements GrokService {
@Override @Override
public void message(List<Message> messages, int maxToken, final Consumer<String> callback) { public void message(List<Message> messages, int maxToken, final Consumer<String> callback) {
Map<String, Object> paramMap = buildMessageStreamRequestBody(messages, maxToken); Map<String, Object> paramMap = buildMessageStreamRequestBody(messages, maxToken);
ThreadUtil.newThread(() -> sendPostStream(MESSAGES, paramMap, callback::accept), "grok-message-sse").start(); ThreadUtil.newThread(() -> sendPostStream(MESSAGES, paramMap, callback), "grok-message-sse").start();
} }
@Override @Override
@ -93,7 +93,7 @@ public class GrokServiceImpl extends BaseAIService implements GrokService {
@Override @Override
public void chatVision(String prompt, List<String> images, String detail, Consumer<String> callback) { public void chatVision(String prompt, List<String> images, String detail, Consumer<String> callback) {
Map<String, Object> paramMap = buildChatVisionStreamRequestBody(prompt, images, detail); Map<String, Object> paramMap = buildChatVisionStreamRequestBody(prompt, images, detail);
ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback::accept), "grok-chatVision-sse").start(); ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback), "grok-chatVision-sse").start();
} }
@Override @Override

View File

@ -71,7 +71,7 @@ public class HutoolServiceImpl extends BaseAIService implements HutoolService {
@Override @Override
public void chat(List<Message> messages,Consumer<String> callback) { public void chat(List<Message> messages,Consumer<String> callback) {
Map<String, Object> paramMap = buildChatStreamRequestBody(messages); Map<String, Object> paramMap = buildChatStreamRequestBody(messages);
ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback::accept), "hutool-chat-sse").start(); ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback), "hutool-chat-sse").start();
} }
@Override @Override
@ -85,7 +85,7 @@ public class HutoolServiceImpl extends BaseAIService implements HutoolService {
public void chatVision(String prompt, List<String> images, String detail, Consumer<String> callback) { public void chatVision(String prompt, List<String> images, String detail, Consumer<String> callback) {
Map<String, Object> paramMap = buildChatVisionStreamRequestBody(prompt, images, detail); Map<String, Object> paramMap = buildChatVisionStreamRequestBody(prompt, images, detail);
System.out.println(JSONUtil.toJsonStr(paramMap)); System.out.println(JSONUtil.toJsonStr(paramMap));
ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback::accept), "hutool-chatVision-sse").start(); ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback), "hutool-chatVision-sse").start();
} }
@Override @Override

View File

@ -84,7 +84,7 @@ public class OllamaServiceImpl extends BaseAIService implements OllamaService {
@Override @Override
public void chat(final List<Message> messages, final Consumer<String> callback) { public void chat(final List<Message> messages, final Consumer<String> callback) {
final Map<String, Object> paramMap = buildChatStreamRequestBody(messages); final Map<String, Object> paramMap = buildChatStreamRequestBody(messages);
ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback::accept), "ollama-chat-sse").start(); ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback), "ollama-chat-sse").start();
} }
@Override @Override
@ -97,7 +97,7 @@ public class OllamaServiceImpl extends BaseAIService implements OllamaService {
@Override @Override
public void generate(final String prompt, final Consumer<String> callback) { public void generate(final String prompt, final Consumer<String> callback) {
final Map<String, Object> paramMap = buildGenerateStreamRequestBody(prompt, null); final Map<String, Object> paramMap = buildGenerateStreamRequestBody(prompt, null);
ThreadUtil.newThread(() -> sendPostStream(GENERATE_ENDPOINT, paramMap, callback::accept), "ollama-generate-sse").start(); ThreadUtil.newThread(() -> sendPostStream(GENERATE_ENDPOINT, paramMap, callback), "ollama-generate-sse").start();
} }
@Override @Override
@ -110,7 +110,7 @@ public class OllamaServiceImpl extends BaseAIService implements OllamaService {
@Override @Override
public void generate(final String prompt, final String format, final Consumer<String> callback) { public void generate(final String prompt, final String format, final Consumer<String> callback) {
final Map<String, Object> paramMap = buildGenerateStreamRequestBody(prompt, format); final Map<String, Object> paramMap = buildGenerateStreamRequestBody(prompt, format);
ThreadUtil.newThread(() -> sendPostStream(GENERATE_ENDPOINT, paramMap, callback::accept), "ollama-generate-sse").start(); ThreadUtil.newThread(() -> sendPostStream(GENERATE_ENDPOINT, paramMap, callback), "ollama-generate-sse").start();
} }
@Override @Override

View File

@ -72,7 +72,7 @@ public class OpenaiServiceImpl extends BaseAIService implements OpenaiService {
@Override @Override
public void chat(List<Message> messages, Consumer<String> callback) { public void chat(List<Message> messages, Consumer<String> callback) {
Map<String, Object> paramMap = buildChatStreamRequestBody(messages); Map<String, Object> paramMap = buildChatStreamRequestBody(messages);
ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback::accept), "openai-chat-sse").start(); ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback), "openai-chat-sse").start();
} }
@Override @Override
@ -85,7 +85,7 @@ public class OpenaiServiceImpl extends BaseAIService implements OpenaiService {
@Override @Override
public void chatVision(String prompt, List<String> images, String detail, Consumer<String> callback) { public void chatVision(String prompt, List<String> images, String detail, Consumer<String> callback) {
Map<String, Object> paramMap = buildChatVisionStreamRequestBody(prompt, images, detail); Map<String, Object> paramMap = buildChatVisionStreamRequestBody(prompt, images, detail);
ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback::accept), "openai-chatVision-sse").start(); ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback), "openai-chatVision-sse").start();
} }
@Override @Override
@ -147,7 +147,7 @@ public class OpenaiServiceImpl extends BaseAIService implements OpenaiService {
@Override @Override
public void chatReasoning(List<Message> messages, String reasoningEffort, Consumer<String> callback) { public void chatReasoning(List<Message> messages, String reasoningEffort, Consumer<String> callback) {
Map<String, Object> paramMap = buildChatReasoningStreamRequestBody(messages, reasoningEffort); Map<String, Object> paramMap = buildChatReasoningStreamRequestBody(messages, reasoningEffort);
ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback::accept), "openai-chatReasoning-sse").start(); ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback), "openai-chatReasoning-sse").start();
} }
// 构建chat请求体 // 构建chat请求体

View File

@ -27,15 +27,14 @@ import cn.hutool.v7.swing.img.ImgUtil;
import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.awt.*; import java.awt.Toolkit;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertNotNull;
class HutoolServiceTest { class HutoolServiceTest {
@ -88,7 +87,7 @@ class HutoolServiceTest {
@Disabled @Disabled
void chatVision() { void chatVision() {
final String base64 = ImgUtil.toBase64DataUri(Toolkit.getDefaultToolkit().createImage("your imageUrl"), "png"); final String base64 = ImgUtil.toBase64DataUri(Toolkit.getDefaultToolkit().createImage("your imageUrl"), "png");
final String chatVision = hutoolService.chatVision("图片上有些什么?", Arrays.asList(base64)); final String chatVision = hutoolService.chatVision("图片上有些什么?", List.of(base64));
assertNotNull(chatVision); assertNotNull(chatVision);
} }
@ -96,7 +95,7 @@ class HutoolServiceTest {
@Disabled @Disabled
void testChatVisionStream() { void testChatVisionStream() {
String prompt = "图片上有些什么?"; String prompt = "图片上有些什么?";
List<String> images = Arrays.asList("https://img2.baidu.com/it/u=862000265,4064861820&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1544"); List<String> images = List.of("https://img2.baidu.com/it/u=862000265,4064861820&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1544");
// 使用AtomicBoolean作为结束标志 // 使用AtomicBoolean作为结束标志
AtomicBoolean isDone = new AtomicBoolean(false); AtomicBoolean isDone = new AtomicBoolean(false);
@ -119,7 +118,7 @@ class HutoolServiceTest {
@Test @Test
@Disabled @Disabled
void testChatVision() { void testChatVision() {
final String chatVision = hutoolService.chatVision("图片上有些什么?", Arrays.asList("https://img2.baidu.com/it/u=862000265,4064861820&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1544")); final String chatVision = hutoolService.chatVision("图片上有些什么?", List.of("https://img2.baidu.com/it/u=862000265,4064861820&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1544"));
assertNotNull(chatVision); assertNotNull(chatVision);
} }
@ -150,10 +149,11 @@ class HutoolServiceTest {
void textToSpeech() { void textToSpeech() {
try { try {
// 测试正常音频流返回 // 测试正常音频流返回
final InputStream inputStream = hutoolService.tts("万里山河一夜白,\n" + final InputStream inputStream = hutoolService.tts("""
"千峰尽染玉龙哀。\n" + 万里山河一夜白
"长风卷起琼花碎,\n" + 千峰尽染玉龙哀
"直上九霄揽月来。", HutoolCommon.HutoolSpeech.NOVA); 长风卷起琼花碎
直上九霄揽月来""", HutoolCommon.HutoolSpeech.NOVA);
assertNotNull(inputStream); assertNotNull(inputStream);
// 保存音频文件 // 保存音频文件

View File

@ -88,7 +88,7 @@ public class CacheObjIterator<K, V> implements Iterator<CacheObj<K, V>>, Seriali
private void nextValue() { private void nextValue() {
while (iterator.hasNext()) { while (iterator.hasNext()) {
nextValue = iterator.next(); nextValue = iterator.next();
if (nextValue.isExpired() == false) { if (!nextValue.isExpired()) {
return; return;
} }
} }

View File

@ -84,7 +84,7 @@ public class LFUCache<K, V> extends LockedCache<K, V> {
CacheObj<K, V> co; CacheObj<K, V> co;
while (values.hasNext()) { while (values.hasNext()) {
co = values.next(); co = values.next();
if (co.isExpired() == true) { if (co.isExpired()) {
values.remove(); values.remove();
onRemove(co.key, co.obj); onRemove(co.key, co.obj);
count++; count++;

View File

@ -79,7 +79,7 @@ public class LRUCache<K, V> extends LockedCache<K, V> {
*/ */
@Override @Override
protected int pruneCache() { protected int pruneCache() {
if (isPruneExpiredActive() == false) { if (!isPruneExpiredActive()) {
return 0; return 0;
} }
int count = 0; int count = 0;

View File

@ -377,7 +377,7 @@ public class Hashids implements Encoder<long[], String>, Decoder<String, long[]>
} }
} }
if (block.length() > 0) { if (!block.isEmpty()) {
// create the salt // create the salt
if (saltLeft > 0) { if (saltLeft > 0) {
System.arraycopy(currentAlphabet, 0, decodeSalt, System.arraycopy(currentAlphabet, 0, decodeSalt,

View File

@ -73,7 +73,6 @@ public class Luhn {
final char[] strArray = str.toCharArray(); final char[] strArray = str.toCharArray();
final int n = strArray.length; final int n = strArray.length;
int sum = strArray[n - 1] - '0'; int sum = strArray[n - 1] - '0';
;
for (int i = 2; i <= n; i++) { for (int i = 2; i <= n; i++) {
int a = strArray[n - i] - '0'; int a = strArray[n - i] - '0';
// 偶数位乘以2 // 偶数位乘以2

View File

@ -55,7 +55,7 @@ public class PunyCode {
final List<String> split = SplitUtil.split(domain, StrUtil.DOT); final List<String> split = SplitUtil.split(domain, StrUtil.DOT);
final StringBuilder result = new StringBuilder(domain.length() * 4); final StringBuilder result = new StringBuilder(domain.length() * 4);
for (final String str : split) { for (final String str : split) {
if (result.length() != 0) { if (!result.isEmpty()) {
result.append(CharUtil.DOT); result.append(CharUtil.DOT);
} }
result.append(encode(str, true)); result.append(encode(str, true));
@ -175,7 +175,7 @@ public class PunyCode {
final List<String> split = SplitUtil.split(domain, StrUtil.DOT); final List<String> split = SplitUtil.split(domain, StrUtil.DOT);
final StringBuilder result = new StringBuilder(domain.length() / 4 + 1); final StringBuilder result = new StringBuilder(domain.length() / 4 + 1);
for (final String str : split) { for (final String str : split) {
if (result.length() != 0) { if (!result.isEmpty()) {
result.append(CharUtil.DOT); result.append(CharUtil.DOT);
} }
result.append(StrUtil.startWithIgnoreEquals(str, PUNY_CODE_PREFIX) ? decode(str) : str); result.append(StrUtil.startWithIgnoreEquals(str, PUNY_CODE_PREFIX) ? decode(str) : str);

View File

@ -321,14 +321,9 @@ public class Base64 {
} }
private static boolean isWhiteSpace(final byte byteToCheck) { private static boolean isWhiteSpace(final byte byteToCheck) {
switch (byteToCheck) { return switch (byteToCheck) {
case ' ': case ' ', '\n', '\r', '\t' -> true;
case '\n': default -> false;
case '\r': };
case '\t':
return true;
default:
return false;
}
} }
} }

View File

@ -23,7 +23,7 @@ import java.util.Objects;
/** /**
* Crockford`s Base32实现<br> * Crockford`s Base32实现<br>
* 来自https://gist.github.com/markov/5206312 * 来自<a href="https://gist.github.com/markov/5206312">markov/5206312</a>
* *
* <p>Provides Base32 encoding and decoding as defined by <a href="http://www.ietf.org/rfc/rfc4648.txt">RFC 4648</a>. * <p>Provides Base32 encoding and decoding as defined by <a href="http://www.ietf.org/rfc/rfc4648.txt">RFC 4648</a>.
* However it uses a custom alphabet first coined by Douglas Crockford. Only addition to the alphabet is that 'u' and * However it uses a custom alphabet first coined by Douglas Crockford. Only addition to the alphabet is that 'u' and
@ -141,15 +141,10 @@ public class CrockfordBase32Codec {
* @return true if byte is whitespace, false otherwise * @return true if byte is whitespace, false otherwise
*/ */
protected static boolean isWhiteSpace(final byte byteToCheck) { protected static boolean isWhiteSpace(final byte byteToCheck) {
switch (byteToCheck) { return switch (byteToCheck) {
case ' ': case ' ', '\n', '\r', '\t' -> true;
case '\n': default -> false;
case '\r': };
case '\t':
return true;
default:
return false;
}
} }
/** /**
@ -609,128 +604,40 @@ public class CrockfordBase32Codec {
} }
private static byte decode(final byte octet) { private static byte decode(final byte octet) {
switch (octet) { return switch (octet) {
case '0': case '0', 'O', 'o' -> 0;
case 'O': case '1', 'I', 'i', 'L', 'l' -> 1;
case 'o': case '2' -> 2;
return 0; case '3' -> 3;
case '4' -> 4;
case '1': case '5' -> 5;
case 'I': case '6' -> 6;
case 'i': case '7' -> 7;
case 'L': case '8' -> 8;
case 'l': case '9' -> 9;
return 1; case 'A', 'a' -> 10;
case 'B', 'b' -> 11;
case '2': case 'C', 'c' -> 12;
return 2; case 'D', 'd' -> 13;
case '3': case 'E', 'e' -> 14;
return 3; case 'F', 'f' -> 15;
case '4': case 'G', 'g' -> 16;
return 4; case 'H', 'h' -> 17;
case '5': case 'J', 'j' -> 18;
return 5; case 'K', 'k' -> 19;
case '6': case 'M', 'm' -> 20;
return 6; case 'N', 'n' -> 21;
case '7': case 'P', 'p' -> 22;
return 7; case 'Q', 'q' -> 23;
case '8': case 'R', 'r' -> 24;
return 8; case 'S', 's' -> 25;
case '9': case 'T', 't' -> 26;
return 9; case 'U', 'u', 'V', 'v' -> 27;
case 'W', 'w' -> 28;
case 'A': case 'X', 'x' -> 29;
case 'a': case 'Y', 'y' -> 30;
return 10; case 'Z', 'z' -> 31;
default -> -1;
case 'B': };
case 'b':
return 11;
case 'C':
case 'c':
return 12;
case 'D':
case 'd':
return 13;
case 'E':
case 'e':
return 14;
case 'F':
case 'f':
return 15;
case 'G':
case 'g':
return 16;
case 'H':
case 'h':
return 17;
case 'J':
case 'j':
return 18;
case 'K':
case 'k':
return 19;
case 'M':
case 'm':
return 20;
case 'N':
case 'n':
return 21;
case 'P':
case 'p':
return 22;
case 'Q':
case 'q':
return 23;
case 'R':
case 'r':
return 24;
case 'S':
case 's':
return 25;
case 'T':
case 't':
return 26;
case 'U':
case 'u':
case 'V':
case 'v':
return 27;
case 'W':
case 'w':
return 28;
case 'X':
case 'x':
return 29;
case 'Y':
case 'y':
return 30;
case 'Z':
case 'z':
return 31;
default:
return -1;
}
} }
} }

View File

@ -101,11 +101,7 @@ public class Z85Codec implements Encoder<byte[], String>, Decoder<String, byte[]
public byte[] decode(String encoded) { public byte[] decode(String encoded) {
final int remainder = encoded.length() % 5; final int remainder = encoded.length() % 5;
final int padding = 5 - (remainder == 0 ? 5 : remainder); final int padding = 5 - (remainder == 0 ? 5 : remainder);
final StringBuilder encodedBuilder = new StringBuilder(encoded); encoded = encoded + String.valueOf(encodeTable[encodeTable.length - 1]).repeat(padding);
for (int p = 0; p < padding; ++p) {
encodedBuilder.append(encodeTable[encodeTable.length - 1]);
}
encoded = encodedBuilder.toString();
final int length = encoded.length(); final int length = encoded.length();
final byte[] bytes = new byte[((length << 2) / 5) - padding]; final byte[] bytes = new byte[((length << 2) / 5) - padding];
long value = 0; long value = 0;

View File

@ -361,32 +361,20 @@ public class CIN {
* @return 校验位 * @return 校验位
*/ */
private static char getVerifyCode18(final int iSum) { private static char getVerifyCode18(final int iSum) {
switch (iSum % 11) { return switch (iSum % 11) {
case 10: case 10 -> '2';
return '2'; case 9 -> '3';
case 9: case 8 -> '4';
return '3'; case 7 -> '5';
case 8: case 6 -> '6';
return '4'; case 5 -> '7';
case 7: case 4 -> '8';
return '5'; case 3 -> '9';
case 6: case 2 -> 'X';
return '6'; case 1 -> '0';
case 5: case 0 -> '1';
return '7'; default -> CharUtil.SPACE;
case 4: };
return '8';
case 3:
return '9';
case 2:
return 'X';
case 1:
return '0';
case 0:
return '1';
default:
return CharUtil.SPACE;
}
} }
/** /**

View File

@ -256,51 +256,18 @@ public class VIN {
* @return 对应值 * @return 对应值
*/ */
private static int getVinValue(final char vinCodeChar) { private static int getVinValue(final char vinCodeChar) {
switch (vinCodeChar) { return switch (vinCodeChar) {
case '0': case '0' -> 0;
return 0; case '1', 'J', 'A' -> 1;
case '1': case '2', 'S', 'K', 'B' -> 2;
case 'J': case '3', 'T', 'L', 'C' -> 3;
case 'A': case '4', 'U', 'M', 'D' -> 4;
return 1; case '5', 'V', 'N', 'E' -> 5;
case '2': case '6', 'W', 'F' -> 6;
case 'S': case '7', 'P', 'X', 'G' -> 7;
case 'K': case '8', 'Y', 'H' -> 8;
case 'B': case '9', 'Z', 'R' -> 9;
return 2; default -> throw new IllegalArgumentException("Invalid VIN char: " + vinCodeChar);
case '3': };
case 'T':
case 'L':
case 'C':
return 3;
case '4':
case 'U':
case 'M':
case 'D':
return 4;
case '5':
case 'V':
case 'N':
case 'E':
return 5;
case '6':
case 'W':
case 'F':
return 6;
case '7':
case 'P':
case 'X':
case 'G':
return 7;
case '8':
case 'Y':
case 'H':
return 8;
case '9':
case 'Z':
case 'R':
return 9;
}
throw new IllegalArgumentException("Invalid VIN char: " + vinCodeChar);
} }
} }

View File

@ -140,39 +140,23 @@ public enum DateField {
* @return DateField * @return DateField
*/ */
public static DateField of(final int calendarPartIntValue) { public static DateField of(final int calendarPartIntValue) {
switch (calendarPartIntValue) { return switch (calendarPartIntValue) {
case Calendar.ERA: case Calendar.ERA -> ERA;
return ERA; case Calendar.YEAR -> YEAR;
case Calendar.YEAR: case Calendar.MONTH -> MONTH;
return YEAR; case Calendar.WEEK_OF_YEAR -> WEEK_OF_YEAR;
case Calendar.MONTH: case Calendar.WEEK_OF_MONTH -> WEEK_OF_MONTH;
return MONTH; case Calendar.DAY_OF_MONTH -> DAY_OF_MONTH;
case Calendar.WEEK_OF_YEAR: case Calendar.DAY_OF_YEAR -> DAY_OF_YEAR;
return WEEK_OF_YEAR; case Calendar.DAY_OF_WEEK -> DAY_OF_WEEK;
case Calendar.WEEK_OF_MONTH: case Calendar.DAY_OF_WEEK_IN_MONTH -> DAY_OF_WEEK_IN_MONTH;
return WEEK_OF_MONTH; case Calendar.AM_PM -> AM_PM;
case Calendar.DAY_OF_MONTH: case Calendar.HOUR -> HOUR;
return DAY_OF_MONTH; case Calendar.HOUR_OF_DAY -> HOUR_OF_DAY;
case Calendar.DAY_OF_YEAR: case Calendar.MINUTE -> MINUTE;
return DAY_OF_YEAR; case Calendar.SECOND -> SECOND;
case Calendar.DAY_OF_WEEK: case Calendar.MILLISECOND -> MILLISECOND;
return DAY_OF_WEEK; default -> null;
case Calendar.DAY_OF_WEEK_IN_MONTH: };
return DAY_OF_WEEK_IN_MONTH;
case Calendar.AM_PM:
return AM_PM;
case Calendar.HOUR:
return HOUR;
case Calendar.HOUR_OF_DAY:
return HOUR_OF_DAY;
case Calendar.MINUTE:
return MINUTE;
case Calendar.SECOND:
return SECOND;
case Calendar.MILLISECOND:
return MILLISECOND;
default:
return null;
}
} }
} }

View File

@ -80,21 +80,15 @@ public enum DateUnit {
* @since 5.4.5 * @since 5.4.5
*/ */
public static DateUnit of(final ChronoUnit unit) { public static DateUnit of(final ChronoUnit unit) {
switch (unit) { return switch (unit) {
case MICROS: case MICROS -> DateUnit.MS;
return DateUnit.MS; case SECONDS -> DateUnit.SECOND;
case SECONDS: case MINUTES -> DateUnit.MINUTE;
return DateUnit.SECOND; case HOURS -> DateUnit.HOUR;
case MINUTES: case DAYS -> DateUnit.DAY;
return DateUnit.MINUTE; case WEEKS -> DateUnit.WEEK;
case HOURS: default -> null;
return DateUnit.HOUR; };
case DAYS:
return DateUnit.DAY;
case WEEKS:
return DateUnit.WEEK;
}
return null;
} }
/** /**
@ -105,20 +99,13 @@ public enum DateUnit {
* @since 5.4.5 * @since 5.4.5
*/ */
public static ChronoUnit toChronoUnit(final DateUnit unit) { public static ChronoUnit toChronoUnit(final DateUnit unit) {
switch (unit) { return switch (unit) {
case MS: case MS -> ChronoUnit.MICROS;
return ChronoUnit.MICROS; case SECOND -> ChronoUnit.SECONDS;
case SECOND: case MINUTE -> ChronoUnit.MINUTES;
return ChronoUnit.SECONDS; case HOUR -> ChronoUnit.HOURS;
case MINUTE: case DAY -> ChronoUnit.DAYS;
return ChronoUnit.MINUTES; case WEEK -> ChronoUnit.WEEKS;
case HOUR: };
return ChronoUnit.HOURS;
case DAY:
return ChronoUnit.DAYS;
case WEEK:
return ChronoUnit.WEEKS;
}
return null;
} }
} }

View File

@ -142,17 +142,11 @@ public enum Month {
* @return 此月份最后一天的值 * @return 此月份最后一天的值
*/ */
public int getLastDay(final boolean isLeapYear) { public int getLastDay(final boolean isLeapYear) {
switch (this) { return switch (this) {
case FEBRUARY: case FEBRUARY -> isLeapYear ? 29 : 28;
return isLeapYear ? 29 : 28; case APRIL, JUNE, SEPTEMBER, NOVEMBER -> 30;
case APRIL: default -> 31;
case JUNE: };
case SEPTEMBER:
case NOVEMBER:
return 30;
default:
return 31;
}
} }
/** /**
@ -249,13 +243,11 @@ public enum Month {
case '九': case '九':
return SEPTEMBER; return SEPTEMBER;
case '十': case '十':
switch (Character.toLowerCase(name.charAt(1))){ return switch (Character.toLowerCase(name.charAt(1))) {
case '一': case '一' -> NOVEMBER;
return NOVEMBER; case '二' -> DECEMBER;
case '二': default -> OCTOBER;
return DECEMBER; };
}
return OCTOBER;
} }
} }

View File

@ -75,18 +75,13 @@ public enum Quarter {
* @see #Q4 * @see #Q4
*/ */
public static Quarter of(final int intValue) { public static Quarter of(final int intValue) {
switch (intValue) { return switch (intValue) {
case 1: case 1 -> Q1;
return Q1; case 2 -> Q2;
case 2: case 3 -> Q3;
return Q2; case 4 -> Q4;
case 3: default -> null;
return Q3; };
case 4:
return Q4;
default:
return null;
}
} }
/** /**

View File

@ -71,24 +71,16 @@ public class TemporalUtil {
if (null == unit) { if (null == unit) {
return null; return null;
} }
switch (unit) { return switch (unit) {
case NANOSECONDS: case NANOSECONDS -> ChronoUnit.NANOS;
return ChronoUnit.NANOS; case MICROSECONDS -> ChronoUnit.MICROS;
case MICROSECONDS: case MILLISECONDS -> ChronoUnit.MILLIS;
return ChronoUnit.MICROS; case SECONDS -> ChronoUnit.SECONDS;
case MILLISECONDS: case MINUTES -> ChronoUnit.MINUTES;
return ChronoUnit.MILLIS; case HOURS -> ChronoUnit.HOURS;
case SECONDS: case DAYS -> ChronoUnit.DAYS;
return ChronoUnit.SECONDS; default -> throw new IllegalArgumentException("Unknown TimeUnit constant");
case MINUTES: };
return ChronoUnit.MINUTES;
case HOURS:
return ChronoUnit.HOURS;
case DAYS:
return ChronoUnit.DAYS;
default:
throw new IllegalArgumentException("Unknown TimeUnit constant");
}
} }
/** /**
@ -103,24 +95,16 @@ public class TemporalUtil {
if (null == unit) { if (null == unit) {
return null; return null;
} }
switch (unit) { return switch (unit) {
case NANOS: case NANOS -> TimeUnit.NANOSECONDS;
return TimeUnit.NANOSECONDS; case MICROS -> TimeUnit.MICROSECONDS;
case MICROS: case MILLIS -> TimeUnit.MILLISECONDS;
return TimeUnit.MICROSECONDS; case SECONDS -> TimeUnit.SECONDS;
case MILLIS: case MINUTES -> TimeUnit.MINUTES;
return TimeUnit.MILLISECONDS; case HOURS -> TimeUnit.HOURS;
case SECONDS: case DAYS -> TimeUnit.DAYS;
return TimeUnit.SECONDS; default -> throw new IllegalArgumentException("ChronoUnit cannot be converted to TimeUnit: " + unit);
case MINUTES: };
return TimeUnit.MINUTES;
case HOURS:
return TimeUnit.HOURS;
case DAYS:
return TimeUnit.DAYS;
default:
throw new IllegalArgumentException("ChronoUnit cannot be converted to TimeUnit: " + unit);
}
} }
/** /**

View File

@ -124,24 +124,15 @@ public enum Week {
* @since 4.0.11 * @since 4.0.11
*/ */
public String toChinese(final String weekNamePre) { public String toChinese(final String weekNamePre) {
switch (this) { return switch (this) {
case SUNDAY: case SUNDAY -> weekNamePre + "";
return weekNamePre + ""; case MONDAY -> weekNamePre + "";
case MONDAY: case TUESDAY -> weekNamePre + "";
return weekNamePre + ""; case WEDNESDAY -> weekNamePre + "";
case TUESDAY: case THURSDAY -> weekNamePre + "";
return weekNamePre + ""; case FRIDAY -> weekNamePre + "";
case WEDNESDAY: case SATURDAY -> weekNamePre + "";
return weekNamePre + ""; };
case THURSDAY:
return weekNamePre + "";
case FRIDAY:
return weekNamePre + "";
case SATURDAY:
return weekNamePre + "";
default:
return null;
}
} }
/** /**
@ -176,7 +167,7 @@ public enum Week {
/** /**
* 解析别名为Week对象别名如sun或者SUNDAY不区分大小写<br> * 解析别名为Week对象别名如sun或者SUNDAY不区分大小写<br>
* 参考https://github.com/sisyphsu/dateparser/blob/master/src/main/java/com/github/sisyphsu/dateparser/DateParser.java#L319 * 参考<a href="https://github.com/sisyphsu/dateparser/blob/master/src/main/java/com/github/sisyphsu/dateparser/DateParser.java#L319">DateParser.java#L319</a>
* *
* @param name 别名值 * @param name 别名值
* @return 周枚举Week非空 * @return 周枚举Week非空
@ -188,23 +179,16 @@ public enum Week {
// issue#3637 // issue#3637
if (StrUtil.startWithAny(name, "星期", "")) { if (StrUtil.startWithAny(name, "星期", "")) {
final char chineseNumber = name.charAt(name.length() - 1); final char chineseNumber = name.charAt(name.length() - 1);
switch (chineseNumber) { return switch (chineseNumber) {
case '一': case '一' -> MONDAY;
return MONDAY; case '二' -> TUESDAY;
case '二': case '三' -> WEDNESDAY;
return TUESDAY; case '四' -> THURSDAY;
case '三': case '五' -> FRIDAY;
return WEDNESDAY; case '六' -> SATURDAY;
case '四': case '日' -> SUNDAY;
return THURSDAY; default -> throw new IllegalArgumentException("Invalid week name: " + name);
case '五': };
return FRIDAY;
case '六':
return SATURDAY;
case '日':
return SUNDAY;
}
throw new IllegalArgumentException("Invalid week name: " + name);
} }
switch (Character.toLowerCase(name.charAt(0))) { switch (Character.toLowerCase(name.charAt(0))) {

View File

@ -304,16 +304,12 @@ public class ChineseDate {
if (day > 30) { if (day > 30) {
return ""; return "";
} }
switch (day) { return switch (day) {
case 10: case 10 -> "初十";
return "初十"; case 20 -> "二十";
case 20: case 30 -> "三十";
return "二十"; default -> chineseTen[day / 10] + ChineseNumberFormatter.of().format(n + 1);
case 30: };
return "三十";
default:
return chineseTen[day / 10] + ChineseNumberFormatter.of().format(n + 1);
}
} }
/** /**

View File

@ -436,10 +436,9 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@Override @Override
public boolean equals(final Object obj) { public boolean equals(final Object obj) {
if (obj instanceof FastDateFormat == false) { if (!(obj instanceof FastDateFormat other)) {
return false; return false;
} }
final FastDateFormat other = (FastDateFormat) obj;
// no need to check parser, as it has same invariants as printer // no need to check parser, as it has same invariants as printer
return printer.equals(other.printer); return printer.equals(other.printer);
} }

View File

@ -75,10 +75,9 @@ public class SimpleDateBasic implements DateBasic, Serializable {
// ----------------------------------------------------------------------- Basics // ----------------------------------------------------------------------- Basics
@Override @Override
public boolean equals(final Object obj) { public boolean equals(final Object obj) {
if (obj instanceof FastDatePrinter == false) { if (!(obj instanceof FastDatePrinter other)) {
return false; return false;
} }
final SimpleDateBasic other = (SimpleDateBasic) obj;
return pattern.equals(other.pattern) && timeZone.equals(other.timeZone) && locale.equals(other.locale); return pattern.equals(other.pattern) && timeZone.equals(other.timeZone) && locale.equals(other.locale);
} }

View File

@ -176,9 +176,7 @@ public class ConsoleTable {
} }
sb.append(SPACE); sb.append(SPACE);
final int maxLength = columnCharNumber.get(i); final int maxLength = columnCharNumber.get(i);
for (int j = 0; j < (maxLength - length + (sbcCount / 2)); j++) { sb.append(String.valueOf(SPACE).repeat(Math.max(0, (maxLength - length + (sbcCount / 2)))));
sb.append(SPACE);
}
sb.append(COLUMN_LINE); sb.append(COLUMN_LINE);
} }
} }

View File

@ -60,16 +60,12 @@ public class ReferenceUtil {
* @return {@link Reference} * @return {@link Reference}
*/ */
public static <T> Reference<T> of(final ReferenceType type, final T referent, final ReferenceQueue<T> queue) { public static <T> Reference<T> of(final ReferenceType type, final T referent, final ReferenceQueue<T> queue) {
switch (type) { return switch (type) {
case SOFT: case SOFT -> new SoftReference<>(referent, queue);
return new SoftReference<>(referent, queue); case WEAK -> new WeakReference<>(referent, queue);
case WEAK: case PHANTOM -> new PhantomReference<>(referent, queue);
return new WeakReference<>(referent, queue); default -> null;
case PHANTOM: };
return new PhantomReference<>(referent, queue);
default:
return null;
}
} }
/** /**

View File

@ -197,7 +197,7 @@ public class Tuple implements Iterable<Object>, Serializable, Cloneable {
return false; return false;
} }
final Tuple other = (Tuple) obj; final Tuple other = (Tuple) obj;
return false != Arrays.deepEquals(members, other.members); return Arrays.deepEquals(members, other.members);
} }
@Override @Override

View File

@ -165,26 +165,14 @@ public class Calculator {
* @return 结果 * @return 结果
*/ */
private BigDecimal calculate(final String firstValue, final String secondValue, final char currentOp) { private BigDecimal calculate(final String firstValue, final String secondValue, final char currentOp) {
final BigDecimal result; final BigDecimal result = switch (currentOp) {
switch (currentOp) { case '+' -> NumberUtil.add(firstValue, secondValue);
case '+': case '-' -> NumberUtil.sub(firstValue, secondValue);
result = NumberUtil.add(firstValue, secondValue); case '*' -> NumberUtil.mul(firstValue, secondValue);
break; case '/' -> NumberUtil.div(firstValue, secondValue);
case '-': case '%' -> NumberUtil.toBigDecimal(firstValue).remainder(NumberUtil.toBigDecimal(secondValue));
result = NumberUtil.sub(firstValue, secondValue); default -> throw new IllegalStateException("Unexpected value: " + currentOp);
break; };
case '*':
result = NumberUtil.mul(firstValue, secondValue);
break;
case '/':
result = NumberUtil.div(firstValue, secondValue);
break;
case '%':
result = NumberUtil.toBigDecimal(firstValue).remainder(NumberUtil.toBigDecimal(secondValue));
break;
default:
throw new IllegalStateException("Unexpected value: " + currentOp);
}
return result; return result;
} }

View File

@ -147,7 +147,6 @@ public class ChineseNumberFormatter {
*/ */
public ChineseNumberFormatter setUnitName(final String unitName) { public ChineseNumberFormatter setUnitName(final String unitName) {
this.unitName = Assert.notNull(unitName); this.unitName = Assert.notNull(unitName);
;
return this; return this;
} }
// endregion // endregion

View File

@ -76,31 +76,16 @@ public class RomanNumberFormatter {
final char[] charArray = roman.toCharArray(); final char[] charArray = roman.toCharArray();
for (int i = charArray.length - 1; i >= 0; i--) { for (int i = charArray.length - 1; i >= 0; i--) {
final char c = charArray[i]; final char c = charArray[i];
switch (c) { currValue = switch (c) {
case 'I': case 'I' -> 1;
currValue = 1; case 'V' -> 5;
break; case 'X' -> 10;
case 'V': case 'L' -> 50;
currValue = 5; case 'C' -> 100;
break; case 'D' -> 500;
case 'X': case 'M' -> 1000;
currValue = 10; default -> throw new IllegalArgumentException("Invalid Roman character: " + c);
break; };
case 'L':
currValue = 50;
break;
case 'C':
currValue = 100;
break;
case 'D':
currValue = 500;
break;
case 'M':
currValue = 1000;
break;
default:
throw new IllegalArgumentException("Invalid Roman character: " + c);
}
if (currValue < prevValue) { if (currValue < prevValue) {
result -= currValue; result -= currValue;
} else { } else {

View File

@ -109,7 +109,7 @@ public class Ipv4Util implements Ipv4Pool {
* <p> * <p>
* 此方法不会抛出异常获取失败将返回{@code null}<br> * 此方法不会抛出异常获取失败将返回{@code null}<br>
* <p> * <p>
* https://github.com/chinabugotech/hutool/issues/428 * <a href="https://github.com/chinabugotech/hutool/issues/428">issues#428</a>
* *
* @return 本机网卡IP地址获取失败返回{@code null} * @return 本机网卡IP地址获取失败返回{@code null}
*/ */
@ -129,7 +129,7 @@ public class Ipv4Util implements Ipv4Pool {
* <p> * <p>
* 此方法不会抛出异常获取失败将返回{@code null}<br> * 此方法不会抛出异常获取失败将返回{@code null}<br>
* <p> * <p>
* https://github.com/chinabugotech/hutool/issues/428 * <a href="https://github.com/chinabugotech/hutool/issues/428">issues#428</a>
* *
* @return 本机网卡IP地址获取失败返回{@code null} * @return 本机网卡IP地址获取失败返回{@code null}
*/ */
@ -149,7 +149,7 @@ public class Ipv4Util implements Ipv4Pool {
* <p> * <p>
* 此方法不会抛出异常获取失败将返回{@code null}<br> * 此方法不会抛出异常获取失败将返回{@code null}<br>
* <p> * <p>
* https://github.com/chinabugotech/hutool/issues/428 * <a href="https://github.com/chinabugotech/hutool/issues/428">issues#428</a>
* *
* @param includeSiteLocal 是否包含局域网地址如10.0.0.0 ~ 10.255.255.255172.16.0.0 ~ 172.31.255.255192.168.0.0 ~ 192.168.255.255 * @param includeSiteLocal 是否包含局域网地址如10.0.0.0 ~ 10.255.255.255172.16.0.0 ~ 172.31.255.255192.168.0.0 ~ 192.168.255.255
* @return 本机网卡IP地址获取失败返回{@code null} * @return 本机网卡IP地址获取失败返回{@code null}
@ -580,18 +580,13 @@ public class Ipv4Util implements Ipv4Pool {
* @since 6.0.0 * @since 6.0.0
*/ */
public static int getPartOfIp(final long ip, final int position) { public static int getPartOfIp(final long ip, final int position) {
switch (position) { return switch (position) {
case 1: case 1 -> (int) (ip >> 24) & 0xFF;
return (int) (ip >> 24) & 0xFF; case 2 -> (int) (ip >> 16) & 0xFF;
case 2: case 3 -> (int) (ip >> 8) & 0xFF;
return (int) (ip >> 16) & 0xFF; case 4 -> (int) ip & 0xFF;
case 3: default -> throw new IllegalArgumentException("Illegal position of ip Long: " + position);
return (int) (ip >> 8) & 0xFF; };
case 4:
return (int) ip & 0xFF;
default:
throw new IllegalArgumentException("Illegal position of ip Long: " + position);
}
} }
/** /**

View File

@ -270,14 +270,11 @@ public class UrlQuery {
* @return URL查询字符串 * @return URL查询字符串
*/ */
public String build(final Charset charset) { public String build(final Charset charset) {
switch (this.encodeMode) { return switch (this.encodeMode) {
case FORM_URL_ENCODED: case FORM_URL_ENCODED -> build(FormUrlencoded.ALL, FormUrlencoded.ALL, charset);
return build(FormUrlencoded.ALL, FormUrlencoded.ALL, charset); case STRICT -> build(RFC3986.QUERY_PARAM_NAME_STRICT, RFC3986.QUERY_PARAM_VALUE_STRICT, charset);
case STRICT: default -> build(RFC3986.QUERY_PARAM_NAME, RFC3986.QUERY_PARAM_VALUE, charset);
return build(RFC3986.QUERY_PARAM_NAME_STRICT, RFC3986.QUERY_PARAM_VALUE_STRICT, charset); };
default:
return build(RFC3986.QUERY_PARAM_NAME, RFC3986.QUERY_PARAM_VALUE, charset);
}
} }
/** /**
@ -306,7 +303,7 @@ public class UrlQuery {
for (final Map.Entry<CharSequence, CharSequence> entry : this.query) { for (final Map.Entry<CharSequence, CharSequence> entry : this.query) {
name = entry.getKey(); name = entry.getKey();
if (null != name) { if (null != name) {
if (sb.length() > 0) { if (!sb.isEmpty()) {
sb.append("&"); sb.append("&");
} }
sb.append(keyCoder.encode(name, charset)); sb.append(keyCoder.encode(name, charset));
@ -332,7 +329,7 @@ public class UrlQuery {
/** /**
* 解析URL中的查询字符串<br> * 解析URL中的查询字符串<br>
* 规则见https://url.spec.whatwg.org/#urlencoded-parsing * 规则见<a href="https://url.spec.whatwg.org/#urlencoded-parsing">urlencoded-parsing</a>
* *
* @param queryStr 查询字符串类似于key1=v1&amp;key2=&amp;key3=v3 * @param queryStr 查询字符串类似于key1=v1&amp;key2=&amp;key3=v3
* @param charset decode编码null表示不做decode * @param charset decode编码null表示不做decode

View File

@ -452,14 +452,11 @@ public class MethodUtil {
public static boolean isGetterOrSetter(final Method method, final boolean ignoreCase) { public static boolean isGetterOrSetter(final Method method, final boolean ignoreCase) {
// 参数个数必须为1 // 参数个数必须为1
final int parameterCount = method.getParameterCount(); final int parameterCount = method.getParameterCount();
switch (parameterCount) { return switch (parameterCount) {
case 0: case 0 -> isGetter(method, ignoreCase);
return isGetter(method, ignoreCase); case 1 -> isSetter(method, ignoreCase);
case 1: default -> false;
return isSetter(method, ignoreCase); };
default:
return false;
}
} }
/** /**

View File

@ -321,19 +321,17 @@ public class CharUtil implements CharPool {
* @return 是否为零宽字符 * @return 是否为零宽字符
*/ */
public static boolean isZeroWidthChar(final char c) { public static boolean isZeroWidthChar(final char c) {
switch (c) { return switch (c) { // 零宽空格
case '\u200B': // 零宽空格 // 零宽非换行空格
case '\u200C': // 零宽非换行空格 // 零宽连接符
case '\u200D': // 零宽连接符 // 零宽无断空格
case '\uFEFF': // 零宽无断空格 // 零宽连字符
case '\u2060': // 零宽连字符 // 零宽不连字符
case '\u2063': // 零宽不连字符 // 零宽连字符
case '\u2064': // 零宽连字符 case '\u200B', '\u200C', '\u200D', '\uFEFF', '\u2060', '\u2063', '\u2064', '\u2065' -> // 零宽不连字符
case '\u2065': // 零宽不连字符 true;
return true; default -> false;
default: };
return false;
}
} }
/** /**

View File

@ -16,11 +16,11 @@
package cn.hutool.v7.core.text; package cn.hutool.v7.core.text;
import cn.hutool.v7.core.array.ArrayUtil;
import cn.hutool.v7.core.collection.iter.ArrayIter; import cn.hutool.v7.core.collection.iter.ArrayIter;
import cn.hutool.v7.core.collection.iter.IterUtil; import cn.hutool.v7.core.collection.iter.IterUtil;
import cn.hutool.v7.core.convert.ConvertUtil; import cn.hutool.v7.core.convert.ConvertUtil;
import cn.hutool.v7.core.io.IORuntimeException; import cn.hutool.v7.core.io.IORuntimeException;
import cn.hutool.v7.core.array.ArrayUtil;
import java.io.IOException; import java.io.IOException;
import java.io.Serial; import java.io.Serial;
@ -236,8 +236,7 @@ public class StrJoiner implements Appendable, Serializable {
append((Iterator<?>) obj); append((Iterator<?>) obj);
} else if (obj instanceof Iterable) { } else if (obj instanceof Iterable) {
append(((Iterable<?>) obj).iterator()); append(((Iterable<?>) obj).iterator());
}else if (obj instanceof Map.Entry) { }else if (obj instanceof Map.Entry<?, ?> entry) {
final Map.Entry<?, ?> entry = (Map.Entry<?, ?>) obj;
append(entry.getKey()).append(entry.getValue()); append(entry.getKey()).append(entry.getValue());
} else { } else {
append(ConvertUtil.toStr(obj)); append(ConvertUtil.toStr(obj));
@ -449,9 +448,8 @@ public class StrJoiner implements Appendable, Serializable {
* @param appendable {@link Appendable} * @param appendable {@link Appendable}
*/ */
private void checkHasContent(final Appendable appendable) { private void checkHasContent(final Appendable appendable) {
if (appendable instanceof CharSequence) { if (appendable instanceof CharSequence charSequence) {
final CharSequence charSequence = (CharSequence) appendable; if (!charSequence.isEmpty() && StrUtil.endWith(charSequence, delimiter)) {
if (charSequence.length() > 0 && StrUtil.endWith(charSequence, delimiter)) {
this.hasContent = true; this.hasContent = true;
} }
} else { } else {

View File

@ -82,7 +82,7 @@ public class StrRepeater {
} }
final int count = this.countOrLength; final int count = this.countOrLength;
if (count <= 0 || str.length() == 0) { if (count <= 0 || str.isEmpty()) {
return StrUtil.EMPTY; return StrUtil.EMPTY;
} }
if (count == 1) { if (count == 1) {

View File

@ -157,7 +157,7 @@ public class StrValidator {
* @see #isBlank(CharSequence) * @see #isBlank(CharSequence)
*/ */
public static boolean isEmpty(final CharSequence str) { public static boolean isEmpty(final CharSequence str) {
return str == null || str.length() == 0; return str == null || str.isEmpty();
} }
/** /**

View File

@ -29,10 +29,6 @@ public interface SensitiveProcessor {
*/ */
default String process(final FoundWord foundWord) { default String process(final FoundWord foundWord) {
final int length = foundWord.getFoundWord().length(); final int length = foundWord.getFoundWord().length();
final StringBuilder sb = new StringBuilder(length); return "*".repeat(length);
for (int i = 0; i < length; i++) {
sb.append("*");
}
return sb.toString();
} }
} }

View File

@ -127,7 +127,7 @@ public class StrMatcher {
} }
} }
if (part.length() > 0) { if (!part.isEmpty()) {
patterns.add(part.toString()); patterns.add(part.toString());
} }
return patterns; return patterns;

View File

@ -167,7 +167,7 @@ public class SplitUtil {
final Function<String, R> mapping) { final Function<String, R> mapping) {
if (null == str) { if (null == str) {
return ListUtil.zero(); return ListUtil.zero();
} else if (0 == str.length() && ignoreEmpty) { } else if (str.isEmpty() && ignoreEmpty) {
return ListUtil.zero(); return ListUtil.zero();
} }
Assert.notEmpty(separator, "Separator must be not empty!"); Assert.notEmpty(separator, "Separator must be not empty!");
@ -304,7 +304,7 @@ public class SplitUtil {
if (null == str) { if (null == str) {
return ListUtil.zero(); return ListUtil.zero();
} }
if(0 == str.length()){ if(str.isEmpty()){
return ignoreEmpty ? ListUtil.zero() : ListUtil.of(StrUtil.EMPTY); return ignoreEmpty ? ListUtil.zero() : ListUtil.of(StrUtil.EMPTY);
} }
if(null == separatorPattern){ if(null == separatorPattern){

View File

@ -391,7 +391,7 @@ public class RuntimeUtil {
} }
} }
if (cache.length() > 0) { if (!cache.isEmpty()) {
cmds.add(cache.toString()); cmds.add(cache.toString());
} }

View File

@ -21,7 +21,6 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
/** /**
* {@link DynaBean}单元测试 * {@link DynaBean}单元测试

View File

@ -48,16 +48,12 @@ public class ProxyBeanTest {
void proxyTest() { void proxyTest() {
final IBean bean = JdkProxyUtil.newProxyInstance((proxy, method, args) -> { final IBean bean = JdkProxyUtil.newProxyInstance((proxy, method, args) -> {
final String name = method.getName(); final String name = method.getName();
switch (name){ return switch (name) {
case "getName": case "getName" -> "hutool";
return "hutool"; case "setName", "setAge" -> null;
case "setName": case "getAge" -> 1;
case "setAge": default -> throw new HutoolException("No method name: " + name);
return null; };
case "getAge":
return 1;
}
throw new HutoolException("No method name: " + name);
}, IBean.class); }, IBean.class);
// 测试代理类的Bean拷贝 // 测试代理类的Bean拷贝

View File

@ -20,7 +20,6 @@ import cn.hutool.v7.core.cache.impl.FIFOCache;
import cn.hutool.v7.core.cache.impl.LRUCache; import cn.hutool.v7.core.cache.impl.LRUCache;
import cn.hutool.v7.core.cache.impl.WeakCache; import cn.hutool.v7.core.cache.impl.WeakCache;
import cn.hutool.v7.core.exception.HutoolException; import cn.hutool.v7.core.exception.HutoolException;
import cn.hutool.v7.core.func.SerSupplier;
import cn.hutool.v7.core.lang.Console; import cn.hutool.v7.core.lang.Console;
import cn.hutool.v7.core.thread.ConcurrencyTester; import cn.hutool.v7.core.thread.ConcurrencyTester;
import cn.hutool.v7.core.thread.ThreadUtil; import cn.hutool.v7.core.thread.ThreadUtil;
@ -29,8 +28,6 @@ import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;

View File

@ -32,7 +32,7 @@ public class PartitionIterTest {
final LineIter lineIter = new LineIter(ResourceUtil.getUtf8Reader("test_lines.csv")); final LineIter lineIter = new LineIter(ResourceUtil.getUtf8Reader("test_lines.csv"));
final PartitionIter<String> iter = new PartitionIter<>(lineIter, 3); final PartitionIter<String> iter = new PartitionIter<>(lineIter, 3);
for (final List<String> lines : iter) { for (final List<String> lines : iter) {
Assertions.assertTrue(lines.size() > 0); Assertions.assertFalse(lines.isEmpty());
} }
} }

View File

@ -46,27 +46,21 @@ public class EnumConvertTest {
A, B, C; A, B, C;
public static TestEnum parse(final String str) { public static TestEnum parse(final String str) {
switch (str) { return switch (str) {
case "AAA": case "AAA" -> A;
return A; case "BBB" -> B;
case "BBB": case "CCC" -> C;
return B; default -> null;
case "CCC": };
return C;
}
return null;
} }
public static TestEnum parseByNumber(final int i) { public static TestEnum parseByNumber(final int i) {
switch (i) { return switch (i) {
case 11: case 11 -> A;
return A; case 22 -> B;
case 22: case 33 -> C;
return B; default -> null;
case 33: };
return C;
}
return null;
} }
} }
} }

View File

@ -16,16 +16,11 @@
package cn.hutool.v7.core.data.id; package cn.hutool.v7.core.data.id;
import cn.hutool.v7.core.data.id.NanoId;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.HashMap; import java.util.*;
import java.util.HashSet;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
@ -45,7 +40,7 @@ public class NanoIdTest {
for (int i = 0; i < idCount; i++) { for (int i = 0; i < idCount; i++) {
final String id = NanoId.randomNanoId(); final String id = NanoId.randomNanoId();
if (ids.contains(id) == false) { if (!ids.contains(id)) {
ids.add(id); ids.add(id);
} else { } else {
Assertions.fail("Non-unique ID generated: " + id); Assertions.fail("Non-unique ID generated: " + id);

View File

@ -24,20 +24,14 @@ import java.util.function.Function;
public class BetweenFormatterTest { public class BetweenFormatterTest {
Function<BetweenFormatter.Level, String> levelFormatterEn = level -> { Function<BetweenFormatter.Level, String> levelFormatterEn = level -> {
switch (level) { return switch (level) {
case DAY: case DAY -> " day";
return " day"; case HOUR -> " hour";
case HOUR: case MINUTE -> " minute";
return " hour"; case SECOND -> " second";
case MINUTE: case MILLISECOND -> " millisecond";
return " minute"; default -> " " + level.name();
case SECOND: };
return " second";
case MILLISECOND:
return " millisecond";
default:
return " " + level.name();
}
}; };
@Test @Test

View File

@ -16,14 +16,12 @@
package cn.hutool.v7.core.lang; package cn.hutool.v7.core.lang;
import lombok.Data;
import cn.hutool.v7.core.exception.HutoolException; import cn.hutool.v7.core.exception.HutoolException;
import cn.hutool.v7.core.thread.ThreadUtil; import cn.hutool.v7.core.thread.ThreadUtil;
import lombok.Data;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnJre;
import org.junit.jupiter.api.condition.JRE;
import java.time.Duration; import java.time.Duration;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;

View File

@ -21,8 +21,6 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.Map;
/** /**
* @author newshiJ * @author newshiJ
*/ */

View File

@ -47,7 +47,7 @@ class UrlDecoderTest {
final String s1 = UrlEncoder.encodeAll(s, StandardCharsets.UTF_16); final String s1 = UrlEncoder.encodeAll(s, StandardCharsets.UTF_16);
Assertions.assertEquals(expectedDecode, s1); Assertions.assertEquals(expectedDecode, s1);
final String s2 = java.net.URLEncoder.encode(s, "UTF-16"); final String s2 = java.net.URLEncoder.encode(s, StandardCharsets.UTF_16);
Assertions.assertEquals(expectedDecode, s2); Assertions.assertEquals(expectedDecode, s2);
final String decode = UrlDecoder.decode(s1, StandardCharsets.UTF_16); final String decode = UrlDecoder.decode(s1, StandardCharsets.UTF_16);
@ -59,7 +59,7 @@ class UrlDecoderTest {
Assertions.assertEquals("测试你好", decode2); Assertions.assertEquals("测试你好", decode2);
Assertions.assertEquals( Assertions.assertEquals(
java.net.URLDecoder.decode(mixDecoded, "UTF-16"), java.net.URLDecoder.decode(mixDecoded, StandardCharsets.UTF_16),
UrlDecoder.decode(mixDecoded, StandardCharsets.UTF_16) UrlDecoder.decode(mixDecoded, StandardCharsets.UTF_16)
); );
} }

View File

@ -24,7 +24,6 @@ import cn.hutool.v7.core.date.StopWatch;
import cn.hutool.v7.core.exception.HutoolException; import cn.hutool.v7.core.exception.HutoolException;
import cn.hutool.v7.core.lang.Console; import cn.hutool.v7.core.lang.Console;
import cn.hutool.v7.core.thread.ThreadUtil; import cn.hutool.v7.core.thread.ThreadUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;

View File

@ -18,7 +18,6 @@ package cn.hutool.v7.core.util;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
public class JdkUtilTest { public class JdkUtilTest {

View File

@ -17,7 +17,6 @@
package cn.hutool.v7.cron; package cn.hutool.v7.cron;
import cn.hutool.v7.cron.task.CronTask; import cn.hutool.v7.cron.task.CronTask;
import cn.hutool.v7.cron.task.Task;
/** /**
* 作业执行器<br> * 作业执行器<br>

View File

@ -19,7 +19,6 @@ package cn.hutool.v7.cron.pattern;
import cn.hutool.v7.core.date.DateField; import cn.hutool.v7.core.date.DateField;
import cn.hutool.v7.core.date.DateTime; import cn.hutool.v7.core.date.DateTime;
import cn.hutool.v7.core.date.DateUtil; import cn.hutool.v7.core.date.DateUtil;
import cn.hutool.v7.core.lang.Console;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;

View File

@ -781,16 +781,18 @@ public class SM2 extends AbstractAsymmetricCrypto<SM2> {
* @return {@link CipherParameters} * @return {@link CipherParameters}
*/ */
private CipherParameters getCipherParameters(final KeyType keyType) { private CipherParameters getCipherParameters(final KeyType keyType) {
switch (keyType) { return switch (keyType) {
case PublicKey: case PublicKey -> {
Assert.notNull(this.publicKeyParams, "PublicKey must be not null !"); Assert.notNull(this.publicKeyParams, "PublicKey must be not null !");
return this.publicKeyParams; yield this.publicKeyParams;
case PrivateKey:
Assert.notNull(this.privateKeyParams, "PrivateKey must be not null !");
return this.privateKeyParams;
} }
case PrivateKey -> {
Assert.notNull(this.privateKeyParams, "PrivateKey must be not null !");
yield this.privateKeyParams;
}
default -> null;
};
return null;
} }
/** /**

View File

@ -221,7 +221,7 @@ public class Sign extends BaseAsymmetric<Sign> {
if (CollUtil.isNotEmpty(critSet) && critSet.contains("2.5.29.15")) { if (CollUtil.isNotEmpty(critSet) && critSet.contains("2.5.29.15")) {
final boolean[] keyUsageInfo = cert.getKeyUsage(); final boolean[] keyUsageInfo = cert.getKeyUsage();
// keyUsageInfo[0] is for digitalSignature. // keyUsageInfo[0] is for digitalSignature.
if ((keyUsageInfo != null) && (keyUsageInfo[0] == false)) { if ((keyUsageInfo != null) && (!keyUsageInfo[0])) {
throw new CryptoException("Wrong key usage"); throw new CryptoException("Wrong key usage");
} }
} }

View File

@ -69,20 +69,12 @@ public class ASN1Util {
* @param elements ASN.1元素 * @param elements ASN.1元素
*/ */
public static void encodeTo(final String asn1Encoding, final OutputStream out, final ASN1Encodable... elements) { public static void encodeTo(final String asn1Encoding, final OutputStream out, final ASN1Encodable... elements) {
final ASN1Sequence sequence; final ASN1Sequence sequence = switch (asn1Encoding) {
switch (asn1Encoding) { case ASN1Encoding.DER -> new DERSequence(elements);
case ASN1Encoding.DER: case ASN1Encoding.BER -> new BERSequence(elements);
sequence = new DERSequence(elements); case ASN1Encoding.DL -> new DLSequence(elements);
break; default -> throw new CryptoException("Unsupported ASN1 encoding: {}", asn1Encoding);
case ASN1Encoding.BER: };
sequence = new BERSequence(elements);
break;
case ASN1Encoding.DL:
sequence = new DLSequence(elements);
break;
default:
throw new CryptoException("Unsupported ASN1 encoding: {}", asn1Encoding);
}
try { try {
sequence.encodeTo(out); sequence.encodeTo(out);
} catch (final IOException e) { } catch (final IOException e) {

View File

@ -146,17 +146,13 @@ public class BCUtil {
return new CTSBlockCipher(cipher); return new CTSBlockCipher(cipher);
} }
switch (padding) { return switch (padding) {
case NoPadding: case NoPadding -> new DefaultBufferedBlockCipher(cipher);
return new DefaultBufferedBlockCipher(cipher); case PKCS5Padding -> new PaddedBufferedBlockCipher(cipher);
case PKCS5Padding: case ZeroPadding -> new PaddedBufferedBlockCipher(cipher, new ZeroBytePadding());
return new PaddedBufferedBlockCipher(cipher); case ISO10126Padding -> new PaddedBufferedBlockCipher(cipher, new ISO10126d2Padding());
case ZeroPadding: default -> null;
return new PaddedBufferedBlockCipher(cipher, new ZeroBytePadding()); };
case ISO10126Padding:
return new PaddedBufferedBlockCipher(cipher, new ISO10126d2Padding());
}
return null;
} }
} }

View File

@ -56,9 +56,7 @@ public class ECIESTest {
private void doTest(final AsymmetricCrypto cryptoForEncrypt, final AsymmetricCrypto cryptoForDecrypt){ private void doTest(final AsymmetricCrypto cryptoForEncrypt, final AsymmetricCrypto cryptoForDecrypt){
final String textBase = "我是一段特别长的测试"; final String textBase = "我是一段特别长的测试";
final StringBuilder text = new StringBuilder(); final StringBuilder text = new StringBuilder();
for (int i = 0; i < 10; i++) { text.append(textBase.repeat(10));
text.append(textBase);
}
// 公钥加密私钥解密 // 公钥加密私钥解密
final String encryptStr = cryptoForEncrypt.encryptBase64(text.toString(), KeyType.PublicKey); final String encryptStr = cryptoForEncrypt.encryptBase64(text.toString(), KeyType.PublicKey);

View File

@ -161,9 +161,7 @@ public class RSATest {
public void rsaBase64Test() { public void rsaBase64Test() {
final String textBase = "我是一段特别长的测试"; final String textBase = "我是一段特别长的测试";
final StringBuilder text = new StringBuilder(); final StringBuilder text = new StringBuilder();
for (int i = 0; i < 10; i++) { text.append(textBase.repeat(10));
text.append(textBase);
}
final RSA rsa = new RSA(); final RSA rsa = new RSA();

View File

@ -100,9 +100,7 @@ public class SM2Test {
public void sm2Base64Test() { public void sm2Base64Test() {
final String textBase = "我是一段特别长的测试"; final String textBase = "我是一段特别长的测试";
final StringBuilder text = new StringBuilder(); final StringBuilder text = new StringBuilder();
for (int i = 0; i < 100; i++) { text.append(textBase.repeat(100));
text.append(textBase);
}
SM2 sm2 = new SM2(); SM2 sm2 = new SM2();

View File

@ -246,7 +246,7 @@ public class Session extends AbstractDb<Session> implements Closeable {
*/ */
public void setTransactionIsolation(final int level) throws DbException { public void setTransactionIsolation(final int level) throws DbException {
try { try {
if (getConnection().getMetaData().supportsTransactionIsolationLevel(level) == false) { if (!getConnection().getMetaData().supportsTransactionIsolationLevel(level)) {
throw new DbException(StrUtil.format("Transaction isolation [{}] not support!", level)); throw new DbException(StrUtil.format("Transaction isolation [{}] not support!", level));
} }
getConnection().setTransactionIsolation(level); getConnection().setTransactionIsolation(level);

View File

@ -296,14 +296,11 @@ public class ResultColumn {
* @return ColumnNullable * @return ColumnNullable
*/ */
public static ColumnNullable of(final int nullable) { public static ColumnNullable of(final int nullable) {
switch (nullable) { return switch (nullable) {
case ResultSetMetaData.columnNoNulls: case ResultSetMetaData.columnNoNulls -> NO_NULLS;
return NO_NULLS; case ResultSetMetaData.columnNullable -> NULLABLE;
case ResultSetMetaData.columnNullable: default -> UNKNOWN;
return NULLABLE; };
default:
return UNKNOWN;
}
} }
final int value; final int value;

View File

@ -357,9 +357,7 @@ public class SqlFormatter {
private void newline() { private void newline() {
this.result.append("\n"); this.result.append("\n");
for (int i = 0; i < this.indent; i++) { this.result.append(indentString.repeat(Math.max(0, this.indent)));
this.result.append(indentString);
}
this.beginLine = true; this.beginLine = true;
} }
} }

View File

@ -18,12 +18,10 @@ package cn.hutool.v7.db.sql;
import cn.hutool.v7.core.date.DateTime; import cn.hutool.v7.core.date.DateTime;
import cn.hutool.v7.core.date.DateUtil; import cn.hutool.v7.core.date.DateUtil;
import cn.hutool.v7.core.lang.Console;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;

View File

@ -16,24 +16,21 @@
package cn.hutool.v7.extra.compress.archiver; package cn.hutool.v7.extra.compress.archiver;
import cn.hutool.v7.core.array.ArrayUtil;
import cn.hutool.v7.core.io.IORuntimeException;
import cn.hutool.v7.core.io.IoUtil;
import cn.hutool.v7.core.io.file.FileUtil;
import cn.hutool.v7.core.io.file.PathUtil; import cn.hutool.v7.core.io.file.PathUtil;
import cn.hutool.v7.extra.compress.CompressException;
import cn.hutool.v7.extra.compress.CompressUtil; import cn.hutool.v7.extra.compress.CompressUtil;
import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveException; import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.archivers.ArchiveOutputStream; import org.apache.commons.compress.archivers.ArchiveOutputStream;
import org.apache.commons.compress.archivers.ArchiveStreamFactory; import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.archivers.ar.ArArchiveOutputStream; import org.apache.commons.compress.archivers.ar.ArArchiveOutputStream;
import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream; import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
import cn.hutool.v7.core.array.ArrayUtil;
import cn.hutool.v7.core.io.IORuntimeException;
import cn.hutool.v7.core.io.IoUtil;
import cn.hutool.v7.core.io.file.FileUtil;
import cn.hutool.v7.core.text.StrUtil;
import cn.hutool.v7.extra.compress.CompressException;
import java.io.BufferedInputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;

View File

@ -38,7 +38,7 @@ public interface PinyinEngine {
*/ */
default String getPinyin(final char c){ default String getPinyin(final char c){
return getPinyin(c, false); return getPinyin(c, false);
}; }
/** /**
* 如果c为汉字则返回大写拼音如果c不是汉字则返回String.valueOf(c) * 如果c为汉字则返回大写拼音如果c不是汉字则返回String.valueOf(c)

View File

@ -114,21 +114,17 @@ public class BeetlEngine implements TemplateEngine {
config = TemplateConfig.DEFAULT; config = TemplateConfig.DEFAULT;
} }
switch (config.getResourceMode()) { return switch (config.getResourceMode()) {
case CLASSPATH: case CLASSPATH ->
return createGroupTemplate(new ClasspathResourceLoader(config.getPath(), config.getCharsetStr())); createGroupTemplate(new ClasspathResourceLoader(config.getPath(), config.getCharsetStr()));
case FILE: case FILE -> createGroupTemplate(new FileResourceLoader(config.getPath(), config.getCharsetStr()));
return createGroupTemplate(new FileResourceLoader(config.getPath(), config.getCharsetStr())); case WEB_ROOT -> createGroupTemplate(new WebAppResourceLoader(config.getPath(), config.getCharsetStr()));
case WEB_ROOT: case STRING -> createGroupTemplate(new StringTemplateResourceLoader());
return createGroupTemplate(new WebAppResourceLoader(config.getPath(), config.getCharsetStr())); case COMPOSITE ->
case STRING:
return createGroupTemplate(new StringTemplateResourceLoader());
case COMPOSITE:
//TODO 需要定义复合资源加载器 //TODO 需要定义复合资源加载器
return createGroupTemplate(new CompositeResourceLoader()); createGroupTemplate(new CompositeResourceLoader());
default: default -> new GroupTemplate();
return new GroupTemplate(); };
}
} }
/** /**

View File

@ -29,16 +29,12 @@ public class ProxyBeanTest {
void proxyTest() { void proxyTest() {
final IBean bean = ProxyUtil.newProxyInstance((proxy, method, args) -> { final IBean bean = ProxyUtil.newProxyInstance((proxy, method, args) -> {
final String name = method.getName(); final String name = method.getName();
switch (name){ return switch (name) {
case "getName": case "getName" -> "hutool";
return "hutool"; case "setName", "setAge" -> null;
case "setName": case "getAge" -> 1;
case "setAge": default -> throw new HutoolException("No method name: " + name);
return null; };
case "getAge":
return 1;
}
throw new HutoolException("No method name: " + name);
}, IBean.class); }, IBean.class);
// 测试代理类的Bean拷贝 // 测试代理类的Bean拷贝

View File

@ -16,7 +16,6 @@
package cn.hutool.v7.extra.management; package cn.hutool.v7.extra.management;
import cn.hutool.v7.core.lang.Console;
import cn.hutool.v7.core.util.SystemUtil; import cn.hutool.v7.core.util.SystemUtil;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Disabled;

View File

@ -29,15 +29,17 @@ import org.junit.jupiter.api.Test;
*/ */
public class JAXBUtilTest { public class JAXBUtilTest {
private final String xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" + private final String xmlStr = """
"<school>\n" + <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
" <school_name>西安市第一中学</school_name>\n" + <school>
" <school_address>西安市雁塔区长安堡一号</school_address>\n" + <school_name>西安市第一中学</school_name>
" <room>\n" + <school_address>西安市雁塔区长安堡一号</school_address>
" <room_no>101</room_no>\n" + <room>
" <room_name>101教室</room_name>\n" + <room_no>101</room_no>
" </room>\n" + <room_name>101教室</room_name>
"</school>\n"; </room>
</school>
""";
@Test @Test
public void beanToXmlTest() { public void beanToXmlTest() {

View File

@ -197,7 +197,6 @@ public class HttpHeaderUtil {
this.value = split.get(2); this.value = split.get(2);
} else { } else {
this.value = StrUtil.unWrap(value, '"'); this.value = StrUtil.unWrap(value, '"');
;
} }
} }

View File

@ -138,7 +138,7 @@ public interface HttpStatus {
* HTTP 1.1 Status-Code 307: Temporary Redirect.<br> * HTTP 1.1 Status-Code 307: Temporary Redirect.<br>
* 由于不可预见的原因该页面暂不可用当站点支持非 GET 方法的链接或操作的时候该状态码优于 302 状态码<br> * 由于不可预见的原因该页面暂不可用当站点支持非 GET 方法的链接或操作的时候该状态码优于 302 状态码<br>
* 方法和消息主体都不发生变化<br> * 方法和消息主体都不发生变化<br>
* https://www.rfc-editor.org/rfc/rfc7231#section-6.4.7 * <a href="https://www.rfc-editor.org/rfc/rfc7231#section-6.4.7">rfc7231#section-6.4.7</a>
*/ */
int HTTP_TEMP_REDIRECT = 307; int HTTP_TEMP_REDIRECT = 307;
@ -363,23 +363,17 @@ public interface HttpStatus {
if(responseCode < 300){ if(responseCode < 300){
return false; return false;
} }
switch (responseCode){ return switch (responseCode) {
case HTTP_MOVED_PERM:
case HTTP_MOVED_TEMP:
case HTTP_SEE_OTHER:
// issue#1504@Github307和308是RFC 7538中http 1.1定义的规范 // issue#1504@Github307和308是RFC 7538中http 1.1定义的规范
case HTTP_TEMP_REDIRECT: case HTTP_MOVED_PERM, HTTP_MOVED_TEMP, HTTP_SEE_OTHER, HTTP_TEMP_REDIRECT, HTTP_PERMANENT_REDIRECT -> true;
case HTTP_PERMANENT_REDIRECT: default -> false;
return true; };
default:
return false;
}
} }
/** /**
* 是否为重定后请求变更为GET方法307308方法消息主体都不发生变化<br> * 是否为重定后请求变更为GET方法307308方法消息主体都不发生变化<br>
* <ul> * <ul>
* <li>https://www.rfc-editor.org/rfc/rfc7231#section-6.4.7</li> * <li><a href="https://www.rfc-editor.org/rfc/rfc7231#section-6.4.7">rfc7231#section-6.4.7</a></li>
* <li>https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Redirections</li> * <li>https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Redirections</li>
* </ul> * </ul>
* *

View File

@ -33,13 +33,9 @@ public enum Method {
public boolean isIgnoreBody() { public boolean isIgnoreBody() {
//https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/OPTIONS //https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/OPTIONS
// OPTIONS请求可以带有响应体 // OPTIONS请求可以带有响应体
switch (this){ return switch (this) {
case HEAD: case HEAD, CONNECT, TRACE -> true;
case CONNECT: default -> false;
case TRACE: };
return true;
default:
return false;
}
} }
} }

View File

@ -82,7 +82,7 @@ public class MultipartFormData {
break; break;
} }
if (header.isFile == true) { if (header.isFile) {
// 文件类型的表单项 // 文件类型的表单项
final String fileName = header.fileName; final String fileName = header.fileName;
if (!fileName.isEmpty() && header.contentType.contains("application/x-macbinary")) { if (!fileName.isEmpty() && header.contentType.contains("application/x-macbinary")) {
@ -281,7 +281,7 @@ public class MultipartFormData {
* @throws IOException IO异常 * @throws IOException IO异常
*/ */
private void setLoaded() throws IOException { private void setLoaded() throws IOException {
if (loaded == true) { if (loaded) {
throw new IOException("Multi-part request already parsed."); throw new IOException("Multi-part request already parsed.");
} }
loaded = true; loaded = true;

View File

@ -89,12 +89,11 @@ public class MultipartRequestInputStream extends BufferedInputStream {
//noinspection StatementWithEmptyBody //noinspection StatementWithEmptyBody
while ((b = readByte()) <= ' ') { while ((b = readByte()) <= ' ') {
} }
boundaryOutput.write(b);
// now read boundary chars // now read boundary chars
while ((b = readByte()) != '\r') { do {
boundaryOutput.write(b); boundaryOutput.write(b);
} } while ((b = readByte()) != '\r');
if (boundaryOutput.size() == 0) { if (boundaryOutput.size() == 0) {
throw new IOException("Problems with parsing request: invalid boundary"); throw new IOException("Problems with parsing request: invalid boundary");
} }
@ -170,7 +169,7 @@ public class MultipartRequestInputStream extends BufferedInputStream {
data.write(b); data.write(b);
} }
skipBytes(3); skipBytes(3);
return charset == null ? data.toString() : data.toString(charset.name()); return charset == null ? data.toString() : data.toString(charset);
} }
// ---------------------------------------------------------------- copy // ---------------------------------------------------------------- copy

View File

@ -16,13 +16,12 @@
package cn.hutool.v7.http.server.servlet; package cn.hutool.v7.http.server.servlet;
import jakarta.servlet.http.HttpServletRequest;
import cn.hutool.v7.http.server.handler.ServerRequest; import cn.hutool.v7.http.server.handler.ServerRequest;
import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**

View File

@ -16,7 +16,6 @@
package cn.hutool.v7.http.webservice; package cn.hutool.v7.http.webservice;
import jakarta.xml.soap.*;
import cn.hutool.v7.core.collection.CollUtil; import cn.hutool.v7.core.collection.CollUtil;
import cn.hutool.v7.core.map.MapUtil; import cn.hutool.v7.core.map.MapUtil;
import cn.hutool.v7.core.text.StrUtil; import cn.hutool.v7.core.text.StrUtil;
@ -27,6 +26,7 @@ import cn.hutool.v7.http.client.HeaderOperation;
import cn.hutool.v7.http.client.Request; import cn.hutool.v7.http.client.Request;
import cn.hutool.v7.http.client.Response; import cn.hutool.v7.http.client.Response;
import cn.hutool.v7.http.meta.Method; import cn.hutool.v7.http.meta.Method;
import jakarta.xml.soap.*;
import javax.xml.XMLConstants; import javax.xml.XMLConstants;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
@ -64,7 +64,7 @@ public class SoapClient implements HeaderOperation<SoapClient> {
* XML消息体的Content-Type * XML消息体的Content-Type
* soap1.1 : text/xml * soap1.1 : text/xml
* soap1.2 : application/soap+xml * soap1.2 : application/soap+xml
* soap1.1与soap1.2区别: https://www.cnblogs.com/qlqwjy/p/7577147.html * soap1.1与soap1.2区别: <a href="https://www.cnblogs.com/qlqwjy/p/7577147.html">https://www.cnblogs.com/qlqwjy/p/7577147.html</a>
*/ */
private static final String CONTENT_TYPE_SOAP11_TEXT_XML = "text/xml;charset="; private static final String CONTENT_TYPE_SOAP11_TEXT_XML = "text/xml;charset=";
private static final String CONTENT_TYPE_SOAP12_SOAP_XML = "application/soap+xml;charset="; private static final String CONTENT_TYPE_SOAP12_SOAP_XML = "application/soap+xml;charset=";
@ -568,14 +568,10 @@ public class SoapClient implements HeaderOperation<SoapClient> {
* @return 请求的Content-Type * @return 请求的Content-Type
*/ */
private String getXmlContentType() { private String getXmlContentType() {
switch (this.protocol) { return switch (this.protocol) {
case SOAP_1_1: case SOAP_1_1 -> CONTENT_TYPE_SOAP11_TEXT_XML.concat(this.charset.toString());
return CONTENT_TYPE_SOAP11_TEXT_XML.concat(this.charset.toString()); case SOAP_1_2 -> CONTENT_TYPE_SOAP12_SOAP_XML.concat(this.charset.toString());
case SOAP_1_2: };
return CONTENT_TYPE_SOAP12_SOAP_XML.concat(this.charset.toString());
default:
throw new SoapRuntimeException("Unsupported protocol: {}", this.protocol);
}
} }
/** /**

View File

@ -16,17 +16,14 @@
package cn.hutool.v7.http.webservice; package cn.hutool.v7.http.webservice;
import java.io.ByteArrayOutputStream; import cn.hutool.v7.core.util.CharsetUtil;
import java.io.IOException; import cn.hutool.v7.core.xml.XmlUtil;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import jakarta.xml.soap.SOAPException; import jakarta.xml.soap.SOAPException;
import jakarta.xml.soap.SOAPMessage; import jakarta.xml.soap.SOAPMessage;
import cn.hutool.v7.core.exception.HutoolException; import java.io.ByteArrayOutputStream;
import cn.hutool.v7.core.util.CharsetUtil; import java.io.IOException;
import cn.hutool.v7.core.xml.XmlUtil; import java.nio.charset.Charset;
/** /**
* SOAP相关工具类 * SOAP相关工具类
@ -98,11 +95,7 @@ public class SoapUtil {
throw new SoapRuntimeException(e); throw new SoapRuntimeException(e);
} }
final String messageToString; final String messageToString;
try { messageToString = out.toString(charset);
messageToString = out.toString(charset.toString());
} catch (final UnsupportedEncodingException e) {
throw new HutoolException(e);
}
return pretty ? XmlUtil.format(messageToString) : messageToString; return pretty ? XmlUtil.format(messageToString) : messageToString;
} }
} }

View File

@ -174,15 +174,16 @@ public class HttpUtilTest {
@Test @Test
@Disabled @Disabled
public void httpUtilCreateRequest1PostSoap11Test(){ public void httpUtilCreateRequest1PostSoap11Test(){
final String requestBody = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + final String requestBody = """
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n" + <?xml version="1.0" encoding="utf-8"?>
" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" + <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
" <soap:Body>\n" + xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
" <getCountryCityByIp xmlns=\"http://WebXml.com.cn/\">\n" + <soap:Body>
" <theIpAddress>222.91.66.232</theIpAddress>\n" + <getCountryCityByIp xmlns="http://WebXml.com.cn/">
" </getCountryCityByIp>\n" + <theIpAddress>222.91.66.232</theIpAddress>
" </soap:Body>\n" + </getCountryCityByIp>
"</soap:Envelope>"; </soap:Body>
</soap:Envelope>""";
final String body = HttpUtil.createRequest("http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx", Method.POST) final String body = HttpUtil.createRequest("http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx", Method.POST)
.header(HeaderName.CONTENT_TYPE, "text/xml; charset=utf-8") .header(HeaderName.CONTENT_TYPE, "text/xml; charset=utf-8")
@ -201,15 +202,16 @@ public class HttpUtilTest {
@Test @Test
@Disabled @Disabled
public void httpUtilCreateRequest2PostSoap12Test(){ public void httpUtilCreateRequest2PostSoap12Test(){
final String requestBody = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + final String requestBody = """
"<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n" + <?xml version="1.0" encoding="utf-8"?>
" xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">\n" + <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
" <soap12:Body>\n" + xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
" <getCountryCityByIp xmlns=\"http://WebXml.com.cn/\">\n" + <soap12:Body>
" <theIpAddress>222.91.66.232</theIpAddress>\n" + <getCountryCityByIp xmlns="http://WebXml.com.cn/">
" </getCountryCityByIp>\n" + <theIpAddress>222.91.66.232</theIpAddress>
" </soap12:Body>\n" + </getCountryCityByIp>
"</soap12:Envelope>"; </soap12:Body>
</soap12:Envelope>""";
final String body = HttpUtil.createPost("http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx") final String body = HttpUtil.createPost("http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx")
.header(HeaderName.CONTENT_TYPE, "application/soap+xml; charset=utf-8") .header(HeaderName.CONTENT_TYPE, "application/soap+xml; charset=utf-8")

View File

@ -35,9 +35,11 @@ public class ContentTypeTest {
@Test @Test
void testGetWithLeadingSpace() { void testGetWithLeadingSpace() {
final String json = " {\n" + final String json = """
" \"name\": \"hutool\"\n" + {
" }"; "name": "hutool"
}\
""";
final ContentType contentType = ContentType.get(json); final ContentType contentType = ContentType.get(json);
assertEquals(ContentType.JSON, contentType); assertEquals(ContentType.JSON, contentType);
} }

View File

@ -23,7 +23,7 @@ import java.security.KeyPair;
/** /**
* 椭圆曲线Elliptic Curve的JWT签名器<br> * 椭圆曲线Elliptic Curve的JWT签名器<br>
* 按照https://datatracker.ietf.org/doc/html/rfc7518#section-3.4,<br> * 按照<a href="https://datatracker.ietf.org/doc/html/rfc7518#section-3.4">rfc7518#section-3.4</a>,<br>
* Elliptic Curve Digital Signature Algorithm (ECDSA)算法签名需要转换DER格式为pair (R, S) * Elliptic Curve Digital Signature Algorithm (ECDSA)算法签名需要转换DER格式为pair (R, S)
* *
* @author Looly * @author Looly
@ -71,19 +71,12 @@ public class EllipticCurveJWTSigner extends AsymmetricJWTSigner {
* @throws JWTException JWT异常 * @throws JWTException JWT异常
*/ */
private static int getSignatureByteArrayLength(final String alg) throws JWTException { private static int getSignatureByteArrayLength(final String alg) throws JWTException {
switch (alg) { return switch (alg) {
case "ES256": case "ES256", "SHA256withECDSA" -> 64;
case "SHA256withECDSA": case "ES384", "SHA384withECDSA" -> 96;
return 64; case "ES512", "SHA512withECDSA" -> 132;
case "ES384": default -> throw new JWTException("Unsupported Algorithm: {}", alg);
case "SHA384withECDSA": };
return 96;
case "ES512":
case "SHA512withECDSA":
return 132;
default:
throw new JWTException("Unsupported Algorithm: {}", alg);
}
} }
/** /**

View File

@ -16,7 +16,6 @@
package cn.hutool.v7.json.jwt.signers; package cn.hutool.v7.json.jwt.signers;
import cn.hutool.v7.core.lang.Assert;
import cn.hutool.v7.core.regex.ReUtil; import cn.hutool.v7.core.regex.ReUtil;
import cn.hutool.v7.json.jwt.JWTException; import cn.hutool.v7.json.jwt.JWTException;

View File

@ -71,7 +71,7 @@ public class JSONTokener extends ReaderWrapper {
* 是否使用前一个字符 * 是否使用前一个字符
*/ */
private boolean usePrevious; private boolean usePrevious;
private boolean ignoreZeroWithChar; private final boolean ignoreZeroWithChar;
// ------------------------------------------------------------------------------------ Constructor start // ------------------------------------------------------------------------------------ Constructor start
@ -302,14 +302,14 @@ public class JSONTokener extends ReaderWrapper {
*/ */
public String nextString() throws JSONException { public String nextString() throws JSONException {
final char c = nextClean(); final char c = nextClean();
switch (c) { return switch (c) {
case CharUtil.DOUBLE_QUOTES: case CharUtil.DOUBLE_QUOTES, CharUtil.SINGLE_QUOTE -> nextWrapString(c);
case CharUtil.SINGLE_QUOTE: default ->
return nextWrapString(c);
}
// 兼容不严格的JSON如key不被双引号包围的情况 // 兼容不严格的JSON如key不被双引号包围的情况
return nextUnwrapString(c); nextUnwrapString(c);
};
} }
/** /**
@ -445,27 +445,17 @@ public class JSONTokener extends ReaderWrapper {
* @return 反转义字符 * @return 反转义字符
*/ */
private char getUnescapeChar(final char c) { private char getUnescapeChar(final char c) {
switch (c) { return switch (c) {
case 'b': case 'b' -> '\b';
return '\b'; case 't' -> '\t';
case 't': case 'n' -> '\n';
return '\t'; case 'f' -> '\f';
case 'n': case 'r' -> '\r';
return '\n'; case 'u' ->// Unicode符
case 'f': nextUnicode();
return '\f'; case CharUtil.DOUBLE_QUOTES, CharUtil.SINGLE_QUOTE, CharUtil.BACKSLASH, CharUtil.SLASH -> c;
case 'r': default -> throw this.syntaxError("Illegal escape.");
return '\r'; };
case 'u':// Unicode符
return nextUnicode();
case CharUtil.DOUBLE_QUOTES:
case CharUtil.SINGLE_QUOTE:
case CharUtil.BACKSLASH:
case CharUtil.SLASH:
return c;
default:
throw this.syntaxError("Illegal escape.");
}
} }
/** /**

View File

@ -87,7 +87,7 @@ public class JSONFormatStyle {
*/ */
public JSONFormatStyle(final String newline, final String indent, final boolean spaceAfterSeparators) { public JSONFormatStyle(final String newline, final String indent, final boolean spaceAfterSeparators) {
this.newline = Assert.notNull(newline); this.newline = Assert.notNull(newline);
this.indent = Assert.notNull(indent);; this.indent = Assert.notNull(indent);
this.spaceAfterSeparators = spaceAfterSeparators; this.spaceAfterSeparators = spaceAfterSeparators;
} }

View File

@ -23,11 +23,12 @@ public class JSONNullTest {
@Test @Test
public void parseNullTest(){ public void parseNullTest(){
final JSONObject bodyjson = JSONUtil.parseObj("{\n" + final JSONObject bodyjson = JSONUtil.parseObj("""
" \"device_model\": null,\n" + {
" \"device_status_date\": null,\n" + "device_model": null,
" \"imsi\": null,\n" + "device_status_date": null,
" \"act_date\": \"2021-07-23T06:23:26.000+00:00\"}"); "imsi": null,
"act_date": "2021-07-23T06:23:26.000+00:00"}""");
Assertions.assertNull(bodyjson.get("device_model")); Assertions.assertNull(bodyjson.get("device_model"));
Assertions.assertNull(bodyjson.get("device_status_date")); Assertions.assertNull(bodyjson.get("device_status_date"));
Assertions.assertNull(bodyjson.get("imsi")); Assertions.assertNull(bodyjson.get("imsi"));
@ -38,11 +39,12 @@ public class JSONNullTest {
@Test @Test
public void parseNullTest2(){ public void parseNullTest2(){
final JSONObject bodyjson = JSONUtil.parseObj("{\n" + final JSONObject bodyjson = JSONUtil.parseObj("""
" \"device_model\": null,\n" + {
" \"device_status_date\": null,\n" + "device_model": null,
" \"imsi\": null,\n" + "device_status_date": null,
" \"act_date\": \"2021-07-23T06:23:26.000+00:00\"}"); "imsi": null,
"act_date": "2021-07-23T06:23:26.000+00:00"}""");
Assertions.assertFalse(bodyjson.containsKey("device_model")); Assertions.assertFalse(bodyjson.containsKey("device_model"));
Assertions.assertFalse(bodyjson.containsKey("device_status_date")); Assertions.assertFalse(bodyjson.containsKey("device_status_date"));
Assertions.assertFalse(bodyjson.containsKey("imsi")); Assertions.assertFalse(bodyjson.containsKey("imsi"));

View File

@ -164,21 +164,22 @@ public class JSONUtilTest {
map.put("rows", list); map.put("rows", list);
final String jsonStr = JSONUtil.toJsonPrettyStr(map); final String jsonStr = JSONUtil.toJsonPrettyStr(map);
Assertions.assertEquals("{\n" + Assertions.assertEquals("""
" \"total\": 13,\n" + {
" \"rows\": [\n" + "total": 13,
" {\n" + "rows": [
" \"name\": \"AAAAName\",\n" + {
" \"a\": \"aaaa\",\n" + "name": "AAAAName",
" \"date\": 1727800929605\n" + "a": "aaaa",
" },\n" + "date": 1727800929605
" {\n" + },
" \"name\": \"AAAA222Name\",\n" + {
" \"a\": \"aaaa222\",\n" + "name": "AAAA222Name",
" \"date\": 1727800929605\n" + "a": "aaaa222",
" }\n" + "date": 1727800929605
" ]\n" + }
"}", jsonStr); ]
}""", jsonStr);
} }
@Test @Test
@ -311,9 +312,10 @@ public class JSONUtilTest {
@Test @Test
public void parseObjTest() { public void parseObjTest() {
// 测试转义 // 测试转义
final JSONObject jsonObject = JSONUtil.parseObj("{\n" + final JSONObject jsonObject = JSONUtil.parseObj("""
" \"test\": \"\\\\地库地库\",\n" + {
"}"); "test": "\\\\地库地库",
}""");
assertEquals("\\地库地库", jsonObject.getObj("test")); assertEquals("\\地库地库", jsonObject.getObj("test"));
} }

View File

@ -36,11 +36,12 @@ public class FastJSONTest {
String jsonString = engine.toJsonString(testBean); String jsonString = engine.toJsonString(testBean);
// 使用统一换行符 // 使用统一换行符
jsonString = StrUtil.removeAll(jsonString, '\r'); jsonString = StrUtil.removeAll(jsonString, '\r');
Assertions.assertEquals("{\n" + Assertions.assertEquals("""
" \"name\":\"张三\",\n" + {
" \"age\":18,\n" + "name":"张三",
" \"gender\":true\n" + "age":18,
"}", jsonString); "gender":true
}""", jsonString);
} }
@Test @Test

View File

@ -37,11 +37,12 @@ public class GsonTest {
final JSONEngineTest.TestBean testBean = new JSONEngineTest.TestBean("张三", 18, true); final JSONEngineTest.TestBean testBean = new JSONEngineTest.TestBean("张三", 18, true);
final String jsonString = engine.toJsonString(testBean); final String jsonString = engine.toJsonString(testBean);
// 使用统一换行符 // 使用统一换行符
Assertions.assertEquals("{\n" + Assertions.assertEquals("""
" \"name\": \"张三\",\n" + {
" \"age\": 18,\n" + "name": "张三",
" \"gender\": true\n" + "age": 18,
"}", jsonString); "gender": true
}""", jsonString);
} }
@Test @Test

View File

@ -27,10 +27,11 @@ public class HutoolJSONTest {
final JSONEngineTest.TestBean testBean = new JSONEngineTest.TestBean("张三", 18, true); final JSONEngineTest.TestBean testBean = new JSONEngineTest.TestBean("张三", 18, true);
final String jsonString = engine.toJsonString(testBean); final String jsonString = engine.toJsonString(testBean);
Assertions.assertEquals("{\n" + Assertions.assertEquals("""
" \"name\": \"张三\",\n" + {
" \"age\": 18,\n" + "name": "张三",
" \"gender\": true\n" + "age": 18,
"}", jsonString); "gender": true
}""", jsonString);
} }
} }

View File

@ -160,19 +160,21 @@ public class JSONEngineTest {
if("moshi".equals(engineName)){ if("moshi".equals(engineName)){
// Moshi顺序不同 // Moshi顺序不同
// 使用统一换行符 // 使用统一换行符
assertEquals("{\n" + assertEquals("""
" \"age\": 18,\n" + {
" \"gender\": true,\n" + "age": 18,
" \"name\": \"张三\"\n" + "gender": true,
"}", jsonString); "name": "张三"
}""", jsonString);
return; return;
} }
// 使用统一换行符 // 使用统一换行符
assertEquals("{\n" + assertEquals("""
" \"name\": \"张三\",\n" + {
" \"age\": 18,\n" + "name": "张三",
" \"gender\": true\n" + "age": 18,
"}", jsonString); "gender": true
}""", jsonString);
} }
@Data @Data

View File

@ -35,15 +35,16 @@ public class JacksonTest {
String jsonString = engine.toJsonString(testBean); String jsonString = engine.toJsonString(testBean);
// 使用统一换行符 // 使用统一换行符
jsonString = StrUtil.removeAll(jsonString, '\r'); jsonString = StrUtil.removeAll(jsonString, '\r');
Assertions.assertEquals("{\n" + Assertions.assertEquals("""
" \"name\" : \"张三\",\n" + {
" \"age\" : 18,\n" + "name" : "张三",
" \"gender\" : true\n" + "age" : 18,
"}", jsonString); "gender" : true
}""", jsonString);
} }
/** /**
* https://gitee.com/chinabugotech/hutool/issues/IB3GM4<br> * <a href="https://gitee.com/chinabugotech/hutool/issues/IB3GM4">issues#IB3GM4</a><br>
* JSON和Jackson兼容 * JSON和Jackson兼容
*/ */
@Test @Test

View File

@ -45,34 +45,35 @@ public class Issue1101Test {
@Test @Test
public void test(){ public void test(){
final String json = "{\n" + final String json = """
"\t\"children\": [{\n" + {
"\t\t\"children\": [],\n" + \t"children": [{
"\t\t\"id\": \"52c95b83-2083-4138-99fb-e6e21f0c1277\",\n" + \t\t"children": [],
"\t\t\"nodeName\": \"admin\",\n" + \t\t"id": "52c95b83-2083-4138-99fb-e6e21f0c1277",
"\t\t\"parentId\": \"00010001\",\n" + \t\t"nodeName": "admin",
"\t\t\"sort\": 0,\n" + \t\t"parentId": "00010001",
"\t\t\"status\": true,\n" + \t\t"sort": 0,
"\t\t\"treeNodeId\": \"00010001_52c95b83-2083-4138-99fb-e6e21f0c1277\",\n" + \t\t"status": true,
"\t\t\"type\": 10\n" + \t\t"treeNodeId": "00010001_52c95b83-2083-4138-99fb-e6e21f0c1277",
"\t}, {\n" + \t\t"type": 10
"\t\t\"children\": [],\n" + \t}, {
"\t\t\"id\": \"97054a82-f8ff-46a1-b76c-cbacf6d18045\",\n" + \t\t"children": [],
"\t\t\"nodeName\": \"test\",\n" + \t\t"id": "97054a82-f8ff-46a1-b76c-cbacf6d18045",
"\t\t\"parentId\": \"00010001\",\n" + \t\t"nodeName": "test",
"\t\t\"sort\": 0,\n" + \t\t"parentId": "00010001",
"\t\t\"status\": true,\n" + \t\t"sort": 0,
"\t\t\"treeNodeId\": \"00010001_97054a82-f8ff-46a1-b76c-cbacf6d18045\",\n" + \t\t"status": true,
"\t\t\"type\": 10\n" + \t\t"treeNodeId": "00010001_97054a82-f8ff-46a1-b76c-cbacf6d18045",
"\t}],\n" + \t\t"type": 10
"\t\"id\": \"00010001\",\n" + \t}],
"\t\"nodeName\": \"测试\",\n" + \t"id": "00010001",
"\t\"parentId\": \"0001\",\n" + \t"nodeName": "测试",
"\t\"sort\": 0,\n" + \t"parentId": "0001",
"\t\"status\": true,\n" + \t"sort": 0,
"\t\"treeNodeId\": \"00010001\",\n" + \t"status": true,
"\t\"type\": 0\n" + \t"treeNodeId": "00010001",
"}"; \t"type": 0
}""";
final JSONObject jsonObject = JSONUtil.parseObj(json); final JSONObject jsonObject = JSONUtil.parseObj(json);

View File

@ -30,12 +30,13 @@ import java.util.List;
public class Issue3139Test { public class Issue3139Test {
@Test @Test
public void toBeanTest() { public void toBeanTest() {
final String xml = "<r>\n" + final String xml = """
" <c>\n" + <r>
" <s>1</s>\n" + <c>
" <p>str</p>\n" + <s>1</s>
" </c>\n" + <p>str</p>
"</r>"; </c>
</r>""";
final JSONObject jsonObject = JSONUtil.parseObj(xml); final JSONObject jsonObject = JSONUtil.parseObj(xml);
Assertions.assertEquals("{\"r\":{\"c\":{\"s\":1,\"p\":\"str\"}}}", jsonObject.toString()); Assertions.assertEquals("{\"r\":{\"c\":{\"s\":1,\"p\":\"str\"}}}", jsonObject.toString());

View File

@ -28,12 +28,13 @@ import org.junit.jupiter.api.Test;
public class Issue3274Test { public class Issue3274Test {
@Test @Test
public void toBeanTest() { public void toBeanTest() {
final JSONObject entries = JSONUtil.parseObj("{\n" + final JSONObject entries = JSONUtil.parseObj("""
" \n" + {
" \"age\": 36,\n" + \s
" \"gender\": \"\",\n" + "age": 36,
" \"id\": \"123123123\"\n" + "gender": "",
"}", JSONConfig.of().setIgnoreError(true)); "id": "123123123"
}""", JSONConfig.of().setIgnoreError(true));
final LarkCoreHrPersonal larkCoreHrPersonal = entries.toBean(LarkCoreHrPersonal.class); final LarkCoreHrPersonal larkCoreHrPersonal = entries.toBean(LarkCoreHrPersonal.class);
Assertions.assertNotNull(larkCoreHrPersonal); Assertions.assertNotNull(larkCoreHrPersonal);
} }

View File

@ -26,15 +26,16 @@ public class IssueI5DHK2Test {
@Test @Test
public void toBeanTest(){ public void toBeanTest(){
final String jsonStr = "{\n" + final String jsonStr = """
" \"punished_parties\": [{\n" + {
" \"properties\": {\n" + "punished_parties": [{
" \"employment_informations\": [{\n" + "properties": {
" \"employer_name\": \"张三皮包公司\"\n" + "employment_informations": [{
" }]\n" + "employer_name": "张三皮包公司"
" }\n" + }]
" }]\n" + }
"}"; }]
}""";
final JSONObject json = JSONUtil.parseObj(jsonStr); final JSONObject json = JSONUtil.parseObj(jsonStr);
final String exployerName = json final String exployerName = json

Some files were not shown because too many files have changed in this diff Show More