1

I'm testing Jersey, I wanted to mack a mock endpoint that produces this JSON object

{
   "Flight1" : 757,
   "Flight2" : 107,
   "Flight3" : 637,
}

so I've written written this resource:

@GET
@Path("myjson")
@Produces(MediaType.APPLICATION_JSON)
public String getMyJson(@QueryParam ("test1") String lat, @QueryParam("test2") String lng) {
    HashMap<String, Integer> map = new HashMap<String, Integer>();
    map.put("Flight 1", 765);
    map.put("Flight 2", 657);
    map.put("Flight 3", 908);
    return map.toString();
}

But then I get this response when I call /myjson

{ Flight 1=765, Flight 2=657, Flight 3=908 }

Jersey already knows which element is a String and which element is an Integer, yet it format then as if they're all numbers. Also the Json as it stands can not be formatted by the "pretty" formatter, and I believe this makes parsing it difficult by http clients.

So my question are:

  1. Why is this happening?

  2. How to avoid it and write simple mock JSON object for testing that is correctly formatted

Young Emil
  • 2,220
  • 2
  • 26
  • 37
Tlink
  • 875
  • 2
  • 14
  • 30

3 Answers3

1

Why is this happening?

Because you are only making a toString of your HashMap. Ex.

    HashMap<String,String> stringStringHashMap = new HashMap<String, String>();
    stringStringHashMap.put("a","b");
    stringStringHashMap.put("b","b");
    stringStringHashMap.put("c","b");

Will print {b=b, c=b, a=b}

How to avoid it and write simple mock JSON object for testing that is correctly formatted

You can do this by using a lot of libraries(Gson, Jackson, JsonSimple,etc). As this already answered what you want to make HashMap to Json

Gatusko
  • 2,503
  • 1
  • 17
  • 25
1

This has nothing to do with Jersey/Tomcat. For core Java programming, that is how best toString() method could process the map to String.

In order to do so you can convert to JSONObject using

    String jon =  JSONObject.valueToString(map);

    System.out.println(jon);

OR even using the gson like

    Gson gson = new Gson();
    String json = gson.toJson(map);
    System.out.println(json);
Young Emil
  • 2,220
  • 2
  • 26
  • 37
  • Thanks this makes sense. So I've imported JSONObject into the project , but the application crashes and I: ` java.lang.ClassNotFoundException: org.json.JSONObject` does the `/Users/USERNAME/.m2/repository/org/json/json/20160212/json-20160212.jar` jar has to be in a specific location for Jersey to find it? – Tlink Dec 06 '17 at 16:17
  • Ok, never mind, I've just used GSON and it's all good now. thanks again. – Tlink Dec 06 '17 at 16:28
1

You can add the Jaxb annotations to serialize and deserialize the response object directly without converting. For this you need to add the jersey's jaxb library so that when you jersey environment is getting booted, it can enable the auto conversion feature.

Example:

@Path("jaxbResource")
@Produces("application/xml")
@Consumes("application/xml")
public class UserResource {
    @GET
    public User[] getUserArray() {
    List<User> userList = new ArrayList<User>();
    userList.add(new User(1, "John"));
    ………
    return userList.toArray(new User[userList.size()]);
    }
}

@XmlRootElement
public class User {
    private int id;
    private String name;

    public User() {}

    public User(int id,String name) {
        this.id = id;
        this.name = name;
    }
    ………
}

Hope this helps!!!

Sunil Gulabani
  • 878
  • 1
  • 8
  • 21
  • 1
    Thanks champ! Guys if you came to this question looking for help, you should definitely check out Sunil's book https://www.amazon.com/Developing-RESTful-Web-Services-Jersey/dp/1783288299 – Tlink Dec 07 '17 at 10:54