Serialize Java List to JSON without field name - json

public class MyResponse {
private List<Data> data;
public static class Data {
private long id;
private String name;
}
}
Using Jackson this gets serialized to the following JSON:
{
"data": [
{
"id": 115125,
"name": "AAAY"
}
]
}
What I need instead is the JSON like this, i,e. omitting the wrapping Data class:
[
{
"id": 115125,
"name": "AAAY"
}
]

Place the #JsonValue annotation on the data field:
public class MyResponse {
#JsonValue
private List<Data> data;
...
}

Related

how to parse a json similar string and map it into a pojo

I am trying to map the following JSON to my POJO using Jackson. I have the following JSON and following POJOs. kindly let me know how to map the JSON to POJO.
JSON string :
{
"Application": {
"id": "0",
"name": "MyApp",
"users": [
{
"User": {
"id": "2",
"name": "Beth Jones"
}
}
],
"groups": [
{
"Group": {
"id": "1",
"name": "SimpleGroup",
"users": [
{
"User": {
"id": "2",
"name": "Beth Jones"
}
}
]
}
}
]
}
}
The POJO according to the client specification is below :
package com.example.custom;
//import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.example.Application;
import com.example.Group;
import com.example.User;
import java.util.Collection;
//#JsonIgnoreProperties(ignoreUnknown = true)
public class MyApplication extends Application {
private Collection<User> users;
private Collection<Group> groups;
public MyApplication(String id, String name) {
super(id, name);
}
public void setUsers(Collection<User> users) {
this.users = users;
}
public void setGroups(Collection<Group> groups) {
this.groups = groups;
}
#Override
public Collection<User> getUsers() {
return this.users;
}
#Override
public User getUser(String userId) {
for (User user: MyParser.myApp.getUsers()) {
if (user.getId().equals(userId))
return user;
}
return null;
}
#Override
public Collection<Group> getGroups() {
return this.groups;
}
#Override
public Group getGroup(String groupId) {
for (Group group: MyParser.myApp.getGroups()) {
if (group.getId().equals(groupId))
return group;
}
return null;
}
#Override
public String toString() {
return "MyApplication{" +
"users=" + users +
", groups=" + groups +
'}';
}
}
Mapping Logic :
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MyParser.myApp = mapper.readValue(rewriter.getText(),MyApplication.class);
The resulting object is not able to capture anything as it is all null. Kindly help. Thanks in advance.
I think you should model your JSON correctly, In the users list you shouldn't specify it again that the key is User, that should be preassumed that a list of users will only contain user, same goes for groups list.
IMHO the JSON should look something like this :
{
"application": {
"id": "0",
"name": "MyApp",
"users": [ . ==> Since this is a user List, it will definitely contains user.
{
"id": "2",
"name": "Beth Jones"
}
],
"groups": [
{
"id": "1",
"name": "SimpleGroup",
"users": [
{
"id": "2",
"name": "Beth Jones"
}
]
}
]
}
}
Now the POJO also needs some modification, I am just adding the bare-minimum POJO.
class Application { <====== Top Level Class
private Long id;
private String name;
private List<User> users; // Application has some Users
private List<Group> groups; // Application has some groups
}
class User {
private Long id;
private String name;
}
class Group {
private Long id;
private String name;
private List<User> users; // Each group has some associated users.
}
Now you can use any standard JSON library for Java and convert your JSON into POJO. This will simplify your structure and you won't face null issues with this structure.

How automatically parse response String into Map using RestTemplate

I'm using RestTemplate to retrieve list of issues from Jira. As response I get String with lots of fields, some of them are arrays. Request looks like:
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
Response string looks like:
{
"expand": "schema,names",
"total": 12,
"issues": [
{
"id": "32",
"key": "TEST-1",
"fields": {
"fixVersions": [
{
"description": "",
"releaseDate": "2017-04-02"
}
]
},
{
"id": "32",
"key": "TEST-2",
"fields": {
"fixVersions": [
{
"description": "",
"releaseDate": "2017-04-01"
}
]
}
]
}
Is it possible to convert this String into Map, where Object could be String or List of Map or something like this, without defining appropriate objects. As result, I'd like to have possibility to access description by: response.getIssues().get(0).getFields().getFixVersion().get(0).getDescription()
In such occasion, defining chain of specific objects looks too cumbersome.
You can create your own POJO classes which corresponds to the structure of the response JSON.
Based on the json that you have shared, you can have a class structure like this :
public class Response {
private String expand;
private String total;
private List<Issues> issues;
}
public class Issues {
private String id;
private String key;
private Map<String, List<FixVersions> fields;
}
public class FixVersions {
private String description;
private String releaseData;
}
Your GET call will change to the following :
ResponseEntity response = restTemplate.exchange(url,
HttpMethod.GET, entity, Response.class);
P.S. - All the fields in the POJO class must have their getters and
setters as well.

Json/Apex: Assigning values to nodes on the Json Array

I have an apex code that defines the JSON structure. I would like to seek for advice on how I will be able to assign values to the string fields on the JSON using Apex. The JSON will have an array (PackageData) which contains the fields that should contain the values
Apex code:
public class Shipment{
public PackageData[] PackageData;
}
public class PackageData{
public Packaging Packaging;
public Dimensions Dimensions;
public PackageWeight PackageWeight;
}
public class Packaging{
public string Code;
}
public class Dimensions{
public UnitOfMeasurement UnitOfMeasurement;
public string Length;
public string Width;
public string Height;
}
public class UnitOfMeasurement{
public string Code;
}
public class PackageWeight{
public UOM UOM;
public string Weight;
}
public class UOM{
public string Code;
}
JSON:
{
"PackageData": [
{
"Packaging": {
"Code": ""
},
"Dimensions": {
"UnitOfMeasurement": {
"Code": ""
},
"Length": "",
"Width": "",
"Height": ""
},
"PackageWeight": {
"UOM": {
"Code": ""
},
"Weight": ""
}
}
]
}
JSON are always string, so there are a parser which parse object to JSON String and vice versa
Parser does it's job and automatically parse to String, You need not worry for that
Json to Object:
ClassName objName = (ClassName) System.JSON.deserialize(jsonString, ClassName.class);
Object to Json:
String jsonString = System.JSON.serialize(objName);

What is the convenient way to deserialize JSON(links + embedded container) using spring-hateoas?

colleagues!
We want to write Rest Client to service which follow the HATEOAS principle. So we have the following HAL+JSON representation and we want to deserialize it using spring-hateoas :
{
"id": "1",
"title": "album title",
"artistId": "1",
"stockLevel": 2,
"_links": {
"self": {"href": "http://localhost:8080/rest/albums/1"},
"artist": {"href": "http://localhost:8080/rest/artist/1"}
},
"_embedded": {
"albums": [{ //can be array or object
"id": "1",
"title": "album title",
"artistId": "1",
"stockLevel": 2,
"_links": {
"self": {"href": "http://localhost:8080/rest/albums/1"}
}
}],
"artist": { //can be array or object
"id": "1",
"name": "artist name",
"_links": {
"self": {"href": "http://localhost:8080/rest/artist/1"}
}
} //....
}
}
We expected the java object like this:
HalResource {
Resource<Album> //entity
List<Link> // _links
List<Resource<BaseEntity>>{ //_embedded
Resource<Album>
Resource<Artist>
....
}
}
So we have custom resource representation with embedded(list of resources) and entity(single resource):
#XmlRootElement(name = "resource")
public class HalResource<EntityType, EmbeddedType> extends Resources<EmbeddedType> {
#JsonUnwrapped
private EntityType entity;
public HalResource() {
}
public HalResource(Iterable<EmbeddedType> content, Link... links) {
super(content, links);
}
public EntityType getEntity() {
return entity;
}
public void setEntity(EntityType entity) {
this.entity = entity;
}
}
DTO classes:
public abstract class BaseEntity{}
#XmlRootElement(name = "album")
public class Album extends BaseEntity {
private String id;
private String title;
private String artistId;
private int stockLevel;
// getters and setters...
}
#XmlRootElement(name = "artist")
public class Artist extends BaseEntity {
private String id;
private String name;
// getters and setters...
}
And we want to get something like this, where Entity will be Artist or Album, but HalResourcesDeserializer return Resource.class with null content.
HalResource<Album, Resource<Entity>> resources =
restClient.getRootTarget().path("albums/1").queryParam("embedded", true).request().accept("application/hal+json")
.get(new GenericType<HalResource<Album, Resource<Entity>>>() {});
By using #JsonTypeInfo and #JsonSubTypes anotations we successfully deserialized our JSON(you can see the example on the github), but we don't want to have some additional type filds and anotattions in our DTO and JSON format.
We see one solution that is create a custom deserializer which can processing that.
So the question is: What is the convenient way to deserialize our JSON(links + embedded container) using spring-hateoas?
We use spring-hateoas 0.16v(but we tried 0.19v) and glassfish jersey 2.22.1
Thank you!

How do deserialize a json object with a Map as one of its properties

I have been using jackson to deserialize successfully json objects and arrays, but this time I just can't wrap my head around how to approach deserialization for the following object. How can I, with Jackson or any other json parsing library, deserialize:
[
{
"name": "x",
"elements": {
"key1": {
"name": "a",
"type": "b"
},
"key2": {
"name": "a",
"type": "b"
}
}
},
{
"name": "y",
"elements": {
"key3": {
"name": "a",
"type": "b"
}
}
}
]
into a list, List<Test>, where Test is defined below?
public class Test {
public class Element {
public String name;
public String type;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
public String name;
public Map<String, Element> elements;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<String, Element> getElements() {
return elements;
}
public void setElements(Map<String, Element> elements) {
this.elements = elements;
}
}
Finally, my deserializing code:
public List<Test> test(final InputStream inputStream) {
List<Test> test = null;
try {
test = mapper.readValue(inputStream, new TypeReference<List<Test>>() { });
} catch (final IOException e) {
log.error("Unable to deserialize json",e);
}
return test;
}
If that is not possible, what object can I actually deserialize my json into? One thing I cannot know ahead of time is the name of the keys (key1, key2, key3 in the example).
It looks like this:
ObjectMapper mapper = new ObjectMapper();
List<Test> tests = mapper.readValue(jsonInput, new TypeReference<List<Test>>() { };
would do it. The only tricky part is that TypeReference, which is needed to pass generic type information. Other libs use similar approaches (GSON has TypeToken or such).