Home > Net >  How to deserialize value of type from array value?
How to deserialize value of type from array value?

Time:04-13

I'm getting an error when trying to convert JSON to an object and I have no idea how I can solve this.

I am trying to map such JSON:

{
    "code": "USD",
    "rates": [
        {
            "effectiveDate": "2022-04-12",
            "mid": 4.2926
        }
    ]
}

I get this message: Cannot deserialize value of type com.example.nbpmaster.webclient.dto.CurrencyRatesDto from Array value (token JsonToken.START_ARRAY) at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 67] (through reference chain: com.example.nbpmaster.webclient.dto.CurrencyDto["rates"])

The class that the message points:

package com.example.nbpmaster.webclient.dto;

import lombok.Getter;
import org.springframework.format.annotation.DateTimeFormat;

import java.time.LocalDate;

@Getter
public class CurrencyRatesDto {
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate effectiveDate;
    private float mid;

}

another dto class:

package com.example.nbpmaster.webclient.dto;

import lombok.Getter;
import java.util.List;


@Getter
public class CurrencyDto {
    private String code;
    private List<CurrencyRatesDto> rates;


}

model Dto:

package com.example.nbpmaster.model;


import lombok.Builder;
import lombok.Getter;
import org.springframework.format.annotation.DateTimeFormat;

import java.time.LocalDate;


@Getter
@Builder
public class CurrencyModelDto {
    private String code;
    private float mid;
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate effectiveDate;
}

client(call)

package com.example.nbpmaster.webclient.currency;

import com.example.nbpmaster.model.CurrencyModelDto;
import com.example.nbpmaster.webclient.dto.CurrencyDto;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

@Component
public class CurrencyClient {

    public static final String URL_API_NBP = "http://api.nbp.pl/api/";
    private final RestTemplate restTemplate = new RestTemplate();

    public CurrencyModelDto getCurrencyType(String value) {
        CurrencyDto currencyDto = callGetMethod("exchangerates/rates/a/{currency}/", CurrencyDto.class, value);
        return CurrencyModelDto.builder()
                .code(currencyDto.getCode())
                .mid(currencyDto.getRates().getMid())
                .effectiveDate(currencyDto.getRates().getEffectiveDate())
                .build();
    }

    private <T> T callGetMethod(String url, Class<T> responseType, Object... objects) {
        return restTemplate.getForObject(URL_API_NBP   url,
                responseType, objects);
    }


}

CodePudding user response:

rates property is array in json, rates field is object in your class. You need to deserialize in the same type - array to array/list, object to object, etc. Make the field array or list in class and you are good to go.

@Getter
public class CurrencyDto {
    private String code;
    private CurrencyRatesDto[] rates;
}

CodePudding user response:

The error Cannot deserialize value of type com.example.nbpmaster.webclient.dto.CurrencyRatesDto from Array value (token JsonToken.START_ARRAY is clear.

The deserializer is expecting rates to be an Object, but it found a JsonToken.START_ARRAY, which is the char [.

You are trying to deserialize a JSON array into a Object (CurrencyRatesDto).

In your CurrencyDto class, change the CurrencyRatesDto to some sort of Collection or primitive array -- I used List<CurrencyRatesDto> in the following example

@Getter
public class CurrencyDto {
    private String code;
    private List<CurrencyRatesDto> rates;
}
  • Related