0

I have following Rest service which queries a database, constructs multiple "Chat"-objects and returns them as an array:

@GET
@Path("/getChats")
@Produces(MediaType.APPLICATION_JSON)
public Chat[] getChats(@QueryParam("userId") String userId){

  ArrayList<Chat> chats = getChatsDB(userId);
  Chat[] chatAr = new Chat[chats.size()];
  return chats.toArray(chatAr);
}

The "Chat"-class is a POJO:

import java.util.HashMap;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;


@JsonIgnoreProperties(ignoreUnknown = true)
public class Chat {
private String userId1;
private String userId2;
private HashMap<String, String> msgs;

public Chat() {
    msgs = new HashMap<>();
}

public String getUserId1() {
    return userId1;
}

public void setUserId1(String userId1) {
    this.userId1 = userId1;
}

public String getUserId2() {
    return userId2;
}

public void setUserId2(String userId2) {
    this.userId2 = userId2;
}
public void addMsg(String date, String msg){
    msgs.put(date, msg);
}

public HashMap<String, String> getMsgs() {
    return msgs;
}    
}

The client code for getting this chat objects is :

public static Chat[] getChats() {
    Chat[] chats = null;
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
    String chatUrl = url+"getChats?userId="+user.getId();
    chats = restTemplate.getForObject(chatUrl, Chat[].class);
    for(Chat c: chats){
        System.out.println(c.getUserId1());
        System.out.println(c.getUserId2());
        for(Map.Entry<String,String> e : c.getMsgs().entrySet()){
            System.out.println(e.getKey() + e.getValue());
        }
    }
    return chats;

The client recieves the chat objects, but without the HashMap with the messages. c.getUserId1 and c.getUserId2 return the correct values, but the HashMap is empty. This problem is only on the client side. The chat-objects in the servicemethod getChats(@QueryParam("userId") String userId) have the correct values in the HashMap.

Opening the link in the browser shows this:

[{"userId1":"414","userId2":"12"}]

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
randomdev8712
  • 261
  • 1
  • 6
  • 23

1 Answers1

2

You need to have both getter and setter in your POJO for the inner map.

public class Chat {
    private HashMap<String, String> msgs;

    public void setMsgs(HashMap<String, String> msgs) {
        this.msgs = msgs;
    }    

    // rest of the code ...
}

If you don't want to change pojo implementation for some reason, you can setup Jackson to use private fields and not getters/setters, something like this: how to specify jackson to only use fields - preferably globally


For some reason your serverside sends you

"maps":{"entry":[{"key":"key1","value":"value1"}]}
instead of 
"maps":{"key1":"value1","key2":"value2"}

You can probably solve it with just client side pojo changes like this:

public void setMsgs(Map<String, List<Map<String,String>>> entries){
    for (Map<String, String> entry: entries.get("entry"))
        msgs.put(entry.get("key"),entry.get("value"));
}
varren
  • 14,551
  • 2
  • 41
  • 72
  • @cyden, hm do you have control over the server, the output looks kinda strange, sure you can come up with a solution to parse the server output, but it would probably be easier to change server side to generate proper json for maps : `"maps":{"key1":"value1"}` instead of `"maps":{"entry":[{"key":"key1","value":"value1"}]}` Updating my answer with just client side changes you need to make to parse your data – varren Nov 29 '17 at 20:44
  • @cyden np, also take a look at https://github.com/FasterXML/jackson-databind/issues/565#issuecomment-317821695 i think the reason is that your db actually gives you POJO with `List>` or `Iterable>` instead of `Map` – varren Nov 29 '17 at 21:05