I'm trying to create a simple REST API with Spring MVC, that returns data in JSON format.
I'm working on a method that returns a list of authors, that's accessed from example.com/api/authors?find=somename
I have a JPA entity called Authors. I have a #Service that fetches a List<Author> collection. The Author entity has properties, like id, firstName, lastName, birthDate.
What I'm trying to achieve is that my JSON result is something like:
{
"data": [
{
"id": 1,
"name": "Leo Tolstoi",
"age": 49
},
{
"id": 2,
"name": "Billy Shakespeare",
"age": 32
}
]
}
As you can see, the result has 2 fields that are not directly from the entity, rather should be generated from Author entity's values. The name field is author.getFirstName() + " " + author.getLastName() and the age is someUtilityClass.calcAge(author.getBirthDate())
I'm trying to figure out how to get this sort of output using GSON.
What I could do, is fetch data from the service class and iterate over it, saving each iteration row to a Map (or something, maybe just save each row to something like List<AuthorJson> entity, which has fields like id, name, age). But this approach doesn't seem to be very clean.
Can you guys suggest any solutions?
You should use a custom Serializer for Author.
Documentation
Since you just need a Serializer, here is an example of what you can do. Note that age will be off by one most of the time.
public static void main(String[] args) {
GsonBuilder gBuild = new GsonBuilder();
gBuild.registerTypeAdapter(Author.class, new AuthorSerializer());
Author author = new Author();
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 1988);
cal.set(Calendar.MONTH, 1);
cal.set(Calendar.DAY_OF_MONTH, 1);
author.setBirthDate(cal);
author.setFirstName("John");
author.setLastName("Smith");
Gson gson = gBuild.setPrettyPrinting().create();
System.out.println(gson.toJson(author));
}
private static class AuthorSerializer implements JsonSerializer<Author> {
#Override
public JsonElement serialize(Author src, Type typeOfSrc, JsonSerializationContext context) {
Calendar today = Calendar.getInstance();
int age = today.get(Calendar.YEAR) - src.getBirthDate().get(Calendar.YEAR);
String fullName = src.getFirstName() + " " + src.getLastName();
JsonObject obj = new JsonObject();
obj.addProperty("fullName", fullName);
obj.addProperty("age", age);
return obj;
}
}
Related
I have a list as follows:-
List<ScheduleActionDispatchDTO> pendingScheduleActions
=restClientApi.getPendingSchedules();
The above list is coming from DB whose values are like this -
schedule_request_id = 576, user_id = 24,
start_time_utc = '2022-12-16 21:00:00', end_time_utc = '2022-12-17 01:00:00',
request_json = '{"testId": "5", "grade": "A"}'
schedule_request_id = 576, user_id = 24,
start_time_utc = '2022-12-16 21:00:00', end_time_utc = '2022-12-17 01:00:00',
request_json = '{"subjectId": "10", "name": "dictation"}'
schedule_request_id = 577, user_id = 24, start_time_utc = '2022-12-17 21:00:00',
end_time_utc = '2022-12-18 01:00:00', request_json = '{"testId": "5", "grade": "A"}'
Now I want the result to be such that if values of schedule_request_id, user_id, start_time_utc and end_time_utc of any rows are same then merge the values of request_json of those rows together.
So it should become -
schedule_request_id = 576, user_id = 24,
start_time_utc = '2022-12-16 21:00:00', end_time_utc = '2022-12-17 01:00:00',
combinedResult = '[{"testId": "5", "grade": "A"}, {"subjectId": "10", "name": "dictation"}]'
and
schedule_request_id = 577, user_id = 24, start_time_utc = '2022-12-17 21:00:00',
end_time_utc = '2022-12-18 01:00:00', combinedResult = '{"testId": "5", "grade": "A"}'
I tried this -
Map<Long, List<ScheduleActionDispatchDTO>> requestMap = pendingScheduleActions.stream()
.collect(Collectors.groupingBy(
ScheduleActionDispatchDTO::getScheduleRequestId, Collectors.toList()));
for (Map.Entry<Long, List<ScheduleActionDispatchDTO>> entry : requestMap.entrySet()) {
List<ScheduleActionDispatchDTO> sameRequestActions = entry.getValue();
Map<ScheduleActionDispatchPair, ScheduleActionDispatchDTO> schedulePairAction =
sameRequestActions.stream().
collect(Collectors.toMap(
s -> new ScheduleActionDispatchPair(s.getScheduleRequestId(), s.getUserUd(), s.getStartTimeUtc(), s.getEndTimeUtc()),
s -> s));
// iterate and combine but not sure how
}
Well, you could do the following. I assumed you have a record1 of the following form:
public record PendingScheduleAction(
long scheduleRequestId,
int userId,
LocalDateTime startTimeUtc,
LocalDateTime endTimeUtc,
String requestJson
) { }
We could first create a Merger, which is used as grouping-by key. We add an ofPendingScheduleAction method, which is a convenience method to ease the grouping-by. We also add a merge method, which is able to merge two PendingScheduleAction objects.
record Merger(long scheduleRequestId, int userId, LocalDateTime startTimeUtc, LocalDateTime endTimeUtc) {
public static Merger ofPendingScheduleAction(PendingScheduleAction action) {
return new Merger(action.scheduleRequestId(), action.userId(), action.startTimeUtc(), action.endTimeUtc());
}
private static PendingScheduleAction merge(PendingScheduleAction a, PendingScheduleAction b) {
String json = a.requestJson() + '\0' + b.requestJson();
return new PendingScheduleAction(a.scheduleRequestId(), a.userId(), a.startTimeUtc(), a.endTimeUtc(), json);
}
}
Now you can utilize groupingBy, reducing and collectingAndThen in order to achieve the desired result:
list.stream()
.collect(groupingBy(Merger::ofPendingScheduleAction, collectingAndThen(reducing(Merger::merge), optional -> {
var entry = optional.orElseThrow();
String[] jsonLines = entry.requestJson().split("\0");
String json = (jsonLines.length == 1 ? jsonLines[0] : "[" + String.join(",", jsonLines) + "]");
return new PendingScheduleAction(entry.scheduleRequestId(), entry.userId(), entry.startTimeUtc(), entry.endTimeUtc(), json);
})));
What happens here, is that we first define how our PendingScheduleAction instances are grouped. The Javadocs call this the classifier. Now you said "such that if values of schedule_request_id, user_id, start_time_utc and end_time_utc of any rows are same then merge", so we need to have those properties together into an object. The Merger class does this.
Then Collectors.reducing(Merger::merge) takes all objects of a group and merges them using the Merger::merge method. Since reducing returns an Optional, we need to unpack it (with orElseThrow), but we also need to fix the JSON, since we temporarily joined it with a NUL byte.
Then the result is a Map<Merger, PendingScheduleAction>, of which you can call values() to get a list with the merged values.
A few notes:
I used a NUL byte to temporarily separate different JSON parts (which is kinda hacky). This is due to your requirement that you want multiple merged JSON entries to be in a JSON array, but a single entry without an array. I suggest you put all JSON entries into an array, regardless of the number of entries (which may be 1). This is both easier to parse and easier to process.
You could replace all \0s by , in the abovementioned code and the finisher function of the collectingAndThen method would look like this:
var entry = optional.orElseThrow();
return new PendingScheduleAction(entry.scheduleRequestId(), entry.userId(), entry.startTimeUtc(), entry.endTimeUtc(), "[" + entry.requestJson() + "]");
Your start time and end time suggest they are UTC timestamps, but the date strings show a local time. I think your timestamps should look like something like this: 2022-12-16T21:00:00Z.
1 If you don't have access to the records feature, you could easily simulate them with the following:
public class PendingScheduleAction {
private long scheduleRequestId;
private int userId;
private LocalDateTime startTimeUtc;
private LocalDateTime endTimeUtc;
private String requestJson;
// Canonical all-args constructor
public PendingScheduleAction(long scheduleRequestId, int userId, LocalDateTime startTimeUtc, LocalDateTime endTimeUtc, String requestJson) {
this.scheduleRequestId = scheduleRequestId;
this.userId = userId;
this.startTimeUtc = startTimeUtc;
this.endTimeUtc = endTimeUtc;
this.requestJson = requestJson;
}
// Record-style getter (just the name of the field, not starting with 'get'
public long scheduleRequestId() {
return scheduleRequestId;
}
// And the remaining getters
public boolean equals(Object o) {
// A proper equals implementation.
// Don't forget hashCode()
}
}
You could also use Lombok to annotate the class with #AllArgsConstructor, #Getter and #EqualsAndHashCode.
I have below json:
{
"type":Flowers,
"input_data": [
{
"id": 35742,
"Request_ID": 8383,
"data_line": "*****Sample text here*****",
"variety": {
"Rose": 0,
"Jasmine": 0,
"Lily": 1,
"Sunflower": 1,
},
"responded": 1
},
{
"id": 35992,
"Request_ID": 8983,
"data_line": "*****Sample text here*****",
"variety": {
"Rose": 1,
"Jasmine": 0,
"Lily": 0,
"Sunflower": 1,
},
"responded": 1
}
],
"token": "F9500930C-15A6-4111-AD7F-7D0DF0CEE4D8"
}
How do I map the values in "variety" with "id"?
Note: id is coming from the response of a different API which should be replaced in this json and mapped with variety.
It's not a good idea to have a field like 'input_data' in your json.
Try to redo your json that's aligned to your data model and something that can be mapped to Java objects.
GSON is a great library for dealing with JSONs in Java - https://github.com/google/gson
I can give you a utility method to get a list of Java objects from a json reprenstation like this:
private static Type typeOfT = TypeToken.getParameterized(List.class, <<your-class>>.class).getType();
public static <T> List<T> loadListFromFile(String fileName, Class<T> clazz) throws Exception{
File file = new File(fileName);
String json = new String(Files.readAllBytes(file.toPath()));
return gson().fromJson(json, typeOfT);
}
First, your JSON string is invalid (e.g. Flowers should be quoted by double quotes). Second, I am confused about what you really want. Therefore, according to the comment under your question, you said that you need a mapping between id and variety. Here comes one way to achieve that by following steps with Jackson (One of the most popular JSON libraries.).
Step 1
Create nested POJOs for deserialization.
class Result {
#JsonProperty("input_data")
private List<InputData> inputData;
//general getter and setter
}
class InputData {
private int id;
private Variety variety;
//general getters and setters
}
class Variety {
#JsonProperty("Rose")
private int rose;
#JsonProperty("Jasmine")
private int jasmine;
#JsonProperty("Lily")
private int lily;
#JsonProperty("Sunflower")
private int sunflower;
//general getters, setters and toString()
}
Step 2
Deserialize JSON response to Result and transform the InputData into Map<Integer, Variety> with Java 8.
ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Result result = mapper.readValue(jsonStr, Result.class);
Map<Integer, Variety> idVarietyMap = result.getInputData().stream()
.collect(Collectors.toMap(InputData::getId, InputData::getVariety));
System.out.println(idVarietyMap.toString());
Console output
{35992=Variety [rose=1, jasmine=0, lily=0, sunflower=1], 35742=Variety [rose=0, jasmine=0, lily=1, sunflower=1]}
I need to perfom a select by date from my DB in my spring boot webapp. What I have so far is a list of sport competitions and there respective informations.
Problem : I can not figure out how my select query convert my String type (dateFrom = '2017-05-02' and dateTo = '2017-05-06') to date like '2017-02-12' in the ?
Alos how to fill my RowMapper with more then one date in some competition which have more then one date.
My data base schema:
CREATE TABLE competition (
competition_id integer PRIMARY KEY,
nom varchar(128) NOT NULL,
);
CREATE TABLE date (
id integer PRIMARY KEY,
date_time timestamptz,
competition_id integer REFERENCES competition (competition_id)
);
Json data:
{
"id": "420",
"name": "SOCCER",
"dates": [
"2016-05-12T03:00:00.000Z"
"2016-05-12T04:00:00.000Z"
"2016-05-12T05:00:00.000Z"
]
},
{
"id": "220",
"name": "BASKETBALL",
"dates": [
"2016-05-12T03:00:00.000Z"
"2016-05-12T04:00:00.000Z"
]
}
My competition Class:
public class Competition{
private int id;
private String name;
private String[] dates;
// setters ... getters
}
My RowMapper Class:
public class RowMapper implements RowMapper
{
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
Competition competition = new Competition();
competition.setId(rs.getInt("id"));
competition.setName(rs.getString("name"));
competition. // How to fill dates
return competition;
}
}
Function to select data :
private static final String SELECT_STMT =
" select * from competition INNER JOIN date ON
+ " competition.competition_id = date.competition_id"
+ " WHERE date(date.date_time) BETWEEN ? AND ?"
;
public List<Competition> findByOptionsAll(String dateFrom, String dateTo ){
List<Competition> competitions = jdbcTemplate.query(SELECT_STMT, new
RowMapper(), dateFrom, dateTo);
return competitions ;
}
Date converting
Right now you have all dates as a String both in your DB and domain model. To convert strings to date you need a date formatter:
private static final String DATE_FORMAT = "dd-MM-yy";
// parsing date; Note you should handle ParseException
java.util.Date date = new SimpleDateFormat(DATE_FORMAT).parse(dateAsString);
// converting date to string
String dateAsString = new SimpleDateFormat(DATE_FORMAT).format(date);
Note that SimpleDateFormat is not thread-safe so it's a good practice to have static final String DATE_FORMAT instead of static final DateFormatter
Converting date and time is tricky in some cases (what about time zone? java.util.Date vs joda.time vs LocalDate from Java 8) but out of scope. I suggest use LocalDate if possible just because it's a new way without old issues.
Mapping
You have two entities in your DB (Competition and Date-of-competition) and only one class Competition in your domain model. Most probably, later you'll want to add additional info to the Date-of-competition (boolean finished, cancelled, Score etc) so it's a good idea to create CompetitionInstance class right now.
Since you have One-to-Many relationship you have to write some additional stuff to map objects. Normally that's what an ORM like Hibernate do istead of you. First, add a 'GROUP BY competition_id' in your sql statement.
Then use RowSetExtractor instead of RowMapper as described here:
private static final class CompetitionMapExtractor implements ResultSetExtractor<List<Competition>> {
#Override
public List<Competition> extractData(ResultSet rs) throws SQLException {
List<Competition> result = new ArrayList<>(rs.getCount());
int previousCompetitionId = NEVER_EXIST; // normally -1 is good enough
while (rs.next()) {
// we have some dates with the same competition_id
// dates are grouped thanks to GROUP BY clause
if ( rs.getInt("id") != previousCompetitionId) {
Competition currentCompetition = new Competition(rs.getInt("id"),
rs.getString("name");
/* I prefer constructor initializers "o = new O(propertyValue)"
instead of snippet "o = new O(); o.setProperty(value)"
*/
result.add(currentCompetition);
previousCompetitionId = currentCompetition.getid();
} else {
currentCompetition.addDate(new CompetitionInstance(rs.getString("date")));
}
}
return result;
}
I suppose Competition has method public void addDate(String date) which simply add a new CompetitionInstance to a list.
Update:
1.
column name in DB and in MapExtractor is different. I prefer to change the query:
SELECT c.id, c.name, d.date_time as date
from competition c
INNER JOIN date d ON c.competition_id = d.competition_id
WHERE date(d.date_time) BETWEEN ? AND ?"
2. I can't reproduce issues you have with date. Most probably you mixed up java.util.Date, java.sql.Date and java.sql.Timestamp - this is a common mistake. There are many answers already, probably you could find one of them useful.
I created an app which pulls json data from an online web api and displays the text of that json data in textview. however, it shows as the raw json data - I would like to take out all the symbols and just display the text in a nice way.
What is this process called please?
Example of json string:
{
"Title": "Up",
"Year": "2009",
"Rated": "PG",
"Released": "29 May 2009",
"Runtime": "96 min",
"Genre": "Animation, Adventure, Comedy",
"Director": "Pete Docter, Bob Peterson",
"Writer": "Pete Docter (story), Bob Peterson (story), Tom McCarthy (story), Bob Peterson (screenplay), Pete Docter (screenplay)",
"Actors": "Edward Asner, Christopher Plummer, Jordan Nagai, Bob Peterson",
"Plot": "Seventy-eight year old Carl Fredricksen travels to Paradise Falls in his home equipped with balloons, inadvertently taking a young stowaway.",
"Language": "English",
"Country": "USA",
"Awards": "Won 2 Oscars. Another 69 wins & 69 nominations.",
"Poster": "http://ia.media-imdb.com/images/M/MV5BMTk3NDE2NzI4NF5BMl5BanBnXkFtZTgwNzE1MzEyMTE#._V1_SX300.jpg",
"Metascore": "88",
"imdbRating": "8.3",
"imdbVotes": "600,265",
"imdbID": "tt1049413",
"Type": "movie",
"Response": "True"
}
You need FastJson.
Step 0.
Import Fastjson into your project.
0.1 - Android Studio Gradle
compile 'com.alibaba:fastjson:1.2.7'
0.2 - Eclipse
Add library
http://repo1.maven.org/maven2/com/alibaba/fastjson/1.2.7/fastjson-1.2.7.jar
Step 1.
Creat Java Objects like
public class MyJsonBean {
private String Title;
private String Year;
private String Rated;
//...
public String getTitle() {
return Title;
}
public void setTitle(String title) {
Title = title;
}
public String getYear() {
return Year;
}
public void setYear(String year) {
Year = year;
}
public String getRated() {
return Rated;
}
public void setRated(String rated) {
Rated = rated;
}
//....
}
Step 2.
String jsonStr = "Your Json Str";
MyJsonBean myBean = JSON.parseObject(jsonStr, MyJsonBean.class);
System.out.println("Title = " + myBean.getTitle());
System.out.println("Year = " + myBean.getYear());
System.out.println("Rated = " + myBean.getRated());
Step 3.
You can use myBean.getName() to get value.
Then, it's done.
Ps. this website can help you create Java Objects
http://www.jsonschema2pojo.org/
Click Preview
You have to parse the Raw Json data into a String or you can user Gson libraries to convert Json object to Java Object.
If your Json is like
{
"text" : "value"
}
Then create a class
public class Text
{
public String text;
}
Then parse json using Gson object.
Gson gson = new Gson();
Text parsedText = gson.fromJson(jsonString,
Text.class);
Now set parsedText.text to your textview
Regards,
Sree
What you need is a JSON consumer, which this article covers (and provides source to): https://www.nabisoft.com/tutorials/java-ee/producing-and-consuming-json-or-xml-in-java-rest-services-with-jersey-and-jackson
A JSON consumer simply makes it easier for you to manage key:value pairs and (obviously) print them out. You direct the consumer to read the incoming data and it parses it into a handy object map for you to access.
This is even nicer in Groovy, but I know you wanted a pure Java solution.
you should parse your json string with this class JSONObject like this:
you have a string object jsonString with this content:{"Title":"Up","Year":"2009","Rated":"PG","Released":"29 May 2009","Runtime":"96 min","Genre":"Animation, Adventure, Comedy","Director":"Pete Docter, Bob Peterson","Writer":"Pete Docter (story), Bob Peterson (story), Tom McCarthy (story), Bob Peterson (screenplay), Pete Docter (screenplay)","Actors":"Edward Asner, Christopher Plummer, Jordan Nagai, Bob Peterson","Plot":"Seventy-eight year old Carl Fredricksen travels to Paradise Falls in his home equipped with balloons, inadvertently taking a young stowaway.","Language":"English","Country":"USA","Awards":"Won 2 Oscars. Another 69 wins & 69 nominations.","Metascore":"88","imdbRating":"8.3","imdbVotes":"600,265","imdbID":"tt1049413","Type":"movie","Response":"True"}
try {
//parse string
JSONObject jso = new JSONObject(jsonString);
//get data
String title = jso.getString("Title");
int year = jso.getInt("Year");
...
}catch(JSONException e) { e.printStackTrace(); }
You don't particularly need to create a custom class to parse the JSON using GSON.
You can pass it as a JsonObject and easily parse it from that.
Gson gson = new Gson();
JsonObject obj = gson.fromJson(JSON_DOCUMENT, JsonObject.class);
String title = obj.get("Title").getAsString();
String rated = obj.get("Rated").getAsString();
You can even grab JSON nested arrays and grab elements from them.
obj.get("SomeArray").getAsJsonArray();
Hope this helps :)
I'm coming to Java from JavaScript/Ruby. Let's say I've got the following JSON object for an animal:
{
name: {
common: "Tiger",
latin: "Panthera tigris"
}
legs: 4
}
I'm dealing with lots of animal APIs, and I want to normalize them all into my own common format, like:
{
common_name: "Tiger",
latin_name: "Panthera tigris",
limbs: {
legs: 4,
arms: 0
}
}
In, say, JavaScript, this would be straightforward:
normalizeAnimal = function(original){
return {
common_name: original.name.common,
latin_name: original.name.latin,
limbs: {
legs: original.legs || 0,
arms: original.arms || 0
}
}
}
But what about in Java? Using the JSONObject class from org.json, I could go down the road of doing something like this:
public JSONObject normalizeAnimal(JSONObject original) throws JSONException{
JSONObject name = original.getJSONObject("name");
JSONObject limbs = new JSONObject();
JSONObject normalized = new JSONObject();
normalized.put("name_name", name.get("common"));
normalized.put("latin_name", name.get("latin"));
try{
limbs.put("legs", original.get("legs");
}catch(e){
limbs.put("legs", 0);
};
try{
limbs.put("arms", original.get("arms");
}catch(e){
limbs.put("arms", 0);
};
normalized.put("limbs", limbs);
return normalized;
}
This gets worse as the JSON objects I'm dealing with get longer and deeper. In addition to all of this, I'm dealing with many providers for animal objects and I'll eventually be looking to have some succinct configuration format for describing the transformations (like, maybe, "common_name": "name.common", "limbs.legs": "legs").
How would I go about making this suck less in Java?
Use a library like Gson or Jackson and map the JSON to a Java Object.
So you're going to have a bean like
public class JsonAnima {
private JsonName name;
private int legs;
}
public class JsonName {
private String commonName;
private String latinName;
}
which can be easily converted with any library with something like (with Jackson)
ObjectMapper mapper = new ObjectMapper();
JsonAnimal animal = mapper.readValue(jsonString, JsonAnimal.class);
then you can create a "converter" to map the JsonAnimal to you Animal class.
This can be a way of doing it. : )
Some links:
Gson: http://code.google.com/p/google-gson/
Jackson: http://wiki.fasterxml.com/JacksonHome
The pure Java solutions all are challenged to deal with unreliable structure of your source data. If you're running in a JVM, I recommend that you consider using Groovy to do the Parse and the Build of your source JSON. The result ends up looking a lot like the Javascript solution you outlined above:
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
def originals = [
'{ "name": { "common": "Tiger", "latin": "Panthera tigris" }, "legs": 4 }',
'{ "name": { "common": "Gecko", "latin": "Gek-onero" }, "legs": 4, "arms": 0 }',
'{ "name": { "common": "Liger" }, "legs": 4, "wings": 2 }',
'{ "name": { "common": "Human", "latin": "Homo Sapien" }, "legs": 2, "arms": 2 }'
]
originals.each { orig ->
def slurper = new JsonSlurper()
def parsed = slurper.parseText( orig )
def builder = new JsonBuilder()
// This builder looks a lot like the Javascript solution, no?
builder {
common_name parsed.name.common
latin_name parsed.name.latin
limbs {
legs parsed.legs ?: 0
arms parsed.arms ?: 0
}
}
def normalized = builder.toString()
println "$normalized"
}
Running the script above deals with "jagged" JSON (not all elements have the same attributes) and outputs like...
{"common_name":"Tiger","latin_name":"Panthera tigris","limbs":{"legs":4,"arms":0}}
{"common_name":"Gecko","latin_name":"Gek-onero","limbs":{"legs":4,"arms":0}}
{"common_name":"Liger","latin_name":null,"limbs":{"legs":4,"arms":0}}
{"common_name":"Human","latin_name":"Homo Sapien","limbs":{"legs":2,"arms":2}}
If you'll be using this for many different types of objects, I would suggest to use reflection instead of serializing each object manually. By using reflection you will not need to create methods like normalizeAnimal, you just create one method or one class to do the serialization to json format.
If you search for "mapping json java" you'll find some useful references. Like gson. Here is an example that is on their website:
class BagOfPrimitives {
private int value1 = 1;
private String value2 = "abc";
private transient int value3 = 3;
BagOfPrimitives() {
// no-args constructor
}
}
//(Serialization)
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String json = gson.toJson(obj);
///==> json is {"value1":1,"value2":"abc"}
///Note that you can not serialize objects with circular references since that will result in infinite recursion.
//(Deserialization)
BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);
//==> obj2 is just like obj
You can try little jmom java library
JsonValue json = JsonParser.parse(stringvariablewithjsoninside);
Jmom mom = Jmom.instance()
.copy("/name/common", "/common_name", true)
.copy("/name/latin", "/latin_name", true)
.copy("/arms", "/limbs/arms", true)
.copy("/legs", "/limbs/legs", true)
.remove("/name")
;
mom.apply(json);
String str = json.toPrettyString(" ");