I am using Spring's RestTemplate to convert a JSON response from the RiotAPI into my BasicSummoner object. I believe the issue is with converting the JSON response into my object. After calling getForObject() all of the object's fields are null/empty. Any help is appreciated as this is my first Spring project and first time using Riot's API.
I have verified that the JSON resonse is correct and looks like this:
{
"riotschmick": {
"id": 585897,
"name": "RiotSchmick",
"profileIconId": 782,
"summonerLevel": 30,
"revisionDate": 1469155559000
}
}
My request looks like this:
public BasicSummoner requestBasicSummoner() {
RestTemplate template = new RestTemplate();
String mes = "https://na.api.pvp.net/api/lol/na/v1.4/summoner/by-name/RiotSchmick?api_key=<my-api-key>";
BasicSummoner summoner = template.getForObject(mes, BasicSummoner.class);
log.info(summoner.toString());
return summoner;
}
And the object BasicSummoner looks like this:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#JsonIgnoreProperties(ignoreUnknown = true)
public class BasicSummoner {
private long id;
private String name;
private int profileIconId;
private long revisionDate;
private long summonerLevel;
public BasicSummoner() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getProfileIconId() {
return profileIconId;
}
public void setProfileIconId(int profileIconId) {
this.profileIconId = profileIconId;
}
public long getRevisionDate() {
return revisionDate;
}
public void setRevisionDate(long revisionDate) {
this.revisionDate = revisionDate;
}
public long getSummonerLevel() {
return summonerLevel;
}
public void setSummonerLevel(long summonerLevel) {
this.summonerLevel = summonerLevel;
}
#Override
public String toString() {
return "id=" + id + ", name=" + name + " , summoner level=" + summonerLevel;
}
}
Your JSON is not a single Object, but an Object inside another Object.
This means that to use your code as it is now, you need to unwrap the inner Object, or change the structure to something else.
The response seems to fit a Map<String, BasicSummoner>
Related
I have a problem with returning an object in json format. This is my function to return a json object:
#GetMapping("/api/code/{n}")
#ResponseBody
public Code getCodeJson(#PathVariable int n) {
Code code = codeList.get(n - 1);
return code;
}
Objects of type Code are stored in a list, and I want to access them by the path variable n. The return looks like this:
{"id":1,"code":"{\"code\":\"hello world\"}","dateTime":"2021-10-05T16:49:31.911591"}
I don't know why this is happening, it should return a json that looks like this:
{"id":1,"code":"hello world","dateTime":"2021-10-05T16:49:31.911591"}
This is how I add code objects to the codeList
#PostMapping("/api/code/new")
#ResponseBody
public String addNewCode(#RequestBody String code) {
Code newCode = new Code(code);
codeList.add(newCode);
return "{\n" + "\"id\" : \"" + newCode.getId() + "\"\n}";
}
This is Code.java class
public class Code {
private static int currentId = 1;
private int id;
private String code;
private LocalDateTime dateTime;
public Code(String code) {
this.id = currentId;
this.code = code;
this.dateTime = LocalDateTime.now();
currentId++;
}
public int getId() {
return id;
}
public String getCode() {
return code;
}
public LocalDateTime getDateTime() {
return dateTime;
}
public void setCode(String code) {
this.code = code;
this.dateTime = LocalDateTime.now();
}
}
You can update the addNewCode to accept Code or new DTO CodeDto as the request body instead and use that instead. As of now you are getting the entire request body as string and assigning it to the code causing the current response.
#PostMapping("/api/code/new")
#ResponseBody
public String addNewCode(#RequestBody CodeDto code) {
Code newCode = new Code(code.getCode());
codeList.add(newCode);
return "{\n" + "\"id\" : \"" + newCode.getId() + "\"\n}";
}
As you are passing {"code":"hello world"} as request body the above code will automatically deserialize it properly into an instance of CodeDto object with code attribute set to "hello world".
public class CodeDto {
private String code;
public CodeDto(String code) {
this.code = code;
}
public CodeDto() {}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
I am trying to use Jackson to parse sample json as demonstrated below. However, I the parsing doesn't work (fails without any exceptions - as I get an empty string for event.getAccountId(); What could I be doing wrong?
Thanks!
ObjectMapper om = new ObjectMapper();
String json = "{\"_procurementEvent\" : [{ \"accountId\" : \"3243234\",\"procurementType\" : \"view\"," +
"\"_procurementSubType\" : \"Standard Connector\",\"_quantity\" : \"4\", \"_pricePerMonth\" : \"100.00\"" +
",\"_annualPrice\" : \"1200.00\"}]}";
ProcurementEvent event = om.readValue(json, ProcurementEvent.class);
event.getAccountId(); // returns null
#JsonIgnoreProperties(ignoreUnknown = true)
private static class ProcurementEvent {
private String _accountId;
private String _procurementType;
private String _quantity;
private String _pricePerMonth;
private String _annualPrice;
#JsonProperty("accountId")
public String getAccountId() {
return _accountId;
}
public void setAccountId(String accountId) {
_accountId = accountId;
}
#JsonProperty("procurementType")
public String getProcurementType() {
return _procurementType;
}
public void setProcurementType(String procurementType) {
_procurementType = procurementType;
}
#JsonProperty("_quantity")
public String getQuantity() {
return _quantity;
}
public void setQuantity(String quantity) {
_quantity = quantity;
}
#JsonProperty("_pricePerMonth")
public String getPricePerMonth() {
return _pricePerMonth;
}
public void setPricePerMonth(String pricePerMonth) {
_pricePerMonth = pricePerMonth;
}
#JsonProperty("_annualPrice")
public String getAnnualPrice() {
return _annualPrice;
}
public void setAnnualPrice(String annualPrice) {
_annualPrice = annualPrice;
}
}
In the question, try the following approach:
class ProcurementEvents {
private List<ProcurementEvent> _procurementEvent; // + annotations like #JsonIgnoreProperties, getters/ setters, etc.
}
// json from your example
ProcurementEvents events = om.readValue(json, ProcurementEvents.class);
events.get(0).getAccountId();
I want to link my received json data to my pojo class using gson library.I used volley library to receive the data.What should i do so that whenever i call getter methods from my pojo class then i get the received json data.
My Json data is in this format.
{
"vichList":[ {
id=1,
username="abc....},
{....},
]
}
I want to get this json data into my pojo class.
Vich.java
public class GetfeedResponse {
private List<Vich> vichList;
public List<Vich> getVichList() {
return vichList;
}
public void setVichList(List<Vich> vichList) {
this.vichList = vichList;
}
}
Vich.java
public class Vich {
private int id;
private String username;
private String full_name;
private String createdAt;
private int vich_id;
private String vich_content;
private String city;
private int like_count;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getFull_name() {
return full_name;
}
public void setFull_name(String full_name) {
this.full_name = full_name;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public int getVich_id() {
return vich_id;
}
public void setVich_id(int vich_id) {
this.vich_id = vich_id;
}
public String getVich_content() {
return vich_content;
}
public void setVich_content(String vich_content) {
this.vich_content = vich_content;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public int getLike_count() {
return like_count;
}
public void setLike_count(int like_count) {
this.like_count = like_count;
}
}
Here i am getting the json response using volley library.
httpUtil.getrequest(url,this,new VolleyCallback(){
#Override
public void onSuccess(String result){
GetfeedResponse getfeedResponse = new GetfeedResponse();
// for(Vich vich : getfeedResponse.getVichList()){
// }
Log.d("Response Result:",result);
}
How can i get objects from json array and use them with the help of pojo class?
Using Gson
Add the following dependency in your gradle:
implementation 'com.google.code.gson:gson:2.8.5'
In your onSuccess()
GetfeedResponse getfeedResponse=new Gson().fromJson(result, GetfeedResponse.class);
If you wish to use Volley and POJO its better to use custom GSON request. Check this link : Custom GSON request With Volley
GSON:
GetfeedResponse parsed = new Gson().fromJson(response, GetfeedResponse.class);
Jackson:
GetfeedResponse parsed = new ObjectMapper().readValue(response, GetfeedResponse.class);
Additionally, if you wanted to convert only list of Vich items (and you stripped your JSON accordingly) you could do following:
[ {
id=1,
username="abc....},
{....},
]
List<Vich> viches = Arrays.asList(new Gson().fromJson(vichItemsJson, Vich[].class));
I am having a very tough time deserializing json in java with gson.
I have the following json:
{"races":[
{"id":1,"mask":1,"side":"alliance","name":"Human"},
{"id":2,"mask":2,"side":"horde","name":"Orc"},
{"id":3,"mask":4,"side":"alliance","name":"Dwarf"}]}
The java code I have now is:
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Gson gson = new Gson();
Type type = new TypeToken<List<WoWDetails>>(){}.getType();
List<WoWRaces> races = gson.fromJson(response, type);
for (WoWRaces race : races){
if(raceID.equals(race.id)) {
raceName = race.name;
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
errorMSG = (TextView) findViewById(R.id. textView5);
errorMSG.setText("That didn't work! URL: \n"+error);
errorMSG.setVisibility(View.VISIBLE);
}
});
In WoWRaces.java is the following code:
WoWRaces.java
public class WoWRaces {
public Integer id;
public String name;
}
It's giving me the following error:
Expected BEGIN_ARRAY but was BEGIN_OBJECT
I have searched and visited multiple questions but I can't seem to figure this out. The data that I would need is the id and the name bound to it.
Thank you in advance
If you are using gson library then try this
Gson gson = new Gson();
MainResponse mainResponse = gson.fromJson(response, MainResponse.class);
List<Race> races = mainResponse.getRaces();
for (Race race : races) {
Log.e("TEST","Race id : " + race.getId());
Log.e("TEST","Race Name : " + race.getName());
}
MainResponse.java
public class MainResponse {
#SerializedName("races")
#Expose
private List<Race> races = null;
public List<Race> getRaces() {
return races;
}
public void setRaces(List<Race> races) {
this.races = races;
}
}
Race.java
public class Race {
#SerializedName("id")
#Expose
private int id;
#SerializedName("mask")
#Expose
private int mask;
#SerializedName("side")
#Expose
private String side;
#SerializedName("name")
#Expose
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getMask() {
return mask;
}
public void setMask(int mask) {
this.mask = mask;
}
public String getSide() {
return side;
}
public void setSide(String side) {
this.side = side;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
1. Create RacesResponse class as:
public class RacesResponse {
#SerializedName("races")
public List<WowRaces> list;
}
2. Change your code to:
RacesResponse racesResponse = gson.fromJson(response, RacesResponse.class);
List<WowRaces> races = racesResponse.list;
you can put your json string here and copy all classes in your app and use main class to in the new Gson.fromJson(jsonString,Example.class)
in the url select this option
Source type:Json
Annotation style:Gson
I have a json
[
{
"host": {
"name": "anotherfullhost",
"id": 55602819,
"operatingsystem_id": 1073012828,
"hostgroup_id": null
}
},
{
"host": {
"name": "dhcp.mydomain.net",
"id": 219245707,
"operatingsystem_id": 1073012828,
"hostgroup_id": null
}
},
{
"host": {
"name": "my5name.mydomain.net",
"id": 980190962,
"operatingsystem_id": 1073012828,
"hostgroup_id": null
}
}
]
I would like to construct a Collection by deserializing the above json. What jackson annotations should I add to the below Host class
public class Host {
#JsonProperty("id")
private Long id;
#JsonProperty("name")
private String name;
#JsonProperty("operatingsystem_id")
private Long operatingSystemId;
#JsonProperty("hostgroup_id")
private Long hostGroupId;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getOperatingSystemId() {
return operatingSystemId;
}
public void setOperatingSystemId(Long operatingSystemId) {
this.operatingSystemId = operatingSystemId;
}
public Long getHostGroupId() {
return hostGroupId;
}
public void setHostGroupId(Long hostGroupId) {
this.hostGroupId = hostGroupId;
}
#Override
public String toString() {
return "Host{" +
"name='" + name + '\'' +
'}';
}
}
Any suggestions?
Note - I am using jackson 2.x API.
Thanks.
Update
Adding a wrapper object does the trick.
public class HostWrapper {
#JsonProperty("host")
private Host host;
public Host getHost() {
return host;
}
public void setHost(Host host) {
this.host = host;
}
#Override
public String toString() {
return host.toString();
}
}
and the below code to deserialize
ObjectMapper mapper = new ObjectMapper();
HostWrapper[] host = mapper.readValue(jsonString, HostWrapper[].class);
Please see this post - This should be the same issue than yours, even if a different API is used:
JsonMappingException: Current token not START_OBJECT (needed to unwrap root name 'Transaction[]'), but START_ARRAY