I am trying to do HTTP PUT using org.apache.cxf.jaxrs.client.WebClient. Server expects the payload in format:
{"key":"mainkey","value":{\"intKey1\":\"value1\",\"intKey2":\"value2\"},"ttl":"100"}
however, I am ending up sending as below:
{"key":"mainkey","value":{"intKey1":"value1","intKey2":"value2"},"ttl":"100"}
(Note that internal key value needs an escape quotes)
Here is my code snippet:
private void callClient4(RestClient client) {
KeyValueMessage<String, Map<String, String>> kv = new KeyValueMessage<String, Map<String, String>>();
kv.setKey("mainkey");
kv.setTtl("100");
Map<String, String> map = new HashMap<>();
map.put("intKey1", "value1");
map.put("intKey2", "value2");
kv.setValue(map);
Response ret = client.getClient().accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON).sync()
.put(Entity.json(kv));
}
What could be done to change the format as expected by server?
used com.fasterxml.jackson.databind.ObjectMapper to solve the problem
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.writeValueAsString(map);
Related
I have a composite object like below:
Map<String, Object> m = new HashMap<>();
m.put("a", "b");
m.put("c", "{\"a\" :3, \"b\" : 5}");
m = {a=b, c={"a" :3, "b" : 5}}
I have to submit this request via https call in order to deserialize to a java object, hence i converted this to JSON string, using,
objectmapper.writeValueAsString(m)
when i convert it , it is appending quotes to the value of c:
{"a":"b","c":"{\"a\" :3, \"b\" : 5}"}
and While deserializing this object at the client side, the request fails saying
"Error deserialize JSON value into type: class"
Any help??
The type of the value C is String, so the object mapper escapes all illegal characters a wraps the string in quotes.
You could make C an another map:
Map<String, Object> c = new HashMap<>();
c.put("a", 3);
c.put("b", 5);
Map<String, Object> m = new HashMap<>();
m.put("a", "b");
m.put("c", c);
Or you can create custom POJO and use #JsonRawValue annotation:
public class MyPojo{
private String a;
#JsonRawValue
private String c;
// getter and setters
}
MyPojo m = new MyPojo();
m.setA("b");
m.setB("{\"a\" :3, \"b\" : 5}");
objectmapper.writeValueAsString(m);
From the documentation:
Marker annotation that indicates that the annotated method or field should be serialized by including literal String value of the property as is, without quoting of characters. This can be useful for injecting values already serialized in JSON or passing javascript function definitions from server to a javascript client.
Warning: the resulting JSON stream may be invalid depending on your input value.
The client error meaning probably is that it can't deserialize String into an Object (it expects { instead of ").
You better use JSONObject for c value:
JSONObject json = new JSONObject();
json.put("a", 3);
json.put("b", 5);
Map<String, Object> m = new HashMap<>();
m.put("a", "b");
m.put("c", json);
Complete code:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.minidev.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
public static void main(String[] args) throws JsonProcessingException {
JSONObject json = new JSONObject();
json.put("a", 3);
json.put("b", 5);
Map<String, Object> m = new HashMap<>();
m.put("a", "b");
m.put("c", json);
ObjectMapper objectMapper = new ObjectMapper();
String valueAsString = objectMapper.writeValueAsString(m);
System.out.println(valueAsString);
}
The output is:
{"a":"b","c":{"a":3,"b":5}}
I'm looking for good way or complete API to create a hierarchical JSON from plain java.util.Properties object.
Exist java.util.Properties object, e.g.:
car.color=blue
car.places=4
car.motor.dimension=2L
car.motor.ps=120
and the target json structur should be:
{
"car":
{"color":"blue",
"places":4,
"motor":
{"dimension":"2L",
"ps":120
}
}
}
public void run() throws IOException {
Properties properties = ...;
Map<String, Object> map = new TreeMap<>();
for (Object key : properties.keySet()) {
List<String> keyList = Arrays.asList(((String) key).split("\\."));
Map<String, Object> valueMap = createTree(keyList, map);
String value = properties.getProperty((String) key);
value = StringEscapeUtils.unescapeHtml(value);
valueMap.put(keyList.get(keyList.size() - 1), value);
}
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(map);
System.out.println("Ready, converts " + properties.size() + " entries.");
}
#SuppressWarnings("unchecked")
private Map<String, Object> createTree(List<String> keys, Map<String, Object> map) {
Map<String, Object> valueMap = (Map<String, Object>) map.get(keys.get(0));
if (valueMap == null) {
valueMap = new HashMap<String, Object>();
}
map.put(keys.get(0), valueMap);
Map<String, Object> out = valueMap;
if (keys.size() > 2) {
out = createTree(keys.subList(1, keys.size()), valueMap);
}
return out;
}
The following project 'Java Properties to JSON' achieves exactly what you seek.
However, it has a restriction on Java 8.
Would be great if someone actually provides changes to make it Java 7 compatible.
You will need to parse your properties to Map<String, Object> where your Object will be either another Map<String, Object> or a String. For this you will have to write your own code. I suppose you will need to take your properties keys and split them over "." using method String.split(). Note that in your code you will need to use "\\." as a parameter as "." is a regular expression. Once you build your Map it is very easy to convert it to JSON using Jackson library or any available JSON library.
I have a JsonObject :
{"result":[{"active":"true"}]}
How can I get value of active?
You can use Jackson
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> parsedMap = mapper.readValue(jsonString, new TypeReference<HashMap<String, Object>>() {
});
We get a Map with key value pairs. With your input you will get a Map<List<Map<String,String>>>. So to get "active", you can use something like parsedMap.get("result").get(0).get("active") (Note: This is just a pseudo code)
I am trying to use map with Bulk Insert Api of ElasticSearch Java Api
public void bulkInsert(List<Map<String,String>> listOfObjects ){
BulkRequestBuilder bulkRequest = client.prepareBulk();
Iterator<Map<String,String>> itr = listOfObjects.iterator();
if (itr.hasNext()){
Map<String,String> document = itr.next();
bulkRequest.add(client.prepareIndex(index, type)
.setSource(document));
}
BulkResponse bulkResponse = bulkRequest.execute().actionGet();
if (bulkResponse.hasFailures()) {
System.out.println(bulkResponse.buildFailureMessage());
}
}
And I am calling this with
Map<String,String> jsonMap = new HashMap<String,String>();
jsonMap.put("name", fullName.toString());
jsonMap.put("file", file);
List<Map<String,String>> listOfObjects = new ArrayList<Map<String,String>>();
listOfObjects.add(jsonMap);
indexService.bulkInsert(listOfObjects);
I am getting following exception
The number of object passed must be even but was [1]
Ok I got the fix :
Use Map<String, Object> instead of Map <String,String>
Map<String,Object> jsonMap = new HashMap<String,Object>();
jsonMap.put("name", fullName.toString());
jsonMap.put("file", file);
List<Map<String,Object>> listOfObjects = new ArrayList<Map<String,Object>>();
listOfObjects.add(jsonMap);
indexService.bulkInsert(listOfObjects);
From ES java api;
Using Map
Map is a key:values pair collection. It represents a JSON structure:
Map<String, Object> json = new HashMap<String, Object>();
json.put("user","kimchy");
json.put("postDate",new Date());
json.put("message","trying out Elasticsearch");
Is there a way to convert a String containing json to a HashMap, where every key is a json-key and the value is the value of the json-key? The json has no nested values. I am using the Gson lib.
For example, given JSON:
{
"id":3,
"location":"NewYork"
}
resulting HashMap:
<"id", "3">
<"location", "NewYork">
Thanks
Use TypeToken, as per the GSON FAQ:
Gson gson = new Gson();
Type stringStringMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String,String> map = gson.fromJson(json, stringStringMap);
No casting. No unnecessary object creation.
If I use the TypeToken solution with a Map<Enum, Object> I get "duplicate key: null".
The best solution for me is:
String json = "{\"id\":3,\"location\":\"NewYork\"}";
Gson gson = new Gson();
Map<String, Object> map = new HashMap<String, Object>();
map = (Map<String, Object>)gson.fromJson(json, map.getClass());
Result:
{id=3.0, location=NewYork}
I like:
private static class MyMap extends HashMap<String,String> {};
...
MyMap map = gson.fromJson(json, MyMap.class);