[dromara/hutool]修复 cn.hutool.core.util.StrUtil#truncateByByteLength 截断字符串方法 maxBytes与速算因子和str入参byte长度未经过appendDots布尔值校验问题

2023-12-12 425 views
2
说明
  1. 请确认你提交的PR是到'v5-dev'分支,否则我会手动修改代码并关闭PR。
  2. 请确认没有更改代码风格(如tab缩进)
  3. 新特性添加请确认注释完备,如有必要,请在src/test/java下添加Junit测试用例
修改描述(包括说明bug修复或者添加新特性)
  1. [bug修复]
    • 修复 cn.hutool.core.util.StrUtil#truncateByByteLength 截断字符串方法 maxBytes与速算因子和str入参byte长度未经过appendDots布尔值校验问题
    • 如图: image

      删除字符串到等于或小于原字符串字节数组长度

      image
    • 修复后正常截取 image
提交前自测

请在提交前自测确保代码没有问题,提交新代码应包含:测试用例、通过(mvn javadoc:javadoc)检验详细注释。

  1. 本地如有多个JDK版本,可以设置临时JDk版本,如:export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_331.jdk/Contents/Home,具体替换为本地jdk目录
  2. 确保本地测试使用JDK8最新版本,echo $JAVA_HOMEmvn -vjava -version均正确。
  3. 执行打包生成文档,使用mvn clean package -Dmaven.test.skip=true -U,并确认通过,会自动执行打包、生成文档
  4. 如需要单独执行文档生成,执行:mvn javadoc:javadoc,并确认通过
  5. 如需要单独执行测试用例,执行:mvn clean test,并确认通过

回答

8

原test正常通过啊,有啥问题?没看懂。

4

原test 有问题 当字节数刚好等于需要截取字符数时 无法通过断言 请看我第二张截图和第一张的比较

4

@topsuder 当然啊,当字节数等于截取长度时,就不需要截取了,返回原字符串啊,这个逻辑没问题吧。

4

原逻辑在下面计算是是包含了...无法达到我截取后三个字节的目的

2

比如5个汉字 我需要截取4个汉字后面以...省略

0

理论在utf8编码下 入参maxBytes为12可以达到需要的实现效果 而并不能

9

@topsuder 当然啊,当字节数等于截取长度时,就不需要截取了,返回原字符串啊,这个逻辑没问题吧。 这个逻辑如果是正确的那么下面不应该加上省略号的字节数。保持原逻辑不动在上面加上对是否拼接省略号的校验这个方法的用途才会清晰

3

@topsuder 没太看懂你说的。可否详细一些?

因为UTF8是1~4字节变长的,因此汉字实际的bytes长度可能随着字符不同在变化,此处为了简化方便,统一按照因子是4计算(默认一个汉字占4个字节),但是实际字节数应该比这个小很多。因此首先判断如果字符串长度(即字符个数*4小于最大长度,返回原字符串)

再就是转为指定编码的bytes,这就是实际长度,再根据实际长度判断是否超出最大长度未超出则返回原字符串。

不知道这个逻辑哪里有问题么?

我想可能的问题就是if (sba.length <= maxBytes)这句判断多此一举了。

7

此方法目的是为了截取字符串 截取汉字在utf8编码下为3个字节 我有五个汉字“一二三四五” 我需要实现“一二三四...” 也就是说我的maxBytes入参值为12 或者原逻辑加上了3个.省略号的情况为15 所以我的结果应该得到”一二三四...” 但是由于上面的if判断中 如果max bytes比字符串的字节数长时 导致结果不正确 会直接返回“一二三四五“

7

image入图 我修改了单元测试中的字符串把后面几个汉字给删除了 逻辑出现问题

2

@topsuder

一二三四五,合计15个字节,如果限制长度是13,则返回一二三...,没问题;如果限制长度超过15或等于15,返回原字符串,不需要截取也不需要加...,我想这个逻辑没问题的。

image

如果pr下无法讨论清楚,可以加我微信私聊:微信搜hutool