Compare commits

...

15 Commits

Author SHA1 Message Date
binyong
c993476686
Pre Merge pull request !1371 from binyong/v5-dev 2025-08-11 03:19:56 +00:00
Looly
66e2829415 getClientIP优先获取传入的请求头信息(pr#1373@Gitee) 2025-08-11 11:19:29 +08:00
Looly
8bc7c997d1
!1373 getClientIP 优先获取传入的请求头信息
Merge pull request !1373 from handy/handy
2025-08-11 03:15:49 +00:00
Looly
6e382b869e add test 2025-08-11 11:14:53 +08:00
Looly
3d49f9bf39
!1374 修复错别字
Merge pull request !1374 from handy/handy1
2025-08-11 03:14:45 +00:00
Looly
68ef91b6fb add test 2025-08-11 11:00:55 +08:00
Golden Looly
2b8284c7fb
Merge pull request #4007 from qibinhang/v5-dev
新增测试用例以测试更多重要场景
2025-08-11 10:59:23 +08:00
Looly
445703380b fix comment 2025-08-11 10:48:06 +08:00
Golden Looly
e92ab1308c
Merge pull request #4004 from fanchenggang/v5-dev
fix 汉子 to 汉字 Update Pinyin4jEngine.java
2025-08-11 10:47:44 +08:00
handy
c8f11cd9f9
修复错别字 2025-08-08 20:00:08 +08:00
qibinhang
f3d95e908b Add tests for covering additional, important scenarios of FileUtil. 2025-08-08 13:51:47 +08:00
qibinhang
8bfefbb9ba Add tests for covering additional, important scenarios of CollUtil. 2025-08-08 13:51:40 +08:00
qibinhang
3e330f1c64 Add tests for covering additional, important scenarios of CollStreamUtil. 2025-08-08 13:51:04 +08:00
handy
a27ebb4403
getClientIP 优先获取传入的请求头信息 2025-08-07 13:35:00 +08:00
Farahani
d5bc6216a4
Update Pinyin4jEngine.java
fix(方法注释):注释错误修改
2025-08-06 00:21:10 +08:00
12 changed files with 198 additions and 44 deletions

View File

@ -2,7 +2,7 @@
# 🚀Changelog
-------------------------------------------------------------------------------------------------------------
# 5.8.40(2025-07-30)
# 5.8.40(2025-08-11)
### 🐣新特性
* 【captcha】 `MathGenerator`四则运算方式支持不生成负数结果pr#1363@Gitee
@ -10,6 +10,7 @@
* 【core 】 `CalendarUtil`增加`isSameYear`和`calendar`方法issue#3995@Github
* 【core 】 `DateUtil`增加`yyyy-MM-dd'T'HH:mmXXX`格式支持pr#1367@Gitee
* 【core 】 `MapUtil`增加flatten方法pr#1368@Gitee
* 【extra 】 `getClientIP`优先获取传入的请求头信息pr#1373@Gitee
### 🐞Bug修复
* 【extra 】 `Sftp``reconnectIfTimeout`方法改为捕获所有异常issue#3989@Github

View File

@ -1823,7 +1823,7 @@ public class NumberUtil {
* @param bigNum1 数字1
* @param bigNum2 数字2
* @return 是否大于等于
* @since 3, 0.9
* @since 3.0.9
*/
public static boolean isGreaterOrEqual(BigDecimal bigNum1, BigDecimal bigNum2) {
Assert.notNull(bigNum1);
@ -1837,7 +1837,7 @@ public class NumberUtil {
* @param bigNum1 数字1
* @param bigNum2 数字2
* @return 是否小于
* @since 3, 0.9
* @since 3.0.9
*/
public static boolean isLess(BigDecimal bigNum1, BigDecimal bigNum2) {
Assert.notNull(bigNum1);
@ -1851,7 +1851,7 @@ public class NumberUtil {
* @param bigNum1 数字1
* @param bigNum2 数字2
* @return 是否小于等于
* @since 3, 0.9
* @since 3.0.9
*/
public static boolean isLessOrEqual(BigDecimal bigNum1, BigDecimal bigNum2) {
Assert.notNull(bigNum1);

View File

@ -4,13 +4,14 @@ import cn.hutool.core.map.MapUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.ToString;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.*;
/**
* CollectionStream测试方法
*/
@ -19,17 +20,17 @@ public class CollStreamUtilTest {
@Test
public void testToIdentityMap() {
Map<Long, Student> map = CollStreamUtil.toIdentityMap(null, Student::getStudentId);
assertEquals(map, Collections.EMPTY_MAP);
assertEquals(Collections.EMPTY_MAP, map);
List<Student> list = new ArrayList<>();
map = CollStreamUtil.toIdentityMap(list, Student::getStudentId);
assertEquals(map, Collections.EMPTY_MAP);
assertEquals(Collections.EMPTY_MAP, map);
list.add(new Student(1, 1, 1, "张三"));
list.add(new Student(1, 1, 2, "李四"));
list.add(new Student(1, 1, 3, "王五"));
map = CollStreamUtil.toIdentityMap(list, Student::getStudentId);
assertEquals(map.get(1L).getName(), "张三");
assertEquals(map.get(2L).getName(), "李四");
assertEquals(map.get(3L).getName(), "王五");
assertEquals("张三", map.get(1L).getName());
assertEquals("李四", map.get(2L).getName());
assertEquals("王五", map.get(3L).getName());
assertNull(map.get(4L));
// 测试value为空时
@ -41,17 +42,17 @@ public class CollStreamUtilTest {
@Test
public void testToMap() {
Map<Long, String> map = CollStreamUtil.toMap(null, Student::getStudentId, Student::getName);
assertEquals(map, Collections.EMPTY_MAP);
assertEquals(Collections.EMPTY_MAP, map);
List<Student> list = new ArrayList<>();
map = CollStreamUtil.toMap(list, Student::getStudentId, Student::getName);
assertEquals(map, Collections.EMPTY_MAP);
assertEquals(Collections.EMPTY_MAP, map);
list.add(new Student(1, 1, 1, "张三"));
list.add(new Student(1, 1, 2, "李四"));
list.add(new Student(1, 1, 3, "王五"));
map = CollStreamUtil.toMap(list, Student::getStudentId, Student::getName);
assertEquals(map.get(1L), "张三");
assertEquals(map.get(2L), "李四");
assertEquals(map.get(3L), "王五");
assertEquals("张三", map.get(1L));
assertEquals("李四", map.get(2L));
assertEquals("王五", map.get(3L));
assertNull(map.get(4L));
// 测试value为空时
@ -60,13 +61,47 @@ public class CollStreamUtilTest {
assertNull(map.get(4L));
}
@Test
public void testToMap_KeyCollision_SilentlyOverwrite() {
List<Student> list = new ArrayList<>();
list.add(new Student(1, 101, 1, "张三"));
list.add(new Student(1, 102, 1, "李四"));
Map<Long, String> map = CollStreamUtil.toMap(list, Student::getStudentId, Student::getName, false);
assertEquals(1, map.size());
assertEquals("李四", map.get(1L)); // 确保后面的值覆盖前面的
}
@Test
public void testToMap_NullKeyOrValue() {
List<Student> list = new ArrayList<>();
list.add(new Student(1, 1, 1L, "张三"));
list.add(null);
list.add(new Student(1, 2, 2L, null));
assertThrows(NullPointerException.class, () -> {
CollStreamUtil.toMap(list, Student::getStudentId, Student::getName);
});
}
@Test
public void testToMap_LargeInputPerformance() {
List<Student> list = new ArrayList<>();
for (long i = 0; i < 10000; i++) {
list.add(new Student(1, 1, i, "学生" + i));
}
Map<Long, String> map = CollStreamUtil.toMap(list, Student::getStudentId, Student::getName);
assertEquals(10000, map.size());
}
@Test
public void testGroupByKey() {
Map<Long, List<Student>> map = CollStreamUtil.groupByKey(null, Student::getClassId);
assertEquals(map, Collections.EMPTY_MAP);
assertEquals(Collections.EMPTY_MAP, map);
List<Student> list = new ArrayList<>();
map = CollStreamUtil.groupByKey(list, Student::getClassId);
assertEquals(map, Collections.EMPTY_MAP);
assertEquals(Collections.EMPTY_MAP, map);
list.add(new Student(1, 1, 1, "张三"));
list.add(new Student(1, 2, 2, "李四"));
list.add(new Student(2, 1, 1, "擎天柱"));
@ -92,10 +127,10 @@ public class CollStreamUtilTest {
@Test
public void testGroupBy2Key() {
Map<Long, Map<Long, List<Student>>> map = CollStreamUtil.groupBy2Key(null, Student::getTermId, Student::getClassId);
assertEquals(map, Collections.EMPTY_MAP);
assertEquals(Collections.EMPTY_MAP, map);
List<Student> list = new ArrayList<>();
map = CollStreamUtil.groupBy2Key(list, Student::getTermId, Student::getClassId);
assertEquals(map, Collections.EMPTY_MAP);
assertEquals(Collections.EMPTY_MAP, map);
list.add(new Student(1, 1, 1, "张三"));
list.add(new Student(1, 2, 2, "李四"));
list.add(new Student(1, 2, 3, "王五"));
@ -131,11 +166,11 @@ public class CollStreamUtilTest {
@Test
public void testGroup2Map() {
Map<Long, Map<Long, Student>> map = CollStreamUtil.group2Map(null, Student::getTermId, Student::getClassId);
assertEquals(map, Collections.EMPTY_MAP);
assertEquals(Collections.EMPTY_MAP, map);
List<Student> list = new ArrayList<>();
map = CollStreamUtil.group2Map(list, Student::getTermId, Student::getClassId);
assertEquals(map, Collections.EMPTY_MAP);
assertEquals(Collections.EMPTY_MAP, map);
list.add(new Student(1, 1, 1, "张三"));
list.add(new Student(1, 2, 1, "李四"));
list.add(new Student(2, 2, 1, "王五"));
@ -152,7 +187,10 @@ public class CollStreamUtilTest {
// 对null友好
Map<Long, Map<Long, Student>> termIdClassIdStudentMap = CollStreamUtil.group2Map(Arrays.asList(null, new Student(2, 2, 1, "王五")), Student::getTermId, Student::getClassId);
Map<Long, Map<Long, Student>> termIdClassIdStudentCompareMap = new HashMap<Long, Map<Long, Student>>() {{
Map<Long, Map<Long, Student>> termIdClassIdStudentCompareMap = new HashMap<Long, Map<Long, Student>>() {
private static final long serialVersionUID = -26683057599474572L;
{
put(null, MapUtil.of(null, null));
put(2L, MapUtil.of(2L, new Student(2, 2, 1, "王五")));
}};
@ -162,11 +200,11 @@ public class CollStreamUtilTest {
@Test
public void testGroupKeyValue() {
Map<Long, List<Long>> map = CollStreamUtil.groupKeyValue(null, Student::getTermId, Student::getClassId);
assertEquals(map, Collections.EMPTY_MAP);
assertEquals(Collections.EMPTY_MAP, map);
List<Student> list = new ArrayList<>();
map = CollStreamUtil.groupKeyValue(list, Student::getTermId, Student::getClassId);
assertEquals(map, Collections.EMPTY_MAP);
assertEquals(Collections.EMPTY_MAP, map);
list.add(new Student(1, 1, 1, "张三"));
list.add(new Student(1, 2, 1, "李四"));
list.add(new Student(2, 2, 1, "王五"));
@ -184,12 +222,12 @@ public class CollStreamUtilTest {
// 参数null测试
Map<Long, List<Student>> map = CollStreamUtil.groupBy(null, Student::getTermId, Collectors.toList());
assertEquals(map, Collections.EMPTY_MAP);
assertEquals(Collections.EMPTY_MAP, map);
// 参数空数组测试
List<Student> list = new ArrayList<>();
map = CollStreamUtil.groupBy(list, Student::getTermId, Collectors.toList());
assertEquals(map, Collections.EMPTY_MAP);
assertEquals(Collections.EMPTY_MAP, map);
// 放入元素
list.add(new Student(1, 1, 1, "张三"));
@ -230,10 +268,10 @@ public class CollStreamUtilTest {
@Test
public void testTranslate2List() {
List<String> list = CollStreamUtil.toList(null, Student::getName);
assertEquals(list, Collections.EMPTY_LIST);
assertEquals(Collections.EMPTY_LIST, list);
List<Student> students = new ArrayList<>();
list = CollStreamUtil.toList(students, Student::getName);
assertEquals(list, Collections.EMPTY_LIST);
assertEquals(Collections.EMPTY_LIST, list);
students.add(new Student(1, 1, 1, "张三"));
students.add(new Student(1, 2, 2, "李四"));
students.add(new Student(2, 1, 1, "李四"));
@ -252,10 +290,10 @@ public class CollStreamUtilTest {
@Test
public void testTranslate2Set() {
Set<String> set = CollStreamUtil.toSet(null, Student::getName);
assertEquals(set, Collections.EMPTY_SET);
assertEquals(Collections.EMPTY_SET, set);
List<Student> students = new ArrayList<>();
set = CollStreamUtil.toSet(students, Student::getName);
assertEquals(set, Collections.EMPTY_SET);
assertEquals(Collections.EMPTY_SET, set);
students.add(new Student(1, 1, 1, "张三"));
students.add(new Student(1, 2, 2, "李四"));
students.add(new Student(2, 1, 1, "李四"));
@ -274,7 +312,7 @@ public class CollStreamUtilTest {
Map<Long, Student> map1 = null;
Map<Long, Student> map2 = Collections.emptyMap();
Map<Long, String> map = CollStreamUtil.merge(map1, map2, (s1, s2) -> s1.getName() + s2.getName());
assertEquals(map, Collections.EMPTY_MAP);
assertEquals(Collections.EMPTY_MAP, map);
map1 = new HashMap<>();
map1.put(1L, new Student(1, 1, 1, "张三"));
map = CollStreamUtil.merge(map1, map2, this::merge);

View File

@ -62,6 +62,25 @@ public class CollUtilTest {
assertEquals(srcList, answerList);
}
@Test
public void testPadLeft_NegativeMinLen_ShouldNotModifyList() {
List<String> list = CollUtil.newArrayList("a", "b", "c");
List<String> original = CollUtil.newArrayList("a", "b", "c");
CollUtil.padLeft(list, -5, "x");
assertEquals(original, list, "List should remain unchanged when minLen is negative");
}
@Test
public void testPadLeft_EmptyList_MinLenZero() {
List<String> list = CollUtil.newArrayList();
CollUtil.padLeft(list, 0, "x");
assertTrue(list.isEmpty(), "List should remain empty when minLen is 0");
}
@Test
public void testPadRight() {
final List<String> srcList = CollUtil.newArrayList("a");
@ -212,6 +231,19 @@ public class CollUtilTest {
assertEquals("[1]", r2.toString());
}
@Test
public void testSubtractWithDuplicates() {
Collection<String> coll1 = new ArrayList<>(Arrays.asList("a", "b", "b", "c"));
Collection<String> coll2 = Collections.singletonList("b");
Collection<String> result = CollUtil.subtract(coll1, coll2);
List<String> expected = Arrays.asList("a", "c");
List<String> resultList = new ArrayList<>(result);
Collections.sort(resultList);
Collections.sort(expected);
assertEquals(expected, resultList);
}
@Test
public void toMapListAndToListMapTest() {
final HashMap<String, String> map1 = new HashMap<>();
@ -825,6 +857,34 @@ public class CollUtilTest {
assertEquals(2, i);
}
@Test
public void lastIndexOf_NoMatchExists() {
List<String> list = CollUtil.newArrayList("a", "b", "c");
int idx = CollUtil.lastIndexOf(list, item -> item.equals("z"));
assertEquals(-1, idx);
}
@Test
public void lastIndexOf_MatcherIsNull_MatchAll() {
List<String> list = CollUtil.newArrayList("x", "y", "z");
int idx = CollUtil.lastIndexOf(list, null);
assertEquals(2, idx);
}
@Test
public void lastIndexOf_EmptyCollection() {
List<String> list = CollUtil.newArrayList();
int idx = CollUtil.lastIndexOf(list, Objects::nonNull);
assertEquals(-1, idx);
}
@Test
public void lastIndexOf_SingletonCollection_Match() {
List<String> list = CollUtil.newArrayList("foo");
int idx = CollUtil.lastIndexOf(list, item -> item.equals("foo"));
assertEquals(0, idx);
}
@Test
public void pageTest() {
final List<Dict> objects = CollUtil.newArrayList();
@ -907,7 +967,7 @@ public class CollUtilTest {
// 测试集合1和集合2不包含相同元素的情况
final List<String> list1 = Arrays.asList("a", "b", "c");
final List<String> list2 = Arrays.asList("d", "e", "f");
// 期望结果返回集合1的完整拷贝
final List<String> result = CollUtil.subtractToList(list1, list2);
assertEquals(3, result.size());
@ -916,11 +976,11 @@ public class CollUtilTest {
assertEquals("c", result.get(2));
assertEquals(list1, result);
assertNotSame(list1, result); // 确保返回的是拷贝而不是原始引用
// 测试集合1中有重复元素的情况
final List<String> list3 = Arrays.asList("a", "a", "b", "b", "c");
final List<String> list4 = Arrays.asList("d", "e", "f");
// 期望结果返回集合1的完整拷贝包括重复元素
final List<String> result2 = CollUtil.subtractToList(list3, list4);
assertEquals(5, result2.size());
@ -931,11 +991,11 @@ public class CollUtilTest {
assertEquals("c", result2.get(4));
assertEquals(list3, result2);
assertNotSame(list3, result2);
// 测试不同类型的元素但确保两个集合的泛型类型一致
final List<Integer> list5 = Arrays.asList(1, 2, 3);
final List<Integer> list6 = Arrays.asList(4, 5, 6);
// 期望结果返回集合1的完整拷贝
final List<Integer> result3 = CollUtil.subtractToList(list5, list6);
assertEquals(3, result3.size());
@ -1227,9 +1287,9 @@ public class CollUtilTest {
genderMap.put(5, "小孩");
genderMap.put(6, "");
assertEquals(people.get(1).getGender(), "woman");
assertEquals("woman", people.get(1).getGender());
CollUtil.setValueByMap(people, genderMap, Person::getId, Person::setGender);
assertEquals(people.get(1).getGender(), "妇女");
assertEquals("妇女", people.get(1).getGender());
final Map<Integer, Person> personMap = new HashMap<>();
personMap.put(1, new Person("AA", 21, "", 1));
@ -1245,7 +1305,7 @@ public class CollUtilTest {
x.setAge(y.getAge());
});
assertEquals(people.get(1).getGender(), "小孩");
assertEquals("小孩", people.get(1).getGender());
}
@Test

View File

@ -528,6 +528,44 @@ public class FileUtilTest {
assertTrue(FileUtil.isSub(file, file2));
}
@Test
public void isSub_SubIsAncestorOfParentTest() {
File parent = new File("d:/home/user/docs/notes");
File sub = new File("d:/home/user/docs");
assertFalse(FileUtil.isSub(parent, sub));
}
@Test
public void isSub_SamePathTest() {
File parent = new File("d:/home/user/docs");
File sub = new File("d:/home/user/docs");
assertTrue(FileUtil.isSub(parent, sub));
}
@Test
public void isSub_NonexistentPathsTest() {
File parent = new File("d:/unlikely/to/exist/parent");
File sub = new File("d:/unlikely/to/exist/parent/child/file.txt");
assertTrue(FileUtil.isSub(parent, sub));
File nonchild = new File("d:/also/unlikely/path.txt");
assertFalse(FileUtil.isSub(parent, nonchild));
}
@Test
public void isSub_NullParentTest() {
assertThrows(IllegalArgumentException.class, () -> {
FileUtil.isSub(null, new java.io.File("d:/any/path"));
});
}
@Test
public void isSub_NullSubTest() {
assertThrows(IllegalArgumentException.class, () -> {
FileUtil.isSub(new java.io.File("d:/any/path"), null);
});
}
@Test
@Disabled
public void appendLinesTest(){

View File

@ -0,0 +1,15 @@
package cn.hutool.core.text.csv;
import cn.hutool.core.io.resource.ResourceUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class IssueICRMKATest {
@Test
public void issueICRMAKTest() {
CsvReader reader = CsvUtil.getReader();
CsvData data = reader.read(ResourceUtil.getUtf8Reader("issueICRMKA.csv"));
final CsvRow row = data.getRow(1);
Assertions.assertEquals("6.3\" Google Pixel 9 Pro 128 GB Beige", row.get(0));
}
}

View File

@ -0,0 +1,2 @@
config,price,unit,package_name,package,equipment,pic_path,crawler_date,set_Discount,installment_details,installment_price,installment_time
6.3" Google Pixel 9 Pro 128 GB Beige,94999,₽,fwefwe,fewfew,"Cores - 8x(3.1 GHz), 16 GB, 1 SIM, OLED, 2856x1280, 50+48+48 MP camera, NFC, 5G, GPS, 4700 mAh more details",["https://xx.png"],2025/8/1 4:05,,gerwgrweg,fwefw,fwefwe
Can't render this file because it contains an unexpected character in line 2 and column 4.

View File

@ -27,7 +27,7 @@ import com.github.stuxuhai.jpinyin.PinyinHelper;
*/
public class JPinyinEngine implements PinyinEngine {
//设置汉拼音输出的格式
//设置汉拼音输出的格式
PinyinFormat format;
public JPinyinEngine(){

View File

@ -33,7 +33,7 @@ import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombi
*/
public class Pinyin4jEngine implements PinyinEngine {
//设置汉拼音输出的格式
//设置汉拼音输出的格式
HanyuPinyinOutputFormat format;
/**

View File

@ -215,7 +215,7 @@ public class JakartaServletUtil {
public static String getClientIP(HttpServletRequest request, String... otherHeaderNames) {
String[] headers = {"X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"};
if (ArrayUtil.isNotEmpty(otherHeaderNames)) {
headers = ArrayUtil.addAll(headers, otherHeaderNames);
headers = ArrayUtil.addAll(otherHeaderNames, headers);
}
return getClientIPByHeader(request, headers);

View File

@ -215,7 +215,7 @@ public class ServletUtil {
public static String getClientIP(HttpServletRequest request, String... otherHeaderNames) {
String[] headers = {"X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"};
if (ArrayUtil.isNotEmpty(otherHeaderNames)) {
headers = ArrayUtil.addAll(headers, otherHeaderNames);
headers = ArrayUtil.addAll(otherHeaderNames, headers);
}
return getClientIPByHeader(request, headers);

View File

@ -391,7 +391,7 @@ public class HttpServerRequest extends HttpServerBase {
public String getClientIP(String... otherHeaderNames) {
String[] headers = {"X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"};
if (ArrayUtil.isNotEmpty(otherHeaderNames)) {
headers = ArrayUtil.addAll(headers, otherHeaderNames);
headers = ArrayUtil.addAll(otherHeaderNames, headers);
}
return getClientIPByHeader(headers);