在Java中将BigDecimal字段作为JSON字符串值返回

8

我有一个Get API,它返回一个JSON。期望的格式是:

{
   "value1": "123.00",
   "value2": "23.00"
}

这些值在对象中是 BigDecimal 类型的:

public class Result{
    BigDecimal value1;
    BigDecimal value2;
    // getters and setters
}

现在,当请求被发出时,我创建一个Result对象,并将这些值作为BigDecimal填充,创建一个列表并返回。我收到的响应是:
{
   "value1": 123.00,
   "value2": 23.00
}

这些值是正确的,但它们不是字符串。我怎样才能使它们成为字符串?

我知道我们可以将 BigDecimal 转换为 String,但我只有带有 BigDecimal 字段的对象,无法将字符串值填充到它。

最后,这就是列表是如何制作的:

List<MyObj> obj = Arrays.stream(myObj).collect(Collectors.toList());

    Result result = new Result();

    obj.forEach(t -> t.mergeToResult(result));  // mergeToResults does all the population like result.setValue1(new BigDecimal(123.00))

    return result;

3
你是否在使用一些用于JSON序列化/反序列化的库? - NiVeR
1
你不能创建一个自定义的序列化器,将BigDecimal值转换为字符串,同时返回JSON输出吗? - Ankur
不,不使用任何库。 - roger_that
@Ankur:这就是问题,我该怎么做? - roger_that
如果您需要字符串,请将它们制作成字符串,而不是BigDecimal。如果它们是数字,请遵循有效的JSON标准并将它们返回为数字。 - Veselin Davidov
显示剩余3条评论
3个回答

6
你可以像下面这样使用@JsonFormat注释:
import com.fasterxml.jackson.annotation.JsonFormat;

public class Result {        
   @JsonFormat(shape = JsonFormat.Shape.STRING)
   private BigDecimal value;

   // getters and setters
}

3

使用String

根据我对维基百科页面的阅读,JSON中的Number类型很可能被视为浮点数,这符合JavaScript传统行为。浮点技术有意牺牲精度以换取执行速度。

BigDecimal类恰恰相反,为了保证准确性而牺牲执行速度。

因此,如果您希望最好地保留BigDecimal值,请将其存储为String。希望这种方法可以降低JSON接收方意外将传入值解析为浮点数的可能性。向那些消费您的JSON数据的人明确说明您希望将数据解析为BigDecimal或等效类型而不是浮点数。

Java导出:

String output = myBigDecimal.toString() ;

JSON:

{
   "value1": "123.00",
   "value2": "23.00"
}

Java导入:

BigDecimal bd = new BigDecimal( "123.00" ) ;

学习 BigDecimal::toStringnew BigDecimal( string ) 的文档。您还应该了解 BigDecimal::toPlainString 方法。

流(Streams)

至于您的Java流(streams),我不理解您的问题。您对使用 List 和数组的解释不清楚。

基本上,您应该在您的 Result 类中实现一个 toJson 方法。在您的流代码中调用 Result::toJson 方法。

以下是这样一个类的示例。

package com.basilbourque.example;

import java.math.BigDecimal;

public class Result {

    BigDecimal start, stop;

    public String toJson () {
        StringBuilder sb = new StringBuilder( "{\n" );
        sb.append( "    " );  // Indent with four spaces.
        sb.append( this.enquote( "start:" ) + " " );
        sb.append( this.enquote( start.toString() ) );
        sb.append( " , \n" );
        sb.append( "    " );  // Indent with four spaces.
        sb.append( this.enquote( "stop:" ) + " " );
        sb.append( this.enquote( stop.toString() ) );
        sb.append( "\n}\n" );
        return sb.toString();
    }

    static public Result fromJson ( String json ) {
         …
    }

    private String enquote ( String string ) {
        return "\"" + string + "\"";
    }

    // Constructor
    public Result ( BigDecimal start , BigDecimal stop ) {
        this.start = start;
        this.stop = stop;
    }

    public static void main ( String[] args ) {
        Result r = new Result( new BigDecimal( "123.00" ) , new BigDecimal( "23.00" ) );
        System.out.println( r.toJson() );
    }
}

运行时。

{
    "start:" "123.00" , 
    "stop:" "23.00"
}

考虑使用一个框架

提示:您可能需要考虑使用JSON↔Java映射框架来帮助完成此项工作。


0
如果您使用Spring框架,可以通过以下方式全局配置序列化BigDecimal -> String
@Bean
@Primary
ObjectMapper objectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configOverride(BigDecimal.class)
            .setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.STRING));
    return objectMapper;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接