Java - JSON output is not expected as what console suggests - java

I'm new to Java and writing APIs.
I basically have two things: a HashMap called db that should be returned as a JSON and an ArrayList called defaultParameters. Basically what the application does are the following:
db basically contains an array of objects of key-value pairs that should be returned as a JSON when a user makes a GET request to this address.
defaultParameters is basically a list of default key-value pairs. If there is no key-value pair within that object, then that object takes in that default key-value pair.
I was able to get it to display on the console, but for some reason, the updated values are not appearing in the JSON when I do the get request.
Here are the relevant code snippets:
private static ArrayList<Item> DB = new ArrayList<>();
private static HashMap<String, String> defaultValues = new HashMap<>();
private void updateAllItems(){
for(Item item : DB){
for(Map.Entry entry : defaultValues.entrySet()){
String currentField = (String) entry.getKey();
String currentValue = (String) entry.getValue();
item.addField(currentField, currentValue);
}
}
}
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response getAllItems() {
updateAllItems();
for(Item item : DB){
// Test code that I added
item.printItem();
}
return Response.ok(DB).build();
}
Snippets of the Item class
public class Item {
private HashMap<String, String> item = new HashMap<>();
public void addField(String key, String value){
item.put(key, value);
}
public void printItem(){
for(Map.Entry entry : item.entrySet()){
String currentField = (String) entry.getKey();
String currentValue = (String) entry.getValue();
System.out.println(currentField + ": " + currentValue);
}
}
}
Doing the POST request and doing the GET request yields the following:
On the console (Something: notsomething) is new:
seller: Mrs. Fields
price: 49.99
title: Cookies
category: 42
something: notsomething
The JSON response however:
[{"category":"42","seller":"Mrs. Fields","price":"49.99","title":"Cookies"}]
The JSON is missing the new key-value pair that the console has. I'm trying to have the JSON reflect what the console is doing. Anyone have any ideas?

Alright, after some thinking, I figured out what to do.
I changed my code from
public class Item {
to
public class Item extends HashMap<String, String> {
and removed
private HashMap<String, String> item = new HashMap<>();
which means I had to change item to this. I figured since that I'm going to be using each instance as a hashmap, I may as well extend the hashmap that will change the instance of the item too.
Thanks for everyone's help. The comment gave me some more insight of what I was trying to do which led to a solution.

Related

fill an HashMap with elements of a set passed as parameter

i have to write the method:
public Map<Robot, Integer> PickedUpForEachRobot(Set<Stuff> pickedUp)
which has to iterate through the set passed as parameter and has to count the quantity of stuff picked up by each robot and associate it to his instance.
what i have done is this:
public Map<Robot, Integer> PickedUpForEachRobot(Set<Stuff> pickedUp) {
final Map<Robot,Integer> map = new HashMap<>();
for(Stuff stuff : pickedUp){
Integer quantity = map.get(stuff.getPicker());
if(quantity!=null){
map.put(stuff.getPicker(), quantity);
}
}
return map;
}
I also have other classes:
public class Stuff {
private Robot picker;
public Robot getPicker() {
return this.picker;
}
}
and:
public class Robot {
private Set<Stuff> bunchOfStuff;
public Set<Stuff> getBunchOfStuff() {
return this.bunchOfStuff;
}
}
for which i have tried to be synthetic, so i hope i can be clear anyway.
So my problem is that when i do a test for this method:
#Test
public void testRaccoltoPerMezzo() {
Statistics stats = new Statistics();
Stuff stuff1 = new ball();
Stuff stuff2 = new legoPiece();
Set<Stuff> set = new HashSet<>();
set.add(stuff1);
assertEquals(1,set.size());
Map<Robot,Integer> map = new HashMap<>();
map.put(stuff1.getPicker(),1);
assertEquals(map, stats.PickedUpForEachRobot(set));
}
it fails and it says to me:
java.lang.AssertionError: expected:<{null=1}> but was:<{}>
and i can't understand why. Can somebody help me?
This message :
java.lang.AssertionError: expected:<{null=1}> but was:<{}>
means that you expect to have a map with one element that owns a null key and as associated value 1 but you got a empty map.
The expected map you have created doesn't seem to be adequate according to your requirement and the actual map either.
About the populating of the map in the implementation, I noticed at least this point that is not at all logical.
Here :
final Map<Robot,Integer> map = new HashMap<>();
for(Stuff stuff : pickedUp){
Integer quantity = map.get(stuff.getPicker());
if(quantity!=null){
map.put(stuff.getPicker(), quantity);
}
}
Integer quantity = map.get(stuff.getPicker()); will always value quantity to null as you get it from an empty map : map = new HashMap<>(); and you populate the map only if quantity is not null :
if(quantity!=null){
map.put(stuff.getPicker(), quantity);
}
But it will never happen as the map is empty : so you never populate the map.
You have probably other issues in the code but I hope it will help you to rework your logic.

Retrieving values from nested JSON after de-serialization

I am trying to test my REST service by a JSON string from Chrome's Advanced REST Client. I have a nested JSON here. I am taking this as string and mapping it to my POJO class:
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(addressString, AddressPOJO.class);
Here, addressString holds the JSON String given below
{
"location":"[{\"Asia\":[{\"India\":[{\"city\":\"Bengaluru\"}]}], [{\"India\":[{\"city\":\"Mumbai\"}]}]}]
}
My AddressPOJO has variable:
Map<String,?> location = new HashMap();
I am retrieving the values from the POJO by
Map<String, ?> locations = addressPOJO.getLocation();
Iterator iterator1 = locations.entrySet().iterator();
while(iterator.hasNext()){
Map.Entry pair1 = (Map.Entry)iterator1.next();
Map<String,?> cities = (Map<String,?>) pair1.getValue();
Iterator iterator2 = dataSets.entrySet().iterator();
while(iterator.hasNext()){
Map.Entry pair2 = (Map.Entry)iterator2.next();
Map<String,?> city = (Map<String, ?>) pair2.getValue();
}
}
Here, I am only able to retrieve the second entry which is
[{\"India\":[{\"city\":\"Mumbai\"}]}]
I need to retrieve all the entries. I also tried to use MultiMap like this
MultiMap cities = (MultiMap) pair1.getValue();
But this is not accepted by compiler. Please note all the entries are dynamic in nature and the (key, value) pairs change as per user's input. Any suggestions how I can retrieve all the entries in this example.
From my understanding, maybe there are 2 things that you need to look into:
Why the data type of location is Map<String, ?>? Because from your JSON string, the type of location is an Array or a List, right? If you want to make it a Map, please use some strings like: {"location" : "\"key\":\"value\""}. If you want to make it a List, remove the "" around the value.
Another thing is that, it seems that you want a hierarchy to describe the some geography structure. Let's say, in Asia we have India and China, and in India we have Bengaluru and in China we have the city Chengdu. So the value of Asia should also be a List which contains two items India and China. So you should remove the ] and [ here, and I think this is also the reason why you are only able to retrieve the second entry.
Following is my testing code, I modified your JSON string and the data type of location.
Location.java
public class Location {
private List location;
public List getLocation() {
return location;
}
public void setLocation(final List location) {
this.location = location;
}
}
TestJSON.java
public class testJson {
private static ObjectMapper mapper = new ObjectMapper();
public static void main(final String[] args) throws JsonParseException, JsonMappingException, IOException {
final String locationString = "{\"location\":[{\"Asia\":[{\"India\":[{\"city\":\"Bengaluru\"}]}, {\"India\":[{\"city\":\"Mumbai\"}]}]}]}";
final Location location = mapper.readValue(locationString, Location.class);
System.out.println("finish");
}
}
Then all entries and levels are ok. Maybe you can have a try.
Hope this will help.

How do I add entries to existing list in Client Server java application?

I'm a beginner in Java. I am asked to develop an online multiplayer game using java.
On first JFrame ,Player has to put user id. When the player clicks the login button I need to put his/her name in a list. After another one login with a user id , I need to put his/her user id for the existing list(After the first one). What I tried is this. But when I run multiple applications , the name is only added in separate applications. The second name is not adding after the first one. How can I overcome this issue? Please help me.
public class Players {
private static Client client;
//Getting details from Fist Form.
public Players(String name, String address, int port) {
client= new Client(name,address,port);
String b = client.getName();
JOptionPane.showMessageDialog(null,"name :" + b);
// create map to store
Map<String, List<String>> map = new HashMap<String, List<String>>();
// create list one and store values
List<String> valSetOne = new ArrayList<String>();
valSetOne.add(b);
map.put("A", valSetOne);
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
String key = entry.getKey();
List<String> values = entry.getValue();
System.out.println("Players = " + values);
}
}
public static void main(String[] args) {
}}
Thanks

aerospike JUNIT Record Constructor not working

I am writing aeropsike junit test cases for my test cases. For Storing aerospike bins, i am using ConcurrentHashMap.
// InMemory Map for storing AeroSpike Related Data...
ConcurrentMap<String, Bin[]> aerospike_keyBins = new ConcurrentHashMap<String, Bin[]>();
// InMemory Map for storing AeroSpike Related Data...
ConcurrentMap<String, Integer> aerospike_keyGen = new ConcurrentHashMap<String, Integer>();
Storing of bins and GenNumber related information is working perfectly fine.
But i am facing issues while getting record from map (Actually converting bins values from Map to Aerospike Record).
Here is the function which is expected to convert the same.
private Record binsToRecord(String stringKey, Bin... bins) {
Map<String, Object> mapOfBins = new HashMap<String, Object>();
for (Bin bin : bins) {
mapOfBins.put(bin.name, bin.value);
}
return new Record(mapOfBins, aerospike_keyGen.get(stringKey), 1);
}
While Calling new Record in that function i am getting following error message.
java.lang.ClassCastException: com.aerospike.client.Value$StringValue cannot be cast to java.lang.String
at com.aerospike.client.Record.getString(Record.java:66)
On Debugging this issue, i found that in Record.class of Aerospike,
following function is giving error.
/**
* Get bin value as String.
*/
public String getString(String name) {
return (String) getValue(name);
}
getValue is returning correct value but (String) getValue(name) throwing error.
Any clue about why am i getting this error ?
Your binsToRecord method looks fine.
/**
* Get bin value as String.
*/
public String getString(String name) {
return (String) getValue(name);
}
Here in the Bin binValue is a StringValue object so you can't directly cast it to String.
try
(getValue(name)).toString()
// StringValue object provide toString() method.
Actually the problem was while putting values to local hashmap.
I was pushing StringValues type of values in local hashmap Fixing that to put Standard String fixed the problem.
Here is the new binsToRecordfunction.
/*
* Convert Bin Set to Record Object.
*/
private Record binsToRecord(String stringKey, Bin... bins) {
Map<String, Object> mapOfBins = new HashMap<String, Object>();
for (Bin bin : bins) {
if (bin.value instanceof Value.StringValue)
mapOfBins.put(bin.name, bin.value.toString());
else if (bin.value instanceof Value.LongValue)
mapOfBins.put(bin.name, bin.value.toLong());
else if (bin.value instanceof Value.DoubleValue)
mapOfBins.put(bin.name, bin.value.toLong());
}
return (new Record(mapOfBins, aerospike_keyGen.get(stringKey), 1));
}

Illegal state exception when putting in a Map

I don't understand why I get the infamous "IllegalStateException" whith the following code:
private void mergeQueryStrings(String url, Map parameterMap) {
String queryString = getQueryString(url);
if(queryString!=null){
String [] params = queryString.split("&");
for(String param:params){
parameterMap.put(param.split("=")[0], param.split("=")[1]);
}
}
}
Could anyone enlighten me?
You've supplied an unmodifiable map. For example, the ServletRequest#getParameterMap() is immutable. If you have no control over the supplied map, then you need to create a new map, put the new items in there, return it and use it instead.
private Map mergeQueryStrings(String url, Map parameterMap) {
Map newParameterMap = new HashMap(parameterMap);
String queryString = getQueryString(url);
if(queryString!=null){
String [] params = queryString.split("&");
for(String param:params){
newParameterMap.put(param.split("=")[0], param.split("=")[1]);
}
}
return newParameterMap;
}
If you were actually using the servlet request parameter map for this, then you'd like to replace the original one with help of a HttpServletRequestWrapper in a Filter. But that's a completely different story :)
Unrelated to the concrete problem, you should url-decode the query string parts before putting them in the new map.

Categories