I'm trying to write a JSON from a java object. Everything works fine until I write the values to a String using the ObjectMapper. The String shows an unexpected field in the JSON document called "map".
I want this:
{
"name": [
{
"a": "1",
"b": "2",
"c": "3",
"d": "4",
"e": "5",
"f": "6"
}
]
}
I get this:
{
"name": [
{
"map": {
"a": "1",
"b": "2",
"c": "3",
"d": "4",
"e": "5",
"f": "6"
}
]
}
This is the class where I've defined the Object I want to convert to JSON:
public class SomeClass{
private List<JSONObject> name;
//getters, setters
}
Can anyone help me?
Please notice that inside the class you are serializing you have a parameter called map if you called it bla you would have seen:
{
"name": [
{
"bla": {
"a": "1",
"b": "2",
"c": "3",
"d": "4",
"e": "5",
"f": "6"
}
]
}
in order to get rid of the parameter name you should use the annotation: #JsonUnwrapped on top of the map parameter inside the class, like:
#JsonUnwrapped
private Map<String, String> map;
Another option is to create a getter function for map use the following:
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(map.getDataMap());
I've solved the problem. I just created an array of object and then I've serialized it with jackson.
private Bla[] bla;
// getters and setters
Class Bla:
private String a;
private String b;
private String c;
...
// getters and setters
Thank you for everything.
Jon
Related
Hi StackOverflow community,
I have a situation where I need to distinct the Java JSONObect key into a List. So that I can do a if else statement after that. Here is an example of my JSON Object.
{
"E23": "1111",
"E25": "5",
"G1": {
"b": "1",
"c": "1"
},
"G2": {
"d": "1"
},
"E2": "test pdf",
"E3": "1",
"E4": "1",
"E5a": "12121991",
"E6": "1",
"E8": "7110",
"E5b": 28,
"E9": "01",
"E1a": "1",
"H3b": "4",
"E24c1": "06",
"E1b": "i",
"H3a": "12",
"E26a": [
"04",
"07",
"09"
],
"E14a": {
"a": "1",
"b": "1",
"c": "1"
}
}
The end result expected is to become like this ArrayList [E,G,H]
Just FYI, the key.chartAt(0) can be from E-I. I am thinking to looping in each of the Object and check the character at 0 and put it in the List if the List doest contain the character yet. But I think its gonna consume a lot of java processing and my function will become longer. Is there any way that I can achieve my end result without looping through all the Object.
Any advise is appreciated.
You can try like this,
JSONObject json = getJsonObject(); // your JSONObject
Set<String> jsonKeys = json.keySet();
Set<Character> myKeySet = jsonKeys.stream()
.map(key-> key.charAt(0))
.collect(Collectors.toSet());
System.out.println(myKeySet);
Output:
[E,G,H]
Note: Since your keys should not be duplicated you use Set, else you can replace it with ArrayList
So, I have the next json:
{
"massive2":[
"a",
"c",
"b"
],
"key5":"val5",
"key2":"val2",
"massive1":[
"3",
"4",
"2",
"1"
],
"key3":"val3",
"key4":"val4",
"key1":"val1"
}
How can I sort all pairs by key and all elements in all massives (to the end of json tree) in alphabetical, or if it is massive in some other order to get json like this:
{
"key1":"val1",
"key2":"val2",
"key3":"val3",
"key4":"val4",
"key5":"val5",
"massive1":[
"1",
"2",
"3",
"4"
],
"massive2":[
"a",
"b",
"c"
]
}
I don't know beforehand how deep my json will be.
Maybe there are some java libraries for this?
let items = {
"massive2":[
"a",
"c",
"b"
],
"key5":"val5",
"key2":"val2",
"massive1":[
"3",
"4",
"2",
"1"
],
"key3":"val3",
"key4":"val4",
"key1":"val1"
};
let data = {};
Object.keys(items).sort().forEach(function(k){
data[k] = items[k];
});
console.log(data);
I use protoc to generate java classes used to serialize data. Sometimes, for example, I want my json to look like:
[
{
"foo": 1,
"bar": "a"
},
{
"foo": 2,
"bar": "b"
},
{
"foo": 3,
"bar": "c"
}
]
I will define an protobuff message:
message Sample {
uint64 foo = 1;
string bar = 2;
}
And I have to define one more message, for array type key:
message SampleResponse {
repeated Sample keys = 1;
}
Above json now looks like:
{
"keys": [
{
"foo": 1,
"bar": "a"
},
{
"foo": 2,
"bar": "b"
},
{
"foo": 3,
"bar": "c"
}
]
}
Is there a possibility to get rid of that excess wrapper-message?
Given that the main purpose of the Protocol Buffer wasn't JSON serialization/deserialization the answer is "No".
Im making an app thats dynamic to a json template (the app reads the template from the internet) and i need to read a JSONArray's key string.
my json:
{
"format": {
"Drive": [
"Mecanum",
"Omni",
"Regular"
],
"Drive-Configuration": [
"H",
"X"
],
"Glyph-Elevator": [
"Parallel Elevator",
"Stick Elevator",
"Strip Elevator"
],
"Glyph-Picker": [
"Strip Picker",
"Dual-Servo Picker"
],
"Relic-Elevator": [
"Horizontal Parallel"
],
"Relic-Holder": [
"Pliers",
"Dual-Servo With Rubber Pads"
],
"CypherBox-Fill": [
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12"
],
"Autonomous": [
"Poor",
"Minimal",
"Okay",
"Good",
"Almost Perfect",
"Perfect"
]
}
}
what i want is to read the "Drive" and the "Drive-Configuration" names by code.
what i have:
JSONObject reader=new JSONObject(template);
JSONArray config=reader.getJSONArray("format");
for(int type=0;type<config.length();type++){
JSONArray con=config.getJSONArray(type);
//Here I Want To Read The Array's Name
}
Instead of JSON Parser use GSON.!
add this to your gradle
compile 'com.google.code.gson:gson:2.8.1'
Create a ClassMain.!
class MainClass{
#SerializedName("format")
Value format;
}
Class value{
#SerializedName("Drive")
ArrayList<String> drive;
#SerializedName("Drive-Configuration")
ArrayList<String> driveConfiguration;
generate getter and setter.!
}
and then Convert your JSON to GSON.!
MainClass mainClass= new Gson().fromJson(json.toString(), MainClass.class);
mainClass.getFormat().getDirve();
Used JSONObject.names();
to read the names
ArrayList<Template> tm = new ArrayList<>();
JSONObject reader = new JSONObject(format);
JSONObject config = reader.getJSONObject("format");
Iterator<String> types = config.keys();
while (types.hasNext()) {
String name = types.next();
tm.add(new Template(name, config.getJSONArray(name)));
}
For example my JSON file look like this;
{
"Test1": {
"A": {},
"B": "1",
"C": "2",
"D": "3"
},
"Test2": {
"A": {},
"B": "4",
"C": "5",
"D": "6"
},
"Test3": {
"A": {},
"B": "7",
"C": "8",
"D": "9"
},
"Test4": {
"A": {},
"B": "10",
"C": "11",
"D": "12"
}
...
...
}
This would have been simple if the file only contained a few records, but in my case I'm dealing with thousands of records. For simpler version I've used gson library but not sure how I could load this JSON file which has unique name for each record into Java.
***************UPDATE*******************************
I now managed to read it raw and Map the data. However, still have a minor issue.
This is the code I used to Map
ObjectMapper mapper = new ObjectMapper();
File jsonFile = new File(jsonFilePath);
Map<String, Object> mapObject = mapper.readValue(jsonFile,
new TypeReference<Map<String, Object>>() {
});
System.out.println(mapObject.get("Test1"));
I'm getting below results, which is fine. However, not sure how I could obtain the data within "values" of the map.
{A={}, B=1, C=2, D=3}
I tried below to re-map but it's failing as expected, because the keys no longer are surrounded by double quotes (see above)!
Map<String, Object> nestedObject = mapper.readValue(
mapObject.get("Test1").toString(),
new TypeReference<Map<String, Object>>() {
});
If you know your objects all contain the same keys A, B, C and D then you could create a class that maps a single object
class MyEntry {
/**
* You've tagged the question "gson" but your example code uses Jackson so I've
* written this class with Jackson annotations rather than Gson ones.
*/
#JsonProperty("A")
public Object a; // or a more specific type if you know one
#JsonProperty("B")
public String b;
#JsonProperty("C")
public String c;
#JsonProperty("D")
public String d;
}
and then unmarshal the JSON as a Map<String, MyEntry>
Map<String, MyEntry> mapObject = mapper.readValue(jsonFile,
new TypeReference<Map<String, MyEntry>>() {
});
System.out.println(mapObject.get("Test1").b); // prints 1