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
public void chat(List<Message> messages, Consumer<String> callback) {
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

View File

@ -74,7 +74,7 @@ public class DoubaoServiceImpl extends BaseAIService implements DoubaoService {
@Override
public void chat(final List<Message> messages, final Consumer<String> callback) {
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
@ -87,7 +87,7 @@ public class DoubaoServiceImpl extends BaseAIService implements DoubaoService {
@Override
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);
ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback::accept), "doubao-chatVision-sse").start();
ThreadUtil.newThread(() -> sendPostStream(CHAT_ENDPOINT, paramMap, callback), "doubao-chatVision-sse").start();
}
@Override
@ -128,7 +128,7 @@ public class DoubaoServiceImpl extends BaseAIService implements DoubaoService {
@Override
public void botsChat(final List<Message> messages, final Consumer<String> callback) {
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
@ -162,7 +162,7 @@ public class DoubaoServiceImpl extends BaseAIService implements DoubaoService {
@Override
public void chatContext(final List<Message> messages, final String contextId, final Consumer<String> callback) {
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

View File

@ -67,7 +67,7 @@ public class GrokServiceImpl extends BaseAIService implements GrokService {
@Override
public void chat(List<Message> messages, Consumer<String> callback) {
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
@ -80,7 +80,7 @@ public class GrokServiceImpl extends BaseAIService implements GrokService {
@Override
public void message(List<Message> messages, int maxToken, final Consumer<String> callback) {
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
@ -93,7 +93,7 @@ public class GrokServiceImpl extends BaseAIService implements GrokService {
@Override
public void chatVision(String prompt, List<String> images, String detail, Consumer<String> callback) {
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

View File

@ -71,7 +71,7 @@ public class HutoolServiceImpl extends BaseAIService implements HutoolService {
@Override
public void chat(List<Message> messages,Consumer<String> callback) {
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
@ -85,7 +85,7 @@ public class HutoolServiceImpl extends BaseAIService implements HutoolService {
public void chatVision(String prompt, List<String> images, String detail, Consumer<String> callback) {
Map<String, Object> paramMap = buildChatVisionStreamRequestBody(prompt, images, detail);
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

View File

@ -84,7 +84,7 @@ public class OllamaServiceImpl extends BaseAIService implements OllamaService {
@Override
public void chat(final List<Message> messages, final Consumer<String> callback) {
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
@ -97,7 +97,7 @@ public class OllamaServiceImpl extends BaseAIService implements OllamaService {
@Override
public void generate(final String prompt, final Consumer<String> callback) {
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
@ -110,7 +110,7 @@ public class OllamaServiceImpl extends BaseAIService implements OllamaService {
@Override
public void generate(final String prompt, final String format, final Consumer<String> callback) {
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

View File

@ -72,7 +72,7 @@ public class OpenaiServiceImpl extends BaseAIService implements OpenaiService {
@Override
public void chat(List<Message> messages, Consumer<String> callback) {
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
@ -85,7 +85,7 @@ public class OpenaiServiceImpl extends BaseAIService implements OpenaiService {
@Override
public void chatVision(String prompt, List<String> images, String detail, Consumer<String> callback) {
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
@ -147,7 +147,7 @@ public class OpenaiServiceImpl extends BaseAIService implements OpenaiService {
@Override
public void chatReasoning(List<Message> messages, String reasoningEffort, Consumer<String> callback) {
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请求体

View File

@ -27,15 +27,14 @@ import cn.hutool.v7.swing.img.ImgUtil;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import java.awt.*;
import java.awt.Toolkit;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertNotNull;
class HutoolServiceTest {
@ -88,7 +87,7 @@ class HutoolServiceTest {
@Disabled
void chatVision() {
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);
}
@ -96,7 +95,7 @@ class HutoolServiceTest {
@Disabled
void testChatVisionStream() {
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 isDone = new AtomicBoolean(false);
@ -119,7 +118,7 @@ class HutoolServiceTest {
@Test
@Disabled
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);
}
@ -150,10 +149,11 @@ class HutoolServiceTest {
void textToSpeech() {
try {
// 测试正常音频流返回
final InputStream inputStream = hutoolService.tts("万里山河一夜白,\n" +
"千峰尽染玉龙哀。\n" +
"长风卷起琼花碎,\n" +
"直上九霄揽月来。", HutoolCommon.HutoolSpeech.NOVA);
final InputStream inputStream = hutoolService.tts("""
万里山河一夜白
千峰尽染玉龙哀
长风卷起琼花碎
直上九霄揽月来""", HutoolCommon.HutoolSpeech.NOVA);
assertNotNull(inputStream);
// 保存音频文件

View File

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

View File

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

View File

@ -79,7 +79,7 @@ public class LRUCache<K, V> extends LockedCache<K, V> {
*/
@Override
protected int pruneCache() {
if (isPruneExpiredActive() == false) {
if (!isPruneExpiredActive()) {
return 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
if (saltLeft > 0) {
System.arraycopy(currentAlphabet, 0, decodeSalt,

View File

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

View File

@ -55,7 +55,7 @@ public class PunyCode {
final List<String> split = SplitUtil.split(domain, StrUtil.DOT);
final StringBuilder result = new StringBuilder(domain.length() * 4);
for (final String str : split) {
if (result.length() != 0) {
if (!result.isEmpty()) {
result.append(CharUtil.DOT);
}
result.append(encode(str, true));
@ -175,7 +175,7 @@ public class PunyCode {
final List<String> split = SplitUtil.split(domain, StrUtil.DOT);
final StringBuilder result = new StringBuilder(domain.length() / 4 + 1);
for (final String str : split) {
if (result.length() != 0) {
if (!result.isEmpty()) {
result.append(CharUtil.DOT);
}
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) {
switch (byteToCheck) {
case ' ':
case '\n':
case '\r':
case '\t':
return true;
default:
return false;
}
return switch (byteToCheck) {
case ' ', '\n', '\r', '\t' -> true;
default -> false;
};
}
}

View File

@ -23,7 +23,7 @@ import java.util.Objects;
/**
* 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>.
* 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
*/
protected static boolean isWhiteSpace(final byte byteToCheck) {
switch (byteToCheck) {
case ' ':
case '\n':
case '\r':
case '\t':
return true;
default:
return false;
}
return switch (byteToCheck) {
case ' ', '\n', '\r', '\t' -> true;
default -> false;
};
}
/**
@ -609,128 +604,40 @@ public class CrockfordBase32Codec {
}
private static byte decode(final byte octet) {
switch (octet) {
case '0':
case 'O':
case 'o':
return 0;
case '1':
case 'I':
case 'i':
case 'L':
case 'l':
return 1;
case '2':
return 2;
case '3':
return 3;
case '4':
return 4;
case '5':
return 5;
case '6':
return 6;
case '7':
return 7;
case '8':
return 8;
case '9':
return 9;
case 'A':
case 'a':
return 10;
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;
}
return switch (octet) {
case '0', 'O', 'o' -> 0;
case '1', 'I', 'i', 'L', 'l' -> 1;
case '2' -> 2;
case '3' -> 3;
case '4' -> 4;
case '5' -> 5;
case '6' -> 6;
case '7' -> 7;
case '8' -> 8;
case '9' -> 9;
case 'A', 'a' -> 10;
case 'B', 'b' -> 11;
case 'C', 'c' -> 12;
case 'D', 'd' -> 13;
case 'E', 'e' -> 14;
case 'F', 'f' -> 15;
case 'G', 'g' -> 16;
case 'H', 'h' -> 17;
case 'J', 'j' -> 18;
case 'K', 'k' -> 19;
case 'M', 'm' -> 20;
case 'N', 'n' -> 21;
case 'P', 'p' -> 22;
case 'Q', 'q' -> 23;
case 'R', 'r' -> 24;
case 'S', 's' -> 25;
case 'T', 't' -> 26;
case 'U', 'u', 'V', 'v' -> 27;
case 'W', 'w' -> 28;
case 'X', 'x' -> 29;
case 'Y', 'y' -> 30;
case 'Z', 'z' -> 31;
default -> -1;
};
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -71,24 +71,16 @@ public class TemporalUtil {
if (null == unit) {
return null;
}
switch (unit) {
case NANOSECONDS:
return ChronoUnit.NANOS;
case MICROSECONDS:
return ChronoUnit.MICROS;
case MILLISECONDS:
return ChronoUnit.MILLIS;
case SECONDS:
return ChronoUnit.SECONDS;
case MINUTES:
return ChronoUnit.MINUTES;
case HOURS:
return ChronoUnit.HOURS;
case DAYS:
return ChronoUnit.DAYS;
default:
throw new IllegalArgumentException("Unknown TimeUnit constant");
}
return switch (unit) {
case NANOSECONDS -> ChronoUnit.NANOS;
case MICROSECONDS -> ChronoUnit.MICROS;
case MILLISECONDS -> ChronoUnit.MILLIS;
case SECONDS -> ChronoUnit.SECONDS;
case MINUTES -> ChronoUnit.MINUTES;
case HOURS -> ChronoUnit.HOURS;
case DAYS -> ChronoUnit.DAYS;
default -> throw new IllegalArgumentException("Unknown TimeUnit constant");
};
}
/**
@ -103,24 +95,16 @@ public class TemporalUtil {
if (null == unit) {
return null;
}
switch (unit) {
case NANOS:
return TimeUnit.NANOSECONDS;
case MICROS:
return TimeUnit.MICROSECONDS;
case MILLIS:
return TimeUnit.MILLISECONDS;
case SECONDS:
return TimeUnit.SECONDS;
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);
}
return switch (unit) {
case NANOS -> TimeUnit.NANOSECONDS;
case MICROS -> TimeUnit.MICROSECONDS;
case MILLIS -> TimeUnit.MILLISECONDS;
case SECONDS -> TimeUnit.SECONDS;
case MINUTES -> TimeUnit.MINUTES;
case HOURS -> TimeUnit.HOURS;
case DAYS -> 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
*/
public String toChinese(final String weekNamePre) {
switch (this) {
case SUNDAY:
return weekNamePre + "";
case MONDAY:
return weekNamePre + "";
case TUESDAY:
return weekNamePre + "";
case WEDNESDAY:
return weekNamePre + "";
case THURSDAY:
return weekNamePre + "";
case FRIDAY:
return weekNamePre + "";
case SATURDAY:
return weekNamePre + "";
default:
return null;
}
return switch (this) {
case SUNDAY -> weekNamePre + "";
case MONDAY -> weekNamePre + "";
case TUESDAY -> weekNamePre + "";
case WEDNESDAY -> weekNamePre + "";
case THURSDAY -> weekNamePre + "";
case FRIDAY -> weekNamePre + "";
case SATURDAY -> weekNamePre + "";
};
}
/**
@ -176,7 +167,7 @@ public enum Week {
/**
* 解析别名为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 别名值
* @return 周枚举Week非空
@ -188,23 +179,16 @@ public enum Week {
// issue#3637
if (StrUtil.startWithAny(name, "星期", "")) {
final char chineseNumber = name.charAt(name.length() - 1);
switch (chineseNumber) {
case '一':
return MONDAY;
case '二':
return TUESDAY;
case '三':
return WEDNESDAY;
case '四':
return THURSDAY;
case '五':
return FRIDAY;
case '六':
return SATURDAY;
case '日':
return SUNDAY;
}
throw new IllegalArgumentException("Invalid week name: " + name);
return switch (chineseNumber) {
case '一' -> MONDAY;
case '二' -> TUESDAY;
case '三' -> WEDNESDAY;
case '四' -> THURSDAY;
case '五' -> FRIDAY;
case '六' -> SATURDAY;
case '日' -> SUNDAY;
default -> throw new IllegalArgumentException("Invalid week name: " + name);
};
}
switch (Character.toLowerCase(name.charAt(0))) {

View File

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

View File

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

View File

@ -75,10 +75,9 @@ public class SimpleDateBasic implements DateBasic, Serializable {
// ----------------------------------------------------------------------- Basics
@Override
public boolean equals(final Object obj) {
if (obj instanceof FastDatePrinter == false) {
if (!(obj instanceof FastDatePrinter other)) {
return false;
}
final SimpleDateBasic other = (SimpleDateBasic) obj;
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);
final int maxLength = columnCharNumber.get(i);
for (int j = 0; j < (maxLength - length + (sbcCount / 2)); j++) {
sb.append(SPACE);
}
sb.append(String.valueOf(SPACE).repeat(Math.max(0, (maxLength - length + (sbcCount / 2)))));
sb.append(COLUMN_LINE);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -270,14 +270,11 @@ public class UrlQuery {
* @return URL查询字符串
*/
public String build(final Charset charset) {
switch (this.encodeMode) {
case FORM_URL_ENCODED:
return build(FormUrlencoded.ALL, FormUrlencoded.ALL, charset);
case STRICT:
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);
}
return switch (this.encodeMode) {
case FORM_URL_ENCODED -> build(FormUrlencoded.ALL, FormUrlencoded.ALL, charset);
case STRICT -> build(RFC3986.QUERY_PARAM_NAME_STRICT, RFC3986.QUERY_PARAM_VALUE_STRICT, charset);
default -> 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) {
name = entry.getKey();
if (null != name) {
if (sb.length() > 0) {
if (!sb.isEmpty()) {
sb.append("&");
}
sb.append(keyCoder.encode(name, charset));
@ -332,7 +329,7 @@ public class UrlQuery {
/**
* 解析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 charset decode编码null表示不做decode

View File

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

View File

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

View File

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

View File

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

View File

@ -157,7 +157,7 @@ public class StrValidator {
* @see #isBlank(CharSequence)
*/
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) {
final int length = foundWord.getFoundWord().length();
final StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
sb.append("*");
}
return sb.toString();
return "*".repeat(length);
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -48,16 +48,12 @@ public class ProxyBeanTest {
void proxyTest() {
final IBean bean = JdkProxyUtil.newProxyInstance((proxy, method, args) -> {
final String name = method.getName();
switch (name){
case "getName":
return "hutool";
case "setName":
case "setAge":
return null;
case "getAge":
return 1;
}
throw new HutoolException("No method name: " + name);
return switch (name) {
case "getName" -> "hutool";
case "setName", "setAge" -> null;
case "getAge" -> 1;
default -> throw new HutoolException("No method name: " + name);
};
}, IBean.class);
// 测试代理类的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.WeakCache;
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.thread.ConcurrencyTester;
import cn.hutool.v7.core.thread.ThreadUtil;
@ -29,8 +28,6 @@ import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
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 PartitionIter<String> iter = new PartitionIter<>(lineIter, 3);
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;
public static TestEnum parse(final String str) {
switch (str) {
case "AAA":
return A;
case "BBB":
return B;
case "CCC":
return C;
}
return null;
return switch (str) {
case "AAA" -> A;
case "BBB" -> B;
case "CCC" -> C;
default -> null;
};
}
public static TestEnum parseByNumber(final int i) {
switch (i) {
case 11:
return A;
case 22:
return B;
case 33:
return C;
}
return null;
return switch (i) {
case 11 -> A;
case 22 -> B;
case 33 -> C;
default -> null;
};
}
}
}

View File

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

View File

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

View File

@ -16,14 +16,12 @@
package cn.hutool.v7.core.lang;
import lombok.Data;
import cn.hutool.v7.core.exception.HutoolException;
import cn.hutool.v7.core.thread.ThreadUtil;
import lombok.Data;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
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.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.Test;
import java.util.Map;
/**
* @author newshiJ
*/

View File

@ -47,7 +47,7 @@ class UrlDecoderTest {
final String s1 = UrlEncoder.encodeAll(s, StandardCharsets.UTF_16);
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);
final String decode = UrlDecoder.decode(s1, StandardCharsets.UTF_16);
@ -59,7 +59,7 @@ class UrlDecoderTest {
Assertions.assertEquals("测试你好", decode2);
Assertions.assertEquals(
java.net.URLDecoder.decode(mixDecoded, "UTF-16"),
java.net.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.lang.Console;
import cn.hutool.v7.core.thread.ThreadUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.RepeatedTest;
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 static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class JdkUtilTest {

View File

@ -17,7 +17,6 @@
package cn.hutool.v7.cron;
import cn.hutool.v7.cron.task.CronTask;
import cn.hutool.v7.cron.task.Task;
/**
* 作业执行器<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.DateTime;
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.Test;

View File

@ -781,16 +781,18 @@ public class SM2 extends AbstractAsymmetricCrypto<SM2> {
* @return {@link CipherParameters}
*/
private CipherParameters getCipherParameters(final KeyType keyType) {
switch (keyType) {
case PublicKey:
return switch (keyType) {
case PublicKey -> {
Assert.notNull(this.publicKeyParams, "PublicKey must be not null !");
return this.publicKeyParams;
case PrivateKey:
Assert.notNull(this.privateKeyParams, "PrivateKey must be not null !");
return this.privateKeyParams;
yield this.publicKeyParams;
}
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")) {
final boolean[] keyUsageInfo = cert.getKeyUsage();
// keyUsageInfo[0] is for digitalSignature.
if ((keyUsageInfo != null) && (keyUsageInfo[0] == false)) {
if ((keyUsageInfo != null) && (!keyUsageInfo[0])) {
throw new CryptoException("Wrong key usage");
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -100,9 +100,7 @@ public class SM2Test {
public void sm2Base64Test() {
final String textBase = "我是一段特别长的测试";
final StringBuilder text = new StringBuilder();
for (int i = 0; i < 100; i++) {
text.append(textBase);
}
text.append(textBase.repeat(100));
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 {
try {
if (getConnection().getMetaData().supportsTransactionIsolationLevel(level) == false) {
if (!getConnection().getMetaData().supportsTransactionIsolationLevel(level)) {
throw new DbException(StrUtil.format("Transaction isolation [{}] not support!", level));
}
getConnection().setTransactionIsolation(level);

View File

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

View File

@ -357,9 +357,7 @@ public class SqlFormatter {
private void newline() {
this.result.append("\n");
for (int i = 0; i < this.indent; i++) {
this.result.append(indentString);
}
this.result.append(indentString.repeat(Math.max(0, this.indent)));
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.DateUtil;
import cn.hutool.v7.core.lang.Console;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;

View File

@ -16,24 +16,21 @@
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.extra.compress.CompressException;
import cn.hutool.v7.extra.compress.CompressUtil;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.archivers.ArchiveOutputStream;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
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.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.IOException;
import java.io.OutputStream;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,7 +16,6 @@
package cn.hutool.v7.http.webservice;
import jakarta.xml.soap.*;
import cn.hutool.v7.core.collection.CollUtil;
import cn.hutool.v7.core.map.MapUtil;
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.Response;
import cn.hutool.v7.http.meta.Method;
import jakarta.xml.soap.*;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
@ -64,7 +64,7 @@ public class SoapClient implements HeaderOperation<SoapClient> {
* XML消息体的Content-Type
* soap1.1 : text/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_SOAP12_SOAP_XML = "application/soap+xml;charset=";
@ -568,14 +568,10 @@ public class SoapClient implements HeaderOperation<SoapClient> {
* @return 请求的Content-Type
*/
private String getXmlContentType() {
switch (this.protocol) {
case SOAP_1_1:
return CONTENT_TYPE_SOAP11_TEXT_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);
}
return switch (this.protocol) {
case SOAP_1_1 -> CONTENT_TYPE_SOAP11_TEXT_XML.concat(this.charset.toString());
case SOAP_1_2 -> CONTENT_TYPE_SOAP12_SOAP_XML.concat(this.charset.toString());
};
}
/**

View File

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

View File

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

View File

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

View File

@ -23,7 +23,7 @@ import java.security.KeyPair;
/**
* 椭圆曲线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)
*
* @author Looly
@ -71,19 +71,12 @@ public class EllipticCurveJWTSigner extends AsymmetricJWTSigner {
* @throws JWTException JWT异常
*/
private static int getSignatureByteArrayLength(final String alg) throws JWTException {
switch (alg) {
case "ES256":
case "SHA256withECDSA":
return 64;
case "ES384":
case "SHA384withECDSA":
return 96;
case "ES512":
case "SHA512withECDSA":
return 132;
default:
throw new JWTException("Unsupported Algorithm: {}", alg);
}
return switch (alg) {
case "ES256", "SHA256withECDSA" -> 64;
case "ES384", "SHA384withECDSA" -> 96;
case "ES512", "SHA512withECDSA" -> 132;
default -> throw new JWTException("Unsupported Algorithm: {}", alg);
};
}
/**

View File

@ -16,7 +16,6 @@
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.json.jwt.JWTException;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -35,15 +35,16 @@ public class JacksonTest {
String jsonString = engine.toJsonString(testBean);
// 使用统一换行符
jsonString = StrUtil.removeAll(jsonString, '\r');
Assertions.assertEquals("{\n" +
" \"name\" : \"张三\",\n" +
" \"age\" : 18,\n" +
" \"gender\" : true\n" +
"}", jsonString);
Assertions.assertEquals("""
{
"name" : "张三",
"age" : 18,
"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兼容
*/
@Test

View File

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

View File

@ -30,12 +30,13 @@ import java.util.List;
public class Issue3139Test {
@Test
public void toBeanTest() {
final String xml = "<r>\n" +
" <c>\n" +
" <s>1</s>\n" +
" <p>str</p>\n" +
" </c>\n" +
"</r>";
final String xml = """
<r>
<c>
<s>1</s>
<p>str</p>
</c>
</r>""";
final JSONObject jsonObject = JSONUtil.parseObj(xml);
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 {
@Test
public void toBeanTest() {
final JSONObject entries = JSONUtil.parseObj("{\n" +
" \n" +
" \"age\": 36,\n" +
" \"gender\": \"\",\n" +
" \"id\": \"123123123\"\n" +
"}", JSONConfig.of().setIgnoreError(true));
final JSONObject entries = JSONUtil.parseObj("""
{
\s
"age": 36,
"gender": "",
"id": "123123123"
}""", JSONConfig.of().setIgnoreError(true));
final LarkCoreHrPersonal larkCoreHrPersonal = entries.toBean(LarkCoreHrPersonal.class);
Assertions.assertNotNull(larkCoreHrPersonal);
}

View File

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

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