[BUG]JSONWriter.Feature.BrowserCompatible和Feature.WriteBigDecimalAsPlain是否有冲突,针对BigDecimal和BigInteger类型与预期不符
é®é¢æè¿°
ç®è¦æè¿°æ¨ç¢°å°çé®é¢ã é®é¢1ï¼è®¾ç½®JSONWriter.Feature.BrowserCompatibleï¼æ¥å£è¿åBigDecimalåBigIntegerç±»åå为å符串 é®é¢2ï¼ä¸è®¾ç½®JSONWriter.Feature.BrowserCompatibleï¼æ¥å£è¿åBigDecimalåBigIntegerç±»åå为æ°åç±»å é®é¢3ï¼ä¸è®¾ç½®JSONWriter.Feature.BrowserCompatibleä¸è®¾ç½®Feature.WriteBigDecimalAsPlainï¼æ¥å£è¿åBigDecimalåBigIntegerç±»åå为æ°åç±»åï¼æè§Feature.WriteBigDecimalAsPlainä¸çæ é®é¢4ï¼è®¾ç½®JSONWriter.Feature.BrowserCompatibleä¸è®¾ç½®Feature.WriteBigDecimalAsPlainï¼æ¥å£è¿åBigDecimalåBigIntegerç±»åå为å符串
é®é¢æ»ç»ï¼æJSONWriter.Feature.BrowserCompatibleç¹æ§ï¼BigDecimalåBigIntegerç±»åæ°æ®åååºåå为å符串ï¼è®¾ç½®Feature.WriteBigDecimalAsPlainä¸çæï¼æ æ³åºååBigDecimalåBigIntegerç±»åæ°æ®ä¸ºå符串
ç¯å¢ä¿¡æ¯
请填å以ä¸ä¿¡æ¯ï¼
- OSä¿¡æ¯ï¼ [e.g.ï¼CentOS 8.4.2105 4Core 3.10GHz 16 GB]
- JDKä¿¡æ¯ï¼ [e.g.ï¼Openjdk 1.8.0_312]
- çæ¬ä¿¡æ¯ï¼[e.g.ï¼Fastjson2 2.0.52]
éç°æ¥éª¤
å¦ä½æä½å¯ä»¥éç°è¯¥é®é¢ï¼
- 使ç¨
xxx.xxxæ¹æ³ - è¾å
¥
...æ°æ® - åºç°
...é误
Controller类示ä¾
@GetMapping(value = "/mockData")
public AjaxResult.Result<Object> mockData(@RequestParam("mock") Object mock){
JSONObject result = new JSONObject();
result.put("boolean", Boolean.TRUE);
result.put("byte", Byte.MAX_VALUE);
result.put("char", Character.MAX_VALUE);
result.put("int", Integer.MAX_VALUE);
result.put("long", Long.MAX_VALUE);
result.put("float", Float.MAX_VALUE);
result.put("double", Double.MAX_VALUE);
result.put("datetime", LocalDateTime.now());
result.put("date", LocalDate.now());
result.put("time", LocalTime.now());
result.put("timestamp", System.currentTimeMillis());
result.put("nanotime", System.nanoTime());
result.put("BigDecimal", new BigDecimal("12345678901234567890"));
// result.put("BigReal", new BigReal("999999999"));
result.put("BigInteger", BigInteger.valueOf(Long.MIN_VALUE));
result.put("string", "为äºéåºè¡ä¸ç¨æ·æ°åååçº§çæ°éæ±åä¿æäº§åææ¯çç«äºå");
result.put("round", new Random().nextLong());
result.put("mock", mock);
return success(ReturnInfo.OPERATION_SUCCESS_MSG, result);
}
MVCé 置示ä¾
@Configuration
public class FastjsonGlobalConfigurer implements WebMvcConfigurer {
/**
* Fastjsoné»è®¤åç¹æ§
*/
public static final JSONWriter.Feature[] FASTJSON_DEFAULT_WRITER_FEATURES = {JSONWriter.Feature.BrowserCompatible, JSONWriter.Feature.WriteMapNullValue, JSONWriter.Feature.WriteNullListAsEmpty, JSONWriter.Feature.WriteNullBooleanAsFalse, JSONWriter.Feature.WriteNulls,JSONWriter.Feature.WriteEnumsUsingName,JSONWriter.Feature.WritePairAsJavaBean,JSONWriter.Feature.IgnoreErrorGetter,JSONWriter.Feature.LargeObject};
/**
* Fastjsoné»è®¤è¯»ç¹æ§
*/
public static final JSONReader.Feature[] FASTJSON_DEFAULT_READER_FEATURES = {JSONReader.Feature.SupportSmartMatch, JSONReader.Feature.SupportArrayToBean, JSONReader.Feature.UseNativeObject, JSONReader.Feature.SupportClassForName,JSONReader.Feature.IgnoreSetNullValue,JSONReader.Feature.AllowUnQuotedFieldNames,JSONReader.Feature.IgnoreCheckClose,JSONReader.Feature.IgnoreAutoTypeNotMatch /* ,JSONReader.Feature.NonErrorOnNumberOverflow */ };
private FastJsonConfig defaultFastJsonConfig() {
Charset charset = StandardCharsets.UTF_8;
JSONWriter.Feature[] writerFeatures = FASTJSON_DEFAULT_WRITER_FEATURES;
JSONReader.Feature[] readerFeatures = FASTJSON_DEFAULT_READER_FEATURES;
// å建é
置类
FastJsonConfig config = new FastJsonConfig();
config.setWriterFeatures(writerFeatures);
config.setReaderFeatures(readerFeatures);
config.setCharset(charset);
config.setDateFormat(DateUtils.DEFAULT_FORMAT_DATE_TIME);
return config;
}
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
FastJsonJsonView view = new FastJsonJsonView();
view.setFastJsonConfig(defaultFastJsonConfig());
registry.enableContentNegotiation(view);
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
Charset charset = StandardCharsets.UTF_8;
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
converter.setFastJsonConfig(defaultFastJsonConfig());
converter.setDefaultCharset(charset);
List<MediaType> supportedMediaTypes = Lists.newArrayList();
supportedMediaTypes.add(MediaType.ALL);
converter.setSupportedMediaTypes(supportedMediaTypes);
converters.add(1, converter);
oconverter.setSupportedMediaTypes(supportedMediaTypes);
oconverter.setDefaultCharset(charset);
}
}
æå¾ çæ£ç¡®ç»æ
å¯¹æ¨ææåççç»æè¿è¡æ¸ æ°ç®æ´çæè¿°ã
ç¸å ³æ¥å¿è¾åº
请å¤å¶å¹¶ç²è´´ä»»ä½ç¸å ³çæ¥å¿è¾åºã
éå ä¿¡æ¯
å¦æä½ è¿æå ¶ä»éè¦æä¾çä¿¡æ¯ï¼å¯ä»¥å¨è¿éå¡«åï¼å¯ä»¥æä¾æªå¾ãè§é¢çï¼ã
@wenshao v2.0.53版本什么时候发布
这个周末
@Test
public void test() {
BigDecimal decimal = new BigDecimal("12345678901234567890");
String expected = "\"12345678901234567890\"";
assertEquals(expected, JSON.toJSONString(decimal, WriteBigDecimalAsPlain, BrowserCompatible));
assertEquals(expected,
new String(JSON.toJSONBytes(decimal, WriteBigDecimalAsPlain, BrowserCompatible)));
Bean bean = new Bean();
bean.decimal = decimal;
assertEquals("{\"decimal\":\"12345678901234567890\"}",
JSON.toJSONString(bean, WriteBigDecimalAsPlain, BrowserCompatible));
assertEquals("{\"decimal\":\"12345678901234567890\"}",
new String(JSON.toJSONBytes(bean, WriteBigDecimalAsPlain, BrowserCompatible)));
}
public static class Bean {
public BigDecimal decimal;
}
我测试是好的,WriteBigDecimalAsPlain, BrowserCompatible没有冲突啊
@wenshao 上述就是我写的测试用例,其结果BigDecimal和BigInteger为字符串,如果没有BrowserCompatible其接口返回BigDecimal和BigInteger为数字,其中WriteBigDecimalAsPlain设置不生效,那是和SpringBoot冲突了吗?
public class FastJSONTest {
@Test
public void test() {
BigDecimal decimal = new BigDecimal("12345678901234567890");
String expected = "\"12345678901234567890\"";
assertEquals(expected, JSON.toJSONString(decimal, WriteBigDecimalAsPlain));
}
public static class Bean {
public BigDecimal decimal;
}
public static void main(String[] args) {
BigDecimal decimal = new BigDecimal("12345678901234567890");
String expected = "\"12345678901234567890\"";
String expectNum = JSON.toJSONString(decimal, BrowserCompatible);
String expectStr = JSON.toJSONString(decimal, WriteBigDecimalAsPlain);
System.out.println("期望输出数字类型:"+expectNum);
System.out.println("期望输出字符串:"+expectStr);
System.out.println(expected.equals(expectStr));
}
}
其测试结果如下:
@wenshao 上述测试用例期望结果未达到预期,我理解的预期的和你设计特性是否一致?如果一致这就是Bug,如果不一致则请给出说明
只要配置了BrowserCompatible,在[-9007199254740991, 9007199254740991]之外的数字都要输出为字符串
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER
@wenshao 上述测试用例只配置WriteBigDecimalAsPlain,但BigDecimal输出仍为数字,这是不是问题
@wenshao 上述测试用例只配置WriteBigDecimalAsPlain,但BigDecimal输出仍为数字,这是不是问题
貌似没什么问题,只是以非科学计数法输出数字,而不是以 string格式输出