mirror of
https://gitee.com/dromara/hutool.git
synced 2025-05-09 15:17:59 +08:00
fix json double
This commit is contained in:
parent
6ea9912fd4
commit
c4fdf545e7
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
# 5.4.5 (2020-10-09)
|
# 5.4.5 (2020-10-11)
|
||||||
|
|
||||||
### 新特性
|
### 新特性
|
||||||
* 【core 】 ConsoleTable代码优化(pr#190@Gitee)
|
* 【core 】 ConsoleTable代码优化(pr#190@Gitee)
|
||||||
@ -18,6 +18,7 @@
|
|||||||
### Bug修复
|
### Bug修复
|
||||||
* 【core 】 解决农历判断节日未判断大小月导致的问题(issue#I1XHSF@Gitee)
|
* 【core 】 解决农历判断节日未判断大小月导致的问题(issue#I1XHSF@Gitee)
|
||||||
* 【core 】 解决ListUtil计算总量可能的int溢出问题(pr#1150@Github)
|
* 【core 】 解决ListUtil计算总量可能的int溢出问题(pr#1150@Github)
|
||||||
|
* 【json 】 解决JSON中转换为double小数精度丢失问题(pr#192@Gitee)
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -140,12 +140,14 @@ final class InternalJSONUtil {
|
|||||||
* @return A simple JSON value.
|
* @return A simple JSON value.
|
||||||
*/
|
*/
|
||||||
protected static Object stringToValue(String string) {
|
protected static Object stringToValue(String string) {
|
||||||
|
// null处理
|
||||||
if (null == string || "null".equalsIgnoreCase(string)) {
|
if (null == string || "null".equalsIgnoreCase(string)) {
|
||||||
return JSONNull.NULL;
|
return JSONNull.NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StrUtil.EMPTY.equals(string)) {
|
// boolean处理
|
||||||
return string;
|
if (0 == string.length()) {
|
||||||
|
return StrUtil.EMPTY;
|
||||||
}
|
}
|
||||||
if ("true".equalsIgnoreCase(string)) {
|
if ("true".equalsIgnoreCase(string)) {
|
||||||
return Boolean.TRUE;
|
return Boolean.TRUE;
|
||||||
@ -154,17 +156,22 @@ final class InternalJSONUtil {
|
|||||||
return Boolean.FALSE;
|
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);
|
char b = string.charAt(0);
|
||||||
if ((b >= '0' && b <= '9') || b == '-') {
|
if ((b >= '0' && b <= '9') || b == '-') {
|
||||||
try {
|
try {
|
||||||
if (string.indexOf('.') > -1 || string.indexOf('e') > -1 || string.indexOf('E') > -1) {
|
if (StrUtil.containsAnyIgnoreCase(string, ".", "e")) {
|
||||||
|
// pr#192@Gitee,Double会出现小数精度丢失问题,此处使用BigDecimal
|
||||||
|
//double d = Double.parseDouble(string);
|
||||||
|
//if (false == Double.isInfinite(d) && false == Double.isNaN(d)) {
|
||||||
|
// return d;
|
||||||
|
//}
|
||||||
return new BigDecimal(string);
|
return new BigDecimal(string);
|
||||||
} else {
|
} else {
|
||||||
Long myLong = new Long(string);
|
final long myLong = Long.parseLong(string);
|
||||||
if (string.equals(myLong.toString())) {
|
if (string.equals(Long.toString(myLong))) {
|
||||||
if (myLong == myLong.intValue()) {
|
if (myLong == (int) myLong) {
|
||||||
return myLong.intValue();
|
return (int) myLong;
|
||||||
} else {
|
} else {
|
||||||
return myLong;
|
return myLong;
|
||||||
}
|
}
|
||||||
@ -173,6 +180,8 @@ final class InternalJSONUtil {
|
|||||||
} catch (Exception ignore) {
|
} catch (Exception ignore) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 其它情况返回原String值下
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,7 +349,7 @@ public class JSONTokener {
|
|||||||
this.back();
|
this.back();
|
||||||
|
|
||||||
string = sb.toString().trim();
|
string = sb.toString().trim();
|
||||||
if ("".equals(string)) {
|
if (0 == string.length()) {
|
||||||
throw this.syntaxError("Missing value");
|
throw this.syntaxError("Missing value");
|
||||||
}
|
}
|
||||||
return InternalJSONUtil.stringToValue(string);
|
return InternalJSONUtil.stringToValue(string);
|
||||||
|
@ -10,10 +10,8 @@ import cn.hutool.json.test.bean.UserC;
|
|||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class JSONUtilTest {
|
public class JSONUtilTest {
|
||||||
@ -126,15 +124,6 @@ public class JSONUtilTest {
|
|||||||
// Assert.assertEquals("{\"age\":18,\"gender\":\"男\"}", user.getProp());
|
// 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
|
@Test
|
||||||
public void putByPathTest() {
|
public void putByPathTest() {
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
@ -172,62 +161,5 @@ public class JSONUtilTest {
|
|||||||
final JSONObject jsonObject = JSONUtil.parseObj(json);
|
final JSONObject jsonObject = JSONUtil.parseObj(json);
|
||||||
Assert.assertEquals("12.00", jsonObject.getBigDecimal("test").setScale(2).toString());
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
75
hutool-json/src/test/java/cn/hutool/json/Pr192Test.java
Normal file
75
hutool-json/src/test/java/cn/hutool/json/Pr192Test.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user