Com.fasterxml.jackson.databind.JsonMappingException: Unable to deserialize instance of org.springframework.data.domain.Sort from START_ARRAY token

My objectMapper retrieves the type value like Page<User>

this:

userList = objectMapper.readValue(RestAdapter.get(url), new TypeReference<PageImplBean<User>>(){});

      

PageImplBean

extends the class PageImpl

as follows:

public class PageImplBean<T> extends PageImpl<T> {
private static final long serialVersionUID = 1L;
private int number;
private int size;
private int totalPages;
private int numberOfElements;
private long totalElements;
private boolean previousPage;
private boolean first;
private boolean nextPage;
private boolean last;
private List<T> content;
private Sort sort;

public PageImplBean() {
    super(new ArrayList<T>());
}

public int getNumber() {
    return number;
}

public void setNumber(int number) {
    this.number = number;
}

public int getSize() {
    return size;
}

public void setSize(int size) {
    this.size = size;
}

public int getTotalPages() {
    return totalPages;
}

public void setTotalPages(int totalPages) {
    this.totalPages = totalPages;
}

public int getNumberOfElements() {
    return numberOfElements;
}

public void setNumberOfElements(int numberOfElements) {
    this.numberOfElements = numberOfElements;
}

public long getTotalElements() {
    return totalElements;
}

public void setTotalElements(long totalElements) {
    this.totalElements = totalElements;
}

public boolean isPreviousPage() {
    return previousPage;
}

public void setPreviousPage(boolean previousPage) {
    this.previousPage = previousPage;
}



public boolean isNextPage() {
    return nextPage;
}

public void setNextPage(boolean nextPage) {
    this.nextPage = nextPage;
}


public boolean isFirst() {
    return first;
}

public void setFirst(boolean first) {
    this.first = first;
}

public boolean isLast() {
    return last;
}

public void setLast(boolean last) {
    this.last = last;
}

public List<T> getContent() {
    return content;
}

public void setContent(List<T> content) {
    this.content = content;
}

public Sort getSort() {
    return sort;
}

public void setSort(Sort sort) {
    this.sort = sort;
}

public PageImpl<T> pageImpl() {
    return new PageImpl<T>(getContent(), new PageRequest(getNumber(),
            getSize(), getSort()), getTotalElements());
}
}

      

My repository class looks like this:

@EnableScan
@EnableScanCount
public abstract interface UserRepository extends PagingAndSortingRepository<User, String>
{
  public abstract Page<User> findByAddressId(String paramString, Pageable paramPageable);

  public abstract Page<User> findAll(Pageable paramPageable);
}    

      

My service class looks like this:

public Page<User> fetchUserList(String addressId,Integer pageNumber, Integer pageSize){
    Page<User> userPageList = null;

        PageRequest pageRequest = new PageRequest(pageNumber - 1, pageSize, Direction.ASC, "addressId");
        userPageList = userRepository.findByAddressId(addressId, pageRequest);

    return userPageList;
}

      

My Page<User>

object from webservice consists of a viewable instance with a Sort object that consists of the value [addressId: ASC].

When deserializing an object into a userList using the objectMapper as shown above, I am facing the specified error.

com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of org.springframework.data.domain.Sort out of START_ARRAY token

      

Any help is greatly appreciated. Thank.

+3


source to share


1 answer


I ran into this question this morning.

CustomSortDeserializer

import java.io.IOException;

import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;

public class CustomSortDeserializer extends JsonDeserializer<Sort> {

@Override
public Sort deserialize(JsonParser jp, DeserializationContext ctxt)
        throws IOException, JsonProcessingException {
    ArrayNode node = jp.getCodec().readTree(jp);
    Order[] orders = new Order[node.size()];
    int i = 0;
    for(JsonNode obj : node){
        orders[i] =  new Order(Direction.valueOf(obj.get("direction").asText()), obj.get("property").asText());
        i++;
    }
    Sort sort = new Sort(orders);
    return sort;
}

      

Then added the following publici void setSort method:

@JsonDeserialize(using=CustomSortDeserializer.class)
public void setSort(Sort sort) {
    this.sort = sort;
}

      



Edit:

Here is the JSON I got to deserialize (from spring-data-commons - 1.9.2.RELEASE):

[
  {
    "direction": "ASC",
    "property": "amount",
    "ignoreCase": false,
    "nullHandling": "NATIVE",
    "ascending": true
  },
  {
    "direction": "ASC",
    "property": "effectiveDate",
    "ignoreCase": false,
    "nullHandling": "NATIVE",
    "ascending": true
  }
]

      

If you look at Sort , you can see that it implements Iteratable for Order. And if you examine the order defined in the same class, you will see fields in my JSON example. So when Sort is serialized, it is serialized as a list of orders, so deserialization to Sort requires a custom deserializer implementation, and also why deserialization without a special implementation fails (since it tries to deserialize the array into one object).

During deserialization, when a setter annotated with @JsonDeserializer is encountered when each property is deserialized, Jackson uses the provided deserializer to deserialize that particular property.

+10


source







All Articles