解析 JSON 的通用方法

我有一个 JSON 示例


{

    "data":"some string data",

    "amount":200,

    "amountCurrencyList":[

        {"value":4000.0,"currency":"USD"}, 

        {"value":100.0,"currency":"GBP"}

    ]

}

以及当前将其解析为基础对象的映射字段的方法


public void buildDetailsFromJson(String details) {

    if (details != null) {

        TypeReference<HashMap<String, Object>> mapTypeReference = new TypeReference<HashMap<String, Object>>() {

        };

        ObjectMapper mapper = new ObjectMapper();

        try {

            mapper.enable(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY);

            mapper.disable(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES);

            detailsMap = mapper.readValue(details, mapTypeReference);

        } catch (IOException e) {

            log.error("Exception during JSON {} parsing! {}", details, e.getMessage());

        }

    }

}

JSON 结构可以更改。想法是有一个单独的方法,理想情况下可以轻松提取所需的参数,例如map.get(key_name)


例如


public void setUpFieldsFromMap() {

    HashMap<String, Object> map = super.detailsMap;

    this.amountCurrencyList = (ArrayList<MoneyValue>) map.get("amountCurrencyList");

    if (isNull(amountCurrencyList)) {

        throw new InvalidOrMissingParametersException("Exception during JSON parsing! Critical data is missing in DetailsMap - " + map.toString());

    }

}

因此,通过按键获取 List 对象并将其转换为所需的参数。但是当我尝试操作时List<MoneyValue>


System.out.println(detailsObj.getAmountCurrencyList().get(0).getValue());

我越来越


Exception: java.util.LinkedHashMap cannot be cast to MoneyValue

实际上是否有可能实现我想要的,而无需使用精确的参数对 TypeReference 进行硬编码TypeReference<HashMap<String, List<MoneyValue>>>?


UPD


public class MoneyValue {

@NotNull

private BigDecimal value;

@NotNull

private String currency;

EventDetails 类


public class SomeEventDetails extends BaseEventDetails implements EventDetails {


private ArrayList<MoneyValue> amountCurrencyList;



慕森卡
浏览 172回答 1
1回答

泛舟湖上清波郎朗

如果一组属性(我的意思是输入数据的结构)是不可修改的,我们可以将它表示为一个 POJO 类。让它成为DetailsData:public class DetailsData {&nbsp; private String data;&nbsp; private BigDecimal amount;&nbsp; private List<MoneyValue> amountCurrencyList;&nbsp; /*getters, setters, constructors*/&nbsp; public DetailsData() {&nbsp; }&nbsp; @JsonProperty("amountCurrencyList")&nbsp; private void deserializeMoneyValue(List<Map<String, Object>> data) {&nbsp; &nbsp; if (Objects.isNull(amountCurrencyList)) {&nbsp; &nbsp; &nbsp; &nbsp; amountCurrencyList = new ArrayList<>();&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; amountCurrencyList.clear();&nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; MoneyValue moneyValue;&nbsp; &nbsp; for (Map<String, Object> item : data) {&nbsp; &nbsp; &nbsp; moneyValue = new MoneyValue(getValue(item.get("value")),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (String) item.get("currency"));&nbsp; &nbsp; &nbsp; amountCurrencyList.add(moneyValue);&nbsp; &nbsp; }&nbsp; }&nbsp; private BigDecimal getValue(Object value) {&nbsp; &nbsp; BigDecimal result = null;&nbsp; &nbsp; if (value != null) {&nbsp; &nbsp; &nbsp; if (value instanceof BigDecimal) {&nbsp; &nbsp; &nbsp; &nbsp; result = (BigDecimal) value;&nbsp; &nbsp; &nbsp; } else if (value instanceof BigInteger) {&nbsp; &nbsp; &nbsp; &nbsp; result = new BigDecimal((BigInteger) value);&nbsp; &nbsp; &nbsp; } else if (value instanceof Number) {&nbsp; &nbsp; &nbsp; &nbsp; result = new BigDecimal(((Number) value).doubleValue());&nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; throw new ClassCastException("Invalid value");&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return result;&nbsp; }}如您所见,这是一个deserializeMoneyValue注释为 JSON 属性的方法。因此,对于 ObjectMapper,它将用作自定义反序列化器。getValue方法是必要的,因为 Jackson 以这种方式工作,因此值将在满足值大小的类中反序列化。例如,如果 value = "100" 它将被反序列化为Integer,如果 value = "100.0" -Double等等。其实这个方法你可以制作static并移动到一些util类中。总结一下,您可以buildDetailsFromJson通过以下方式进行更改:public void buildDetailsFromJson(String details) {&nbsp; &nbsp; if (details != null) {&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; ObjectMapper mapper = new ObjectMapper();&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mapper.enable(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mapper.disable(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // assuming the eventDetails is an instance of DetailsData&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; eventDetails = mapper.readValue(details, DetailsData.class);&nbsp; &nbsp; &nbsp; &nbsp; } catch (IOException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.error("Exception during JSON {} parsing! {}", details, e.getMessage());&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}和 EventDetail 类:public class SomeEventDetails extends BaseEventDetails implements EventDetails {&nbsp; &nbsp; private List<MoneyValue> amountCurrencyList;&nbsp; &nbsp; @Override&nbsp; &nbsp; public void setUpFieldsFromMap() {&nbsp; &nbsp; &nbsp; &nbsp; this.amountCurrencyList = super.eventDetails.getAmountCurrencyList();&nbsp; &nbsp; &nbsp; &nbsp; if (isNull(amountCurrencyList)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new InvalidOrMissingParametersException("Exception during JSON parsing! Critical data is missing in DetailsMap - " + super.eventDetails.toString());&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java