I want to create one API which format will be like below.
{
"jsonObject": {
//some json object
},
"key": "SampleKey",
"jsonDataKey": "SampleDataKey"
}
for this I have created the RequestBody class as below.
public class ParentJsonInfo {
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
private String key;
public JsonObject getJsonData() {
return jsonData;
}
public void setJsonData(JsonObject jsonData) {
this.jsonData = jsonData;
}
private JsonObject jsonData;
public String getJsonDataKey() {
return jsonDataKey;
}
public void setJsonDataKey(String jsonDataKey) {
this.jsonDataKey = jsonDataKey;
}
private String jsonDataKey;
}
but unfortunately I am not getting any data inside the json object of my class. M I doing anything wrong. please guide me to how should i access the data inside that object.
Here is the controller method code.
#RequestMapping(value = "/postNews", method = RequestMethod.POST)
public Greeting greeting(#RequestBody ParentJsonInfo parentJsonInfo) {
Jsonobject jsonObject= parentJsonInfo.getjsonObject();
}
The problem you are having is that you are trying to deserialize jsonObject which is from your json, but your field is called jsonData.
As #Mushtu mentioned, you need to rename that field.
Here is your ParentJsonInfo with a few adjustments:
moving the fields to the top (it is a good practice to group fields and methods separately)
renamed your field from jsonData to jsonObject
ParentJsonInfo:
public class ParentJsonInfo {
private String key;
private JsonObject jsonObject;
private String jsonDataKey;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public JsonObject getJsonObject() {
return jsonObject;
}
public void setJsonObject(JsonObject jsonObject) {
this.jsonObject = jsonObject;
}
public String getJsonDataKey() {
return jsonDataKey;
}
public void setJsonDataKey(String jsonDataKey) {
this.jsonDataKey = jsonDataKey;
}
}
JsonObject:
public class JsonObject {
private Map<String, Object> other = new HashMap<>();
#JsonAnyGetter
public Map<String, Object> getProperties() {
return other;
}
#JsonAnySetter
public void set(String name, String value) {
other.put(name, value);
}
}
u can modify like this
public Greeting greeting(#RequestBody String parentJsonInfo) {
// parse string to jsonobject
}
Related
I want to get the country details from an external api and using Gson to set the data received from the get request to class Country. The problem is that in the response, the currencies key has value which is between [](please see below) and in some cases there is a space between the currencies name values which causes the following error
com.google.gson.stream.MalformedJsonException: Unterminated object at line 1 column 41 path $.currencies[0].name:
"currencies":[{"code":"BGN","name":"Bulgarian lev","symbol":"лв"}]
#RestController
public class CountryController {
#Autowired
private RestTemplate restTemplate;
private static String baseURL = "https://restcountries.com/v2/";
public Object[] getCountryDetails(String countryName){
Object[] countryDetails = restTemplate.getForObject(baseURL+"name/"+countryName+"?fields=name,alpha2Code,alpha3Code,capital,currencies", Object[].class);
return countryDetails;
}
public Country createCountryObject(String countryName) {
String response = Arrays.asList(getCountryDetails(countryName)).get(0).toString();
Gson g = new Gson();
JsonReader reader = new JsonReader(new StringReader(response.trim()));
reader.setLenient(true);
Country country = g.fromJson(reader, Country.class);
return country;
}
#GetMapping("/")
public String getAll(){
Country country = createCountryObject("bulgaria");
return country.getName();
}
}
Country.java:
package country.neighbours.tour.models;
import java.util.List;
public class Country {
private String name;
private String alpha2Code;
private String alpha3Code;
private List<String> borders;
private Object[] currencies;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getBorders() {
return borders;
}
public void setBorders(List<String> borders) {
this.borders = borders;
}
public String getAlpha2Code() {
return alpha2Code;
}
public void setAlpha2Code(String alpha2Code) {
this.alpha2Code = alpha2Code;
}
public String getAlpha3Code() {
return alpha3Code;
}
public void setAlpha3Code(String alpha3Code) {
this.alpha3Code = alpha3Code;
}
public Object[] getCurrencies() {
return currencies;
}
public void setCurrencies(Object[] currencies) {
this.currencies = currencies;
}
}
How can I get only the currency code?
It looks like you are parsing the response twice; once with restTemplate.getForObject, then you convert its result to a String (the result of your toString() call is most likely not JSON) and then you try to parse it a second time with Gson.
In case you only want to use Gson, you can use a TypeToken in the fromJson call to parse the response JSON array:
List<Country> countries = gson.fromJson(..., new TypeToken<List<Country>>() {}.getType());
Maybe someone more familiar with Spring can also explain how to use only RestTemplate.getForObject for this instead of Gson.
The json structure is the following:
{
"key":"Key",
"value":{
"first": "first",
"second": "second"
}
}
I want using Spring Boot get this json as Plain Old Java Object.
public class File {
private String key;
private JsonObject value;
public File(String key, JsonObject value) {
this.key = key;
this.value = value;
}
public File() {
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public JsonObject getValue() {
return value;
}
public void setValue(JsonObject value) {
this.value = value;
}
}
JsonObject - the class from lib com.google.gson
I am getting {}
It would be perfect to get field "value" as String but JsonObject is okay too.
Done! It's possible with com.google.json lib using setter:
public class File {
private String key;
private String value;
public File() {
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(Object value) {
this.value = new Gson().toJson(value);
}
}
I'm new to GSON and have been having trouble parsing the JSON below. The parsing works fine until it gets to the list of bills (staring at "0":). At that point I get a null reference in the resulting gson.fromJson object. If those bills were specified in a JSON array I think it would be easy, but they're not and I can't change that. What is the best way to handle this situation?
{
"status":"OK",
"masterlist":{
"session":{
"session_id":1007,
"session_name":"97th Legislature"
},
"0":{
"bill_id":446875,
"number":"HB4001"
},
"1":{
"bill_id":446858,
"number":"HB4002"
},
"2":{
"bill_id":446842,
"number":"HB4003"
},...
This is the code in my main method:
InputStream source = retrieveStream(url);
Gson gson = new Gson();
Reader reader = new InputStreamReader(source);
ResponseData response = gson.fromJson(reader, ResponseData.class);
And this is the ResponseData class:
public class ResponseData {
private String status;
private MasterList masterlist;
public static class MasterList{
private Session session;
private Bill bill; //Also tried: Map<String, String> bill;
}
public static class Session{
private String session_id;
private String session_name;
}
public static class Bill{
private String bill_id;
private String number;
}
}
You can map the object as below:
declare an object to map with json string
public class ResponseData {
private String status;
private Map<String, MasterList> masterlist;
public Map<String, MasterList> getMasterlist() {
return masterlist;
}
public void setMasterlist(Map<String, MasterList> masterlist) {
this.masterlist = masterlist;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public static class MasterList {
private String session_id;
private String session_name;
private String bill_id;
private String number;
public String getSession_id() {
return session_id;
}
public void setSession_id(String session_id) {
this.session_id = session_id;
}
public String getSession_name() {
return session_name;
}
public void setSession_name(String session_name) {
this.session_name = session_name;
}
public String getBill_id() {
return bill_id;
}
public void setBill_id(String bill_id) {
this.bill_id = bill_id;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
}
And use it as below:
String data = "{\"status\":\"OK\",\"masterlist\":{ \"session\":{ \"session_id\":1007, \"session_name\":\"97th Legislature\" }, \"0\":{ \"bill_id\":446875, \"number\":\"HB4001\" }, \"1\":{ \"bill_id\":446858, \"number\":\"HB4002\" }, \"2\":{ \"bill_id\":446842, \"number\":\"HB4003\" }}}";
Gson gson = new Gson();
ResponseData response = gson.fromJson(data, ResponseData.class);
for (Iterator<Entry<String, MasterList>> it = response.getMasterlist().entrySet().iterator(); it.hasNext(); ) {
Map.Entry<String, MasterList> entry = it.next();
System.out.println(entry.getKey());
System.out.println(entry.getValue().getSession_id());
}
I'm being given a Json file with the form:
{
"descriptions": {
"desc1": "someString",
"desc2": {"name":"someName", "val": 7.0}
}
}
I have the POJO:
public class CustomClass {
Map<String, Object> descriptions;
public static class NameVal{
String name;
double val;
public NameVal(String name, double val){...}
}
}
I can recreate the json file with the code:
CustomClass a = new CustomClass();
a.descriptions = new HashMap<String, Object>();
a.descriptions.put("desc1", "someString");
a.descriptions.put("desc2", new CustomClass.NameVal("someName", 7.0));
new ObjectMapper().writeValue(new File("testfile"), a);
But, when I read the object back in using:
CustomClass fromFile = new ObjectMapper().readValue(new File("testfile"), CustomClass.class);
then fromFile.descriptions.get("desc2") is of type LinkedHashMap instead of type CustomClass.NameVal.
How can I get Jackson to properly parse the type of the CustomClass.NameVal descriptors (other than making some class that wraps the parsing and explicitly converts the LinkedHashMap after Jackson reads the file)?
Try this. Create a class Description with name and value attributes:
public class Description {
private String name;
private double val;
}
Now in your CustomClass do this:
public class CustomClass {
List<Description> descriptions;
}
And that's it. Remember to create getters and setters because Jackson needs it.
You could try something like this:
public class DescriptionWrapper {
private Description descriptions;
public Description getDescriptions() {
return descriptions;
}
public void setDescriptions(Description descriptions) {
this.descriptions = descriptions;
}
}
public class Description {
private String desc1;
private NameValue desc2;
public String getDesc1() {
return desc1;
}
public void setDesc1(String desc1) {
this.desc1 = desc1;
}
public NameValue getDesc2() {
return desc2;
}
public void setDesc2(NameValue desc2) {
this.desc2 = desc2;
}
}
public class NameValue {
private String name;
private double val;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getVal() {
return val;
}
public void setVal(double val) {
this.val = val;
}
}
I'm trying to figure out how to use gson to convert reddit's api response to a form I can use. After some code I use
System.out.println(response.toString());
to get output (slightly edited)
{"json": {"errors": [], "data": {"modhash": "dosiom5o6abbbb758729039f04762a05778db4aeeeacd8eb4a", "cookie": "14756159,2012-08-21T12:05:05,0971bdec35d71af4073cf56ad82fb0ae7c5fe2d1"}}}
After googling around I built the following class
class GSONClass {
private Response jsonresponse;
public Response getJsonresponse() {
return jsonresponse;
}
public void setJsonresponse(Response jsonresponse) {
this.jsonresponse = jsonresponse;
}
public static class Response {
private String[] errors;
private Data data;
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public String[] getErrors() {
return errors;
}
public void setErrors(String[] errors) {
this.errors = errors;
}
}
public static class Data {
private String modhash = "hi";
private String cookie;
public String getCookie() {
return cookie;
}
public void setCookie(String cookie) {
this.cookie = cookie;
}
public String getModhash() {
return modhash;
}
public void setModhash(String modhash) {
this.modhash = modhash;
}
}
}
Then I use:
GSONClass target = new GSONClass();
String json = gson.toJson(response.toString());
GSONClass target = gson.fromJson(json, GSONClass.class);
I'm doing something wrong because I get a "java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING" error.
You were close. Your object needed to have an attribute named json that contained both an array(errors) and an object named data that contained properties modhash and cookie. The property you were calling jsonResponse needed to be called json.
public class GSONClass {
private Response json;
public static class Response {
private String[] errors;
private Data data;
}
public static class Data {
private String modhash = "hi";
private String cookie;
}
}
And a stub/runner.
import com.google.gson.Gson;
public class Main {
public static void main(String[] args) {
String response = "{\"json\": {\"errors\": [], \"data\": {\"modhash\": \"dosiom5o6abbbb758729039f04762a05778db4aeeeacd8eb4a\", \"cookie\": \"14756159,2012-08-21T12:05:05,0971bdec35d71af4073cf56ad82fb0ae7c5fe2d1\"}}}";
GSONClass target = new Gson().fromJson(response, GSONClass.class);
System.out.println(target);
}
}