1
0
mirror of https://gitee.com/dromara/hutool.git synced 2025-04-05 17:37:59 +08:00

fix json double

This commit is contained in:
Looly 2020-10-11 13:45:33 +08:00
parent 6ea9912fd4
commit c4fdf545e7
5 changed files with 95 additions and 78 deletions
CHANGELOG.md
hutool-json/src
main/java/cn/hutool/json
test/java/cn/hutool/json

View File

@ -3,7 +3,7 @@
-------------------------------------------------------------------------------------------------------------
# 5.4.5 (2020-10-09)
# 5.4.5 (2020-10-11)
### 新特性
* 【core 】 ConsoleTable代码优化pr#190@Gitee
@ -18,6 +18,7 @@
### Bug修复
* 【core 】 解决农历判断节日未判断大小月导致的问题issue#I1XHSF@Gitee
* 【core 】 解决ListUtil计算总量可能的int溢出问题pr#1150@Github
* 【json 】 解决JSON中转换为double小数精度丢失问题pr#192@Gitee
-------------------------------------------------------------------------------------------------------------

View File

@ -140,12 +140,14 @@ final class InternalJSONUtil {
* @return A simple JSON value.
*/
protected static Object stringToValue(String string) {
// null处理
if (null == string || "null".equalsIgnoreCase(string)) {
return JSONNull.NULL;
}
if (StrUtil.EMPTY.equals(string)) {
return string;
// boolean处理
if (0 == string.length()) {
return StrUtil.EMPTY;
}
if ("true".equalsIgnoreCase(string)) {
return Boolean.TRUE;
@ -154,17 +156,22 @@ final class InternalJSONUtil {
return Boolean.FALSE;
}
/* If it might be a number, try converting it. If a number cannot be produced, then the value will just be a string. */
// Number处理
char b = string.charAt(0);
if ((b >= '0' && b <= '9') || b == '-') {
try {
if (string.indexOf('.') > -1 || string.indexOf('e') > -1 || string.indexOf('E') > -1) {
if (StrUtil.containsAnyIgnoreCase(string, ".", "e")) {
// pr#192@GiteeDouble会出现小数精度丢失问题此处使用BigDecimal
//double d = Double.parseDouble(string);
//if (false == Double.isInfinite(d) && false == Double.isNaN(d)) {
// return d;
//}
return new BigDecimal(string);
} else {
Long myLong = new Long(string);
if (string.equals(myLong.toString())) {
if (myLong == myLong.intValue()) {
return myLong.intValue();
final long myLong = Long.parseLong(string);
if (string.equals(Long.toString(myLong))) {
if (myLong == (int) myLong) {
return (int) myLong;
} else {
return myLong;
}
@ -173,6 +180,8 @@ final class InternalJSONUtil {
} catch (Exception ignore) {
}
}
// 其它情况返回原String值下
return string;
}

View File

@ -349,7 +349,7 @@ public class JSONTokener {
this.back();
string = sb.toString().trim();
if ("".equals(string)) {
if (0 == string.length()) {
throw this.syntaxError("Missing value");
}
return InternalJSONUtil.stringToValue(string);

View File

@ -10,10 +10,8 @@ import cn.hutool.json.test.bean.UserC;
import org.junit.Assert;
import org.junit.Test;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JSONUtilTest {
@ -126,15 +124,6 @@ public class JSONUtilTest {
// Assert.assertEquals("{\"age\":18,\"gender\":\"\"}", user.getProp());
}
@Test
public void toBeanTest3() {
// 测试数字类型精度丢失的情况
String number = "1234.123456789123456";
String jsonString = "{\"create\":{\"details\":[{\"price\":" + number + "}]}}";
WebCreate create = JSONUtil.toBean(jsonString, WebCreate.class);
Assert.assertEquals(number,create.getCreate().getDetails().get(0).getPrice().toString());
}
@Test
public void putByPathTest() {
JSONObject json = new JSONObject();
@ -172,62 +161,5 @@ public class JSONUtilTest {
final JSONObject jsonObject = JSONUtil.parseObj(json);
Assert.assertEquals("12.00", jsonObject.getBigDecimal("test").setScale(2).toString());
}
class WebCreate {
private Create create;
@Override
public String toString() {
return "WebCreate{" +
"create=" + create +
'}';
}
public void setCreate(Create create) {
this.create = create;
}
public Create getCreate() {
return create;
}
}
class Create {
@Override
public String toString() {
return "Create{" +
"details=" + details +
'}';
}
private List<Detail> details;
public void setDetails(List<Detail> details) {
this.details = details;
}
public List<Detail> getDetails() {
return details;
}
}
class Detail {
private BigDecimal price;
public void setPrice(BigDecimal price) {
this.price = price;
}
@Override
public String toString() {
return "Detail{" +
"price=" + price +
'}';
}
public BigDecimal getPrice() {
return price;
}
}
}

View File

@ -0,0 +1,75 @@
package cn.hutool.json;
import org.junit.Assert;
import org.junit.Test;
import java.math.BigDecimal;
import java.util.List;
public class Pr192Test {
@Test
public void toBeanTest3() {
// 测试数字类型精度丢失的情况
String number = "1234.123456789123456";
String jsonString = "{\"create\":{\"details\":[{\"price\":" + number + "}]}}";
WebCreate create = JSONUtil.toBean(jsonString, WebCreate.class);
Assert.assertEquals(number,create.getCreate().getDetails().get(0).getPrice().toString());
}
static class WebCreate {
private Create create;
@Override
public String toString() {
return "WebCreate{" +
"create=" + create +
'}';
}
public void setCreate(Create create) {
this.create = create;
}
public Create getCreate() {
return create;
}
}
static class Create {
@Override
public String toString() {
return "Create{" +
"details=" + details +
'}';
}
private List<Detail> details;
public void setDetails(List<Detail> details) {
this.details = details;
}
public List<Detail> getDetails() {
return details;
}
}
static class Detail {
private BigDecimal price;
public void setPrice(BigDecimal price) {
this.price = price;
}
@Override
public String toString() {
return "Detail{" +
"price=" + price +
'}';
}
public BigDecimal getPrice() {
return price;
}
}
}