I am trying to call a Spring Cloud Data Flow REST Endpoint which is supposed to return a list of all the executions of a task whose name is passed in the input.
For starters, I ran the following URL in the browser :
http://dataflow-server.myhost.net/tasks/executions?task1225
The following JSON is shown on the browser :
{
"_embedded": {
"taskExecutionResourceList": [
{
"executionId": 2908,
"exitCode": 0,
"taskName": "task1225",
"startTime": "2021-06-25T18:40:24.823+0000",
"endTime": "2021-06-25T18:40:27.585+0000",
"exitMessage": null,
"arguments": [
"--spring.datasource.username=******",
"--spring.cloud.task.name=task1225",
"--spring.datasource.url=******",
"--spring.datasource.driverClassName=org.h2.Driver",
"key=******",
"batchId=20210625_025755702",
"--spring.cloud.data.flow.platformname=default",
"--spring.cloud.task.executionid=2908"
],
"jobExecutionIds": [],
"errorMessage": null,
"externalExecutionId": "task1225-kp7mvwkmll",
"parentExecutionId": null,
"resourceUrl": "Docker Resource [docker:internal.artifactrepository.myhost.net/myProject/myimage:0.1]",
"appProperties": {
"spring.datasource.username": "******",
"spring.cloud.task.name": "task1225",
"spring.datasource.url": "******",
"spring.datasource.driverClassName": "org.h2.Driver"
},
"deploymentProperties": {
"spring.cloud.deployer.kubernetes.requests.memory": "512Mi",
"spring.cloud.deployer.kubernetes.limits.cpu": "1000m",
"spring.cloud.deployer.kubernetes.limits.memory": "8192Mi",
"spring.cloud.deployer.kubernetes.requests.cpu": "100m"
},
"taskExecutionStatus": "COMPLETE",
"_links": {
"self": {
"href": "http://dataflow-server.myhost.net/tasks/executions/2908"
}
}
}
]
},
"_links": {
"first": {
"href": "http://dataflow-server.myhost.net/tasks/executions?page=0&size=20"
},
"self": {
"href": "http://dataflow-server.myhost.net/tasks/executions?page=0&size=20"
},
"next": {
"href": "http://dataflow-server.myhost.net/tasks/executions?page=1&size=20"
},
"last": {
"href": "http://dataflow-server.myhost.net/tasks/executions?page=145&size=20"
}
},
"page": {
"size": 20,
"totalElements": 2908,
"totalPages": 146,
"number": 0
}
}
Next, I tried to call the same REST endpoint through Java; however, no matter what I try, the response object seems to be empty with none of the attributes populated :
Approach 1 : Custom domain classes created to deserialize the response. (Did not work. Empty content recieved in response)
ParameterizedTypeReference<Resources<TaskExecutions>> ptr = new ParameterizedTypeReference<Resources<TaskExecutions>>() {
};
ResponseEntity<Resources<TaskExecutions>> entity = restTemplate.exchange(
"http://dataflow-server.myhost.net/tasks/executions?task1225",
HttpMethod.GET, null, ptr);
System.out.println(entity.getBody().getContent()); **//empty content**
Where, TaskExecutions domain is as follows :
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({ "taskExecutionResourceList" })
#JsonIgnoreProperties(ignoreUnknown = true)
public class TaskExecutions {
public TaskExecutions() {
}
#JsonProperty("taskExecutionResourceList")
List<TaskExecutionResource> taskExecutionResourceList = new ArrayList<>();
#JsonProperty("taskExecutionResourceList")
public List<TaskExecutionResource> getTaskExecutionResourceList() {
return taskExecutionResourceList;
}
#JsonProperty("taskExecutionResourceList")
public void setTaskExecutionResourceList(List<TaskExecutionResource> taskExecutionResourceList) {
this.taskExecutionResourceList = taskExecutionResourceList;
}
}
And TaskExecutionResource is as follows :
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"executionId",
"exitCode",
"taskName",
"startTime",
"endTime",
"exitMessage",
"arguments",
"jobExecutionIds",
"errorMessage",
"externalExecutionId",
"parentExecutionId",
"resourceUrl",
"appProperties",
"deploymentProperties",
"taskExecutionStatus",
"_links" })
#JsonIgnoreProperties(ignoreUnknown = true)
public class TaskExecutionResource {
#JsonProperty("executionId")
private Integer executionId;
#JsonProperty("exitCode")
private Integer exitCode;
#JsonProperty("taskName")
private String taskName;
#JsonProperty("startTime")
private String startTime;
#JsonProperty("endTime")
private String endTime;
#JsonProperty("exitMessage")
private Object exitMessage;
#JsonProperty("arguments")
private List<String> arguments = new ArrayList<String>();
#JsonProperty("jobExecutionIds")
private List<Object> jobExecutionIds = new ArrayList<Object>();
#JsonProperty("errorMessage")
private Object errorMessage;
#JsonProperty("externalExecutionId")
private String externalExecutionId;
#JsonProperty("parentExecutionId")
private Object parentExecutionId;
#JsonProperty("resourceUrl")
private String resourceUrl;
#JsonProperty("appProperties")
private AppProperties appProperties;
#JsonProperty("deploymentProperties")
private DeploymentProperties deploymentProperties;
#JsonProperty("taskExecutionStatus")
private String taskExecutionStatus;
#JsonProperty("_links")
private Links links;
#JsonProperty("executionId")
public Integer getExecutionId() {
return executionId;
}
#JsonProperty("executionId")
public void setExecutionId(Integer executionId) {
this.executionId = executionId;
}
#JsonProperty("exitCode")
public Integer getExitCode() {
return exitCode;
}
#JsonProperty("exitCode")
public void setExitCode(Integer exitCode) {
this.exitCode = exitCode;
}
#JsonProperty("taskName")
public String getTaskName() {
return taskName;
}
#JsonProperty("taskName")
public void setTaskName(String taskName) {
this.taskName = taskName;
}
#JsonProperty("startTime")
public String getStartTime() {
return startTime;
}
#JsonProperty("startTime")
public void setStartTime(String startTime) {
this.startTime = startTime;
}
#JsonProperty("endTime")
public String getEndTime() {
return endTime;
}
#JsonProperty("endTime")
public void setEndTime(String endTime) {
this.endTime = endTime;
}
#JsonProperty("exitMessage")
public Object getExitMessage() {
return exitMessage;
}
#JsonProperty("exitMessage")
public void setExitMessage(Object exitMessage) {
this.exitMessage = exitMessage;
}
#JsonProperty("arguments")
public List<String> getArguments() {
return arguments;
}
#JsonProperty("arguments")
public void setArguments(List<String> arguments) {
this.arguments = arguments;
}
#JsonProperty("jobExecutionIds")
public List<Object> getJobExecutionIds() {
return jobExecutionIds;
}
#JsonProperty("jobExecutionIds")
public void setJobExecutionIds(List<Object> jobExecutionIds) {
this.jobExecutionIds = jobExecutionIds;
}
#JsonProperty("errorMessage")
public Object getErrorMessage() {
return errorMessage;
}
#JsonProperty("errorMessage")
public void setErrorMessage(Object errorMessage) {
this.errorMessage = errorMessage;
}
#JsonProperty("externalExecutionId")
public String getExternalExecutionId() {
return externalExecutionId;
}
#JsonProperty("externalExecutionId")
public void setExternalExecutionId(String externalExecutionId) {
this.externalExecutionId = externalExecutionId;
}
#JsonProperty("parentExecutionId")
public Object getParentExecutionId() {
return parentExecutionId;
}
#JsonProperty("parentExecutionId")
public void setParentExecutionId(Object parentExecutionId) {
this.parentExecutionId = parentExecutionId;
}
#JsonProperty("resourceUrl")
public String getResourceUrl() {
return resourceUrl;
}
#JsonProperty("resourceUrl")
public void setResourceUrl(String resourceUrl) {
this.resourceUrl = resourceUrl;
}
#JsonProperty("appProperties")
public AppProperties getAppProperties() {
return appProperties;
}
#JsonProperty("appProperties")
public void setAppProperties(AppProperties appProperties) {
this.appProperties = appProperties;
}
#JsonProperty("deploymentProperties")
public DeploymentProperties getDeploymentProperties() {
return deploymentProperties;
}
#JsonProperty("deploymentProperties")
public void setDeploymentProperties(DeploymentProperties deploymentProperties) {
this.deploymentProperties = deploymentProperties;
}
#JsonProperty("taskExecutionStatus")
public String getTaskExecutionStatus() {
return taskExecutionStatus;
}
#JsonProperty("taskExecutionStatus")
public void setTaskExecutionStatus(String taskExecutionStatus) {
this.taskExecutionStatus = taskExecutionStatus;
}
#JsonProperty("_links")
public Links getLinks() {
return links;
}
#JsonProperty("_links")
public void setLinks(Links links) {
this.links = links;
}
}
Approach 2 : Add spring-cloud-data-flow-rest as a maven dependency in my project and use the TaskExectuionResource entity defined in this project. :
TaskExecutionResource.Page = restTemplate.getForObject("http://dataflow-server.myhost.net/tasks/executions?task1225",
TaskExecutionResource.Page.class);//**Empty content**
Question : How can I deserialize the response of the JSON returned by a rest enndpoint that is using HATEOAS? It seems like a very daunting task to get this to work.
Not sure how you constructed RestTemplate but it doesn't work as is with hateoas and there's some additional steps you need to do.
To get idea what we've done see ObjectMapper config. There's hal module and additional mixin's what mapper needs to be aware of for these things to work.
I am getting list of coins from API https://min-api.cryptocompare.com/data/all/coinlist?api-key.
It returns json response like this -
{
"Response": "Success",
"Message": "Coin list succesfully returned!",
"Data": {
"42": {
"Id": "4321",
"Url": "/coins/42/overview",
"ImageUrl": "/media/35650717/42.jpg",
"ContentCreatedOn": 1427211129,
"Name": "42",
"Symbol": "42",
"CoinName": "42 Coin",
"FullName": "42 Coin (42)",
"Algorithm": "Scrypt",
"ProofType": "PoW/PoS",
"FullyPremined": "0",
"TotalCoinSupply": "42",
"BuiltOn": "N/A",
"SmartContractAddress": "N/A",
"DecimalPlaces": 0,
"PreMinedValue": "N/A",
"TotalCoinsFreeFloat": "N/A",
"SortOrder": "34",
"Sponsored": false,
"Taxonomy": {
"Access": "",
"FCA": "",
"FINMA": "",
"Industry": "",
"CollateralizedAsset": "",
"CollateralizedAssetType": "",
"CollateralType": "",
"CollateralInfo": ""
},
"Rating": {
"Weiss": {
"Rating": "",
"TechnologyAdoptionRating": "",
"MarketPerformanceRating": ""
}
},
"IsTrading": true,
"TotalCoinsMined": 41.9999528,
"BlockNumber": 173122,
"NetHashesPerSecond": 0,
"BlockReward": 0,
"BlockTime": 0
},
"300": {
"Id": "749869",
"Url": "/coins/300/overview",
"ImageUrl": "/media/27010595/300.png",
"ContentCreatedOn": 1517935016,
"Name": "300",
"Symbol": "300",
"CoinName": "300 token",
"FullName": "300 token (300)",
"Algorithm": "N/A",
"ProofType": "N/A",
"FullyPremined": "0",
"TotalCoinSupply": "300",
"BuiltOn": "7605",
"SmartContractAddress": "0xaec98a708810414878c3bcdf46aad31ded4a4557",
"DecimalPlaces": 18,
"PreMinedValue": "N/A",
"TotalCoinsFreeFloat": "N/A",
"SortOrder": "2212",
"Sponsored": false,
"Taxonomy": {
"Access": "",
"FCA": "",
"FINMA": "",
"Industry": "",
"CollateralizedAsset": "",
"CollateralizedAssetType": "",
"CollateralType": "",
"CollateralInfo": ""
},
"Rating": {
"Weiss": {
"Rating": "",
"TechnologyAdoptionRating": "",
"MarketPerformanceRating": ""
}
},
"IsTrading": true,
"TotalCoinsMined": 300,
"BlockNumber": 0,
"NetHashesPerSecond": 0,
"BlockReward": 0,
"BlockTime": 0
}
}
}
When I am generating pojo class for it, it is creating class _42 as well as class _300 means for every object it is creating new class.
Here it is :-
package com.mountblue.cryptocoin.entity;
import com.google.gson.annotations.SerializedName;
public class CoinBean {
/**
* Response : Success
* Message : Coin list succesfully returned!
* Data : {"42":{"Id":"4321","Url":"/coins/42/overview","ImageUrl":"/media/35650717/42.jpg","ContentCreatedOn":1427211129,"Name":"42","Symbol":"42","CoinName":"42 Coin","FullName":"42 Coin (42)","Algorithm":"Scrypt","ProofType":"PoW/PoS","FullyPremined":"0","TotalCoinSupply":"42","BuiltOn":"N/A","SmartContractAddress":"N/A","DecimalPlaces":0,"PreMinedValue":"N/A","TotalCoinsFreeFloat":"N/A","SortOrder":"34","Sponsored":false,"Taxonomy":{"Access":"","FCA":"","FINMA":"","Industry":"","CollateralizedAsset":"","CollateralizedAssetType":"","CollateralType":"","CollateralInfo":""},"Rating":{"Weiss":{"Rating":"","TechnologyAdoptionRating":"","MarketPerformanceRating":""}},"IsTrading":true,"TotalCoinsMined":41.9999528,"BlockNumber":173122,"NetHashesPerSecond":0,"BlockReward":0,"BlockTime":0},"300":{"Id":"749869","Url":"/coins/300/overview","ImageUrl":"/media/27010595/300.png","ContentCreatedOn":1517935016,"Name":"300","Symbol":"300","CoinName":"300 token","FullName":"300 token (300)","Algorithm":"N/A","ProofType":"N/A","FullyPremined":"0","TotalCoinSupply":"300","BuiltOn":"7605","SmartContractAddress":"0xaec98a708810414878c3bcdf46aad31ded4a4557","DecimalPlaces":18,"PreMinedValue":"N/A","TotalCoinsFreeFloat":"N/A","SortOrder":"2212","Sponsored":false,"Taxonomy":{"Access":"","FCA":"","FINMA":"","Industry":"","CollateralizedAsset":"","CollateralizedAssetType":"","CollateralType":"","CollateralInfo":""},"Rating":{"Weiss":{"Rating":"","TechnologyAdoptionRating":"","MarketPerformanceRating":""}},"IsTrading":true,"TotalCoinsMined":300,"BlockNumber":0,"NetHashesPerSecond":0,"BlockReward":0,"BlockTime":0}}
*/
private String Response;
private String Message;
private DataBean Data;
public String getResponse() {
return Response;
}
public void setResponse(String Response) {
this.Response = Response;
}
public String getMessage() {
return Message;
}
public void setMessage(String Message) {
this.Message = Message;
}
public DataBean getData() {
return Data;
}
public void setData(DataBean Data) {
this.Data = Data;
}
public static class DataBean {
/**
* 42 : {"Id":"4321","Url":"/coins/42/overview","ImageUrl":"/media/35650717/42.jpg","ContentCreatedOn":1427211129,"Name":"42","Symbol":"42","CoinName":"42 Coin","FullName":"42 Coin (42)","Algorithm":"Scrypt","ProofType":"PoW/PoS","FullyPremined":"0","TotalCoinSupply":"42","BuiltOn":"N/A","SmartContractAddress":"N/A","DecimalPlaces":0,"PreMinedValue":"N/A","TotalCoinsFreeFloat":"N/A","SortOrder":"34","Sponsored":false,"Taxonomy":{"Access":"","FCA":"","FINMA":"","Industry":"","CollateralizedAsset":"","CollateralizedAssetType":"","CollateralType":"","CollateralInfo":""},"Rating":{"Weiss":{"Rating":"","TechnologyAdoptionRating":"","MarketPerformanceRating":""}},"IsTrading":true,"TotalCoinsMined":41.9999528,"BlockNumber":173122,"NetHashesPerSecond":0,"BlockReward":0,"BlockTime":0}
* 300 : {"Id":"749869","Url":"/coins/300/overview","ImageUrl":"/media/27010595/300.png","ContentCreatedOn":1517935016,"Name":"300","Symbol":"300","CoinName":"300 token","FullName":"300 token (300)","Algorithm":"N/A","ProofType":"N/A","FullyPremined":"0","TotalCoinSupply":"300","BuiltOn":"7605","SmartContractAddress":"0xaec98a708810414878c3bcdf46aad31ded4a4557","DecimalPlaces":18,"PreMinedValue":"N/A","TotalCoinsFreeFloat":"N/A","SortOrder":"2212","Sponsored":false,"Taxonomy":{"Access":"","FCA":"","FINMA":"","Industry":"","CollateralizedAsset":"","CollateralizedAssetType":"","CollateralType":"","CollateralInfo":""},"Rating":{"Weiss":{"Rating":"","TechnologyAdoptionRating":"","MarketPerformanceRating":""}},"IsTrading":true,"TotalCoinsMined":300,"BlockNumber":0,"NetHashesPerSecond":0,"BlockReward":0,"BlockTime":0}
*/
#SerializedName("42")
private _$42Bean _$42;
#SerializedName("300")
private _$300Bean _$300;
public _$42Bean get_$42() {
return _$42;
}
public void set_$42(_$42Bean _$42) {
this._$42 = _$42;
}
public _$300Bean get_$300() {
return _$300;
}
public void set_$300(_$300Bean _$300) {
this._$300 = _$300;
}
public static class _$42Bean {
/**
* Id : 4321
* Url : /coins/42/overview
* ImageUrl : /media/35650717/42.jpg
* ContentCreatedOn : 1427211129
* Name : 42
* Symbol : 42
* CoinName : 42 Coin
* FullName : 42 Coin (42)
* Algorithm : Scrypt
* ProofType : PoW/PoS
* FullyPremined : 0
* TotalCoinSupply : 42
* BuiltOn : N/A
* SmartContractAddress : N/A
* DecimalPlaces : 0
* PreMinedValue : N/A
* TotalCoinsFreeFloat : N/A
* SortOrder : 34
* Sponsored : false
* Taxonomy : {"Access":"","FCA":"","FINMA":"","Industry":"","CollateralizedAsset":"","CollateralizedAssetType":"","CollateralType":"","CollateralInfo":""}
* Rating : {"Weiss":{"Rating":"","TechnologyAdoptionRating":"","MarketPerformanceRating":""}}
* IsTrading : true
* TotalCoinsMined : 41.9999528
* BlockNumber : 173122
* NetHashesPerSecond : 0
* BlockReward : 0
* BlockTime : 0
*/
private String Id;
private String Url;
private String ImageUrl;
private int ContentCreatedOn;
private String Name;
private String Symbol;
private String CoinName;
private String FullName;
private String Algorithm;
private String ProofType;
private String FullyPremined;
private String TotalCoinSupply;
private String BuiltOn;
private String SmartContractAddress;
private int DecimalPlaces;
private String PreMinedValue;
private String TotalCoinsFreeFloat;
private String SortOrder;
private boolean Sponsored;
private TaxonomyBean Taxonomy;
private RatingBean Rating;
private boolean IsTrading;
private double TotalCoinsMined;
private int BlockNumber;
private int NetHashesPerSecond;
private int BlockReward;
private int BlockTime;
public String getId() {
return Id;
}
public void setId(String Id) {
this.Id = Id;
}
public String getUrl() {
return Url;
}
public void setUrl(String Url) {
this.Url = Url;
}
public String getImageUrl() {
return ImageUrl;
}
public void setImageUrl(String ImageUrl) {
this.ImageUrl = ImageUrl;
}
public int getContentCreatedOn() {
return ContentCreatedOn;
}
public void setContentCreatedOn(int ContentCreatedOn) {
this.ContentCreatedOn = ContentCreatedOn;
}
public String getName() {
return Name;
}
public void setName(String Name) {
this.Name = Name;
}
public String getSymbol() {
return Symbol;
}
public void setSymbol(String Symbol) {
this.Symbol = Symbol;
}
public String getCoinName() {
return CoinName;
}
public void setCoinName(String CoinName) {
this.CoinName = CoinName;
}
public String getFullName() {
return FullName;
}
public void setFullName(String FullName) {
this.FullName = FullName;
}
public String getAlgorithm() {
return Algorithm;
}
public void setAlgorithm(String Algorithm) {
this.Algorithm = Algorithm;
}
public String getProofType() {
return ProofType;
}
public void setProofType(String ProofType) {
this.ProofType = ProofType;
}
public String getFullyPremined() {
return FullyPremined;
}
public void setFullyPremined(String FullyPremined) {
this.FullyPremined = FullyPremined;
}
public String getTotalCoinSupply() {
return TotalCoinSupply;
}
public void setTotalCoinSupply(String TotalCoinSupply) {
this.TotalCoinSupply = TotalCoinSupply;
}
public String getBuiltOn() {
return BuiltOn;
}
public void setBuiltOn(String BuiltOn) {
this.BuiltOn = BuiltOn;
}
public String getSmartContractAddress() {
return SmartContractAddress;
}
public void setSmartContractAddress(String SmartContractAddress) {
this.SmartContractAddress = SmartContractAddress;
}
public int getDecimalPlaces() {
return DecimalPlaces;
}
public void setDecimalPlaces(int DecimalPlaces) {
this.DecimalPlaces = DecimalPlaces;
}
public String getPreMinedValue() {
return PreMinedValue;
}
public void setPreMinedValue(String PreMinedValue) {
this.PreMinedValue = PreMinedValue;
}
public String getTotalCoinsFreeFloat() {
return TotalCoinsFreeFloat;
}
public void setTotalCoinsFreeFloat(String TotalCoinsFreeFloat) {
this.TotalCoinsFreeFloat = TotalCoinsFreeFloat;
}
public String getSortOrder() {
return SortOrder;
}
public void setSortOrder(String SortOrder) {
this.SortOrder = SortOrder;
}
public boolean isSponsored() {
return Sponsored;
}
public void setSponsored(boolean Sponsored) {
this.Sponsored = Sponsored;
}
public TaxonomyBean getTaxonomy() {
return Taxonomy;
}
public void setTaxonomy(TaxonomyBean Taxonomy) {
this.Taxonomy = Taxonomy;
}
public RatingBean getRating() {
return Rating;
}
public void setRating(RatingBean Rating) {
this.Rating = Rating;
}
public boolean isIsTrading() {
return IsTrading;
}
public void setIsTrading(boolean IsTrading) {
this.IsTrading = IsTrading;
}
public double getTotalCoinsMined() {
return TotalCoinsMined;
}
public void setTotalCoinsMined(double TotalCoinsMined) {
this.TotalCoinsMined = TotalCoinsMined;
}
public int getBlockNumber() {
return BlockNumber;
}
public void setBlockNumber(int BlockNumber) {
this.BlockNumber = BlockNumber;
}
public int getNetHashesPerSecond() {
return NetHashesPerSecond;
}
public void setNetHashesPerSecond(int NetHashesPerSecond) {
this.NetHashesPerSecond = NetHashesPerSecond;
}
public int getBlockReward() {
return BlockReward;
}
public void setBlockReward(int BlockReward) {
this.BlockReward = BlockReward;
}
public int getBlockTime() {
return BlockTime;
}
public void setBlockTime(int BlockTime) {
this.BlockTime = BlockTime;
}
public static class TaxonomyBean {
/**
* Access :
* FCA :
* FINMA :
* Industry :
* CollateralizedAsset :
* CollateralizedAssetType :
* CollateralType :
* CollateralInfo :
*/
private String Access;
private String FCA;
private String FINMA;
private String Industry;
private String CollateralizedAsset;
private String CollateralizedAssetType;
private String CollateralType;
private String CollateralInfo;
public String getAccess() {
return Access;
}
public void setAccess(String Access) {
this.Access = Access;
}
public String getFCA() {
return FCA;
}
public void setFCA(String FCA) {
this.FCA = FCA;
}
public String getFINMA() {
return FINMA;
}
public void setFINMA(String FINMA) {
this.FINMA = FINMA;
}
public String getIndustry() {
return Industry;
}
public void setIndustry(String Industry) {
this.Industry = Industry;
}
public String getCollateralizedAsset() {
return CollateralizedAsset;
}
public void setCollateralizedAsset(String CollateralizedAsset) {
this.CollateralizedAsset = CollateralizedAsset;
}
public String getCollateralizedAssetType() {
return CollateralizedAssetType;
}
public void setCollateralizedAssetType(String CollateralizedAssetType) {
this.CollateralizedAssetType = CollateralizedAssetType;
}
public String getCollateralType() {
return CollateralType;
}
public void setCollateralType(String CollateralType) {
this.CollateralType = CollateralType;
}
public String getCollateralInfo() {
return CollateralInfo;
}
public void setCollateralInfo(String CollateralInfo) {
this.CollateralInfo = CollateralInfo;
}
}
public static class RatingBean {
/**
* Weiss : {"Rating":"","TechnologyAdoptionRating":"","MarketPerformanceRating":""}
*/
private WeissBean Weiss;
public WeissBean getWeiss() {
return Weiss;
}
public void setWeiss(WeissBean Weiss) {
this.Weiss = Weiss;
}
public static class WeissBean {
/**
* Rating :
* TechnologyAdoptionRating :
* MarketPerformanceRating :
*/
private String Rating;
private String TechnologyAdoptionRating;
private String MarketPerformanceRating;
public String getRating() {
return Rating;
}
public void setRating(String Rating) {
this.Rating = Rating;
}
public String getTechnologyAdoptionRating() {
return TechnologyAdoptionRating;
}
public void setTechnologyAdoptionRating(String TechnologyAdoptionRating) {
this.TechnologyAdoptionRating = TechnologyAdoptionRating;
}
public String getMarketPerformanceRating() {
return MarketPerformanceRating;
}
public void setMarketPerformanceRating(String MarketPerformanceRating) {
this.MarketPerformanceRating = MarketPerformanceRating;
}
}
}
}
public static class _$300Bean {
/**
* Id : 749869
* Url : /coins/300/overview
* ImageUrl : /media/27010595/300.png
* ContentCreatedOn : 1517935016
* Name : 300
* Symbol : 300
* CoinName : 300 token
* FullName : 300 token (300)
* Algorithm : N/A
* ProofType : N/A
* FullyPremined : 0
* TotalCoinSupply : 300
* BuiltOn : 7605
* SmartContractAddress : 0xaec98a708810414878c3bcdf46aad31ded4a4557
* DecimalPlaces : 18
* PreMinedValue : N/A
* TotalCoinsFreeFloat : N/A
* SortOrder : 2212
* Sponsored : false
* Taxonomy : {"Access":"","FCA":"","FINMA":"","Industry":"","CollateralizedAsset":"","CollateralizedAssetType":"","CollateralType":"","CollateralInfo":""}
* Rating : {"Weiss":{"Rating":"","TechnologyAdoptionRating":"","MarketPerformanceRating":""}}
* IsTrading : true
* TotalCoinsMined : 300
* BlockNumber : 0
* NetHashesPerSecond : 0
* BlockReward : 0
* BlockTime : 0
*/
private String Id;
private String Url;
private String ImageUrl;
private int ContentCreatedOn;
private String Name;
private String Symbol;
private String CoinName;
private String FullName;
private String Algorithm;
private String ProofType;
private String FullyPremined;
private String TotalCoinSupply;
private String BuiltOn;
private String SmartContractAddress;
private int DecimalPlaces;
private String PreMinedValue;
private String TotalCoinsFreeFloat;
private String SortOrder;
private boolean Sponsored;
private TaxonomyBeanX Taxonomy;
private RatingBeanX Rating;
private boolean IsTrading;
private int TotalCoinsMined;
private int BlockNumber;
private int NetHashesPerSecond;
private int BlockReward;
private int BlockTime;
public String getId() {
return Id;
}
public void setId(String Id) {
this.Id = Id;
}
public String getUrl() {
return Url;
}
public void setUrl(String Url) {
this.Url = Url;
}
public String getImageUrl() {
return ImageUrl;
}
public void setImageUrl(String ImageUrl) {
this.ImageUrl = ImageUrl;
}
public int getContentCreatedOn() {
return ContentCreatedOn;
}
public void setContentCreatedOn(int ContentCreatedOn) {
this.ContentCreatedOn = ContentCreatedOn;
}
public String getName() {
return Name;
}
public void setName(String Name) {
this.Name = Name;
}
public String getSymbol() {
return Symbol;
}
public void setSymbol(String Symbol) {
this.Symbol = Symbol;
}
public String getCoinName() {
return CoinName;
}
public void setCoinName(String CoinName) {
this.CoinName = CoinName;
}
public String getFullName() {
return FullName;
}
public void setFullName(String FullName) {
this.FullName = FullName;
}
public String getAlgorithm() {
return Algorithm;
}
public void setAlgorithm(String Algorithm) {
this.Algorithm = Algorithm;
}
public String getProofType() {
return ProofType;
}
public void setProofType(String ProofType) {
this.ProofType = ProofType;
}
public String getFullyPremined() {
return FullyPremined;
}
public void setFullyPremined(String FullyPremined) {
this.FullyPremined = FullyPremined;
}
public String getTotalCoinSupply() {
return TotalCoinSupply;
}
public void setTotalCoinSupply(String TotalCoinSupply) {
this.TotalCoinSupply = TotalCoinSupply;
}
public String getBuiltOn() {
return BuiltOn;
}
public void setBuiltOn(String BuiltOn) {
this.BuiltOn = BuiltOn;
}
public String getSmartContractAddress() {
return SmartContractAddress;
}
public void setSmartContractAddress(String SmartContractAddress) {
this.SmartContractAddress = SmartContractAddress;
}
public int getDecimalPlaces() {
return DecimalPlaces;
}
public void setDecimalPlaces(int DecimalPlaces) {
this.DecimalPlaces = DecimalPlaces;
}
public String getPreMinedValue() {
return PreMinedValue;
}
public void setPreMinedValue(String PreMinedValue) {
this.PreMinedValue = PreMinedValue;
}
public String getTotalCoinsFreeFloat() {
return TotalCoinsFreeFloat;
}
public void setTotalCoinsFreeFloat(String TotalCoinsFreeFloat) {
this.TotalCoinsFreeFloat = TotalCoinsFreeFloat;
}
public String getSortOrder() {
return SortOrder;
}
public void setSortOrder(String SortOrder) {
this.SortOrder = SortOrder;
}
public boolean isSponsored() {
return Sponsored;
}
public void setSponsored(boolean Sponsored) {
this.Sponsored = Sponsored;
}
public TaxonomyBeanX getTaxonomy() {
return Taxonomy;
}
public void setTaxonomy(TaxonomyBeanX Taxonomy) {
this.Taxonomy = Taxonomy;
}
public RatingBeanX getRating() {
return Rating;
}
public void setRating(RatingBeanX Rating) {
this.Rating = Rating;
}
public boolean isIsTrading() {
return IsTrading;
}
public void setIsTrading(boolean IsTrading) {
this.IsTrading = IsTrading;
}
public int getTotalCoinsMined() {
return TotalCoinsMined;
}
public void setTotalCoinsMined(int TotalCoinsMined) {
this.TotalCoinsMined = TotalCoinsMined;
}
public int getBlockNumber() {
return BlockNumber;
}
public void setBlockNumber(int BlockNumber) {
this.BlockNumber = BlockNumber;
}
public int getNetHashesPerSecond() {
return NetHashesPerSecond;
}
public void setNetHashesPerSecond(int NetHashesPerSecond) {
this.NetHashesPerSecond = NetHashesPerSecond;
}
public int getBlockReward() {
return BlockReward;
}
public void setBlockReward(int BlockReward) {
this.BlockReward = BlockReward;
}
public int getBlockTime() {
return BlockTime;
}
public void setBlockTime(int BlockTime) {
this.BlockTime = BlockTime;
}
......//
}
}
}
I want json to be in Array response. How can I do this?
ApiService class looks like -
#GET("/data/all/coinlist")
Call<CoinBean> getCurrencyList(
#Query("api_key") String apiKey
);
u can create below class structure to de serialize at ur side.
Class Data {
List<Map<String, ImageInfo>> body = new ArrayList()
}
I've tried to set values inside movies ArrayList in BlogRepository class.
but I couldn't find the results in the end.
I want to modify the example so that the storage inside the ArrayList is movies.
so the example works and the results show then the example works.
json data :
[
{
"albumId": 1,
"id": 1,
"title": "accusamus beatae ad facilis cum similique qui sunt",
"url": "https://via.placeholder.com/600/92c952",
"thumbnailUrl": "https://via.placeholder.com/150/92c952"
},
{
"albumId": 1,
"id": 2,
"title": "reprehenderit est deserunt velit ipsam",
"url": "https://via.placeholder.com/600/771796",
"thumbnailUrl": "https://via.placeholder.com/150/771796"
},
{
"albumId": 1,
"id": 3,
"title": "officia porro iure quia iusto qui ipsa ut modi",
"url": "https://via.placeholder.com/600/24f355",
"thumbnailUrl": "https://via.placeholder.com/150/24f355"
}
]
Code:
//
public class BlogRepository {
private ArrayList<Blog2> movies = new ArrayList<>();
private MutableLiveData<List<Blog2>> mutableLiveData = new MutableLiveData<>();
private Application application;
public BlogRepository(Application application){
this.application = application;
}
public MutableLiveData<List<Blog2>> getMutableLiveData() {
RestApiService service = RetrofitInstance.getApiService();
Call<List<BlogWrapper>> call = service.getPopularBlog();
call.enqueue(new Callback<List<BlogWrapper>>(){
#Override
public void onResponse(Call<List<BlogWrapper>> call, Response<List<BlogWrapper>> response) {
List<BlogWrapper> mBlogWrapper = response.body();
for (int i=0; i<mBlogWrapper.size(); i++) {
movies = (ArrayList<Blog2>) mBlogWrapper.get(i).getBlog();
//Log.d("trace_movies : ",""+ movies);
}
}
#Override
public void onFailure(Call<List<BlogWrapper>> call, Throwable t) {
// Toast.makeText(MainActivity.this, "Unable to load users", Toast.LENGTH_SHORT).show();
Log.e("trace_2",""+t.getMessage().toString());
}
});
return mutableLiveData;
}
}
//
public class Blog2 {
#SerializedName("albumId")
private int albumId;
#SerializedName("id")
private int id;
#SerializedName("title")
private String title;
#SerializedName("url")
private String url;
#SerializedName("thumbnailUrl")
private String thumbnailUrl;
public void setAlbumId(int albumId) {
this.albumId = albumId;
}
public void setId(int id) {
this.id = id;
}
public void setTitle(String title) {
this.title = title;
}
public void setUrl(String url) {
this.url = url;
}
public void setThumbnailUrl(String thumbnailUrl) {
this.thumbnailUrl = thumbnailUrl;
}
public int getAlbumId() {
return albumId;
}
public int getId() {
return id;
}
public String getTitle() {
return title;
}
public String getUrl() {
return url;
}
public String getThumbnailUrl() {
return thumbnailUrl;
}
}
///
public class BlogWrapper {
#SerializedName("data")
private List<Blog2> mData;
#SerializedName("error")
private Boolean mError;
#SerializedName("message")
private String mMessage;
#SerializedName("status")
private String mStatus;
public List<Blog2>getBlog() {
return mData;
}
public void setBlog(List<Blog2> data) {
mData = data;
}
public Boolean getError() {
return mError;
}
public void setError(Boolean error) {
mError = error;
}
public String getMessage() {
return mMessage;
}
public void setMessage(String message) {
mMessage = message;
}
public String getStatus() {
return mStatus;
}
public void setStatus(String status) {
mStatus = status;
}
}
///
public interface RestApiService {
#GET("/photos")
public Call<List<BlogWrapper>> getPopularBlog();
}
//
public class RetrofitInstance {
private static Retrofit retrofit = null;
public static final String BASE_URL_ = "https://jsonplaceholder.typicode.com/albums/1/";
// public static final String BASE_URL_ = "https://androidwave.com/api/";
public static RestApiService getApiService() {
Gson gson = new GsonBuilder().setLenient().create();
if (retrofit == null) {
retrofit = new retrofit2.Retrofit
.Builder()
.baseUrl(BASE_URL_)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
return retrofit.create(RestApiService.class);
}
}
Try this code, sorry i am away from laptop... mybe you can understand from this. I just swich response object as List<Blog2>, because you need it
call.enqueue(new Callback<List<Blog2>>(){
#Override
public void onResponse(Call<List<Blog2>> call, Response<List<Blog2>> response) {
List<Blog2> mBlogWrapper = response.body();
for (int i=0; i<mBlogWrapper.size(); i++) {
movies.add(mBlogWrapper.get(i));
//Log.d("trace_movies : ",""+ movies);
}
}
});
now you have values from the List, then you can store its value to MutableLivedata.
Also don't forget to change your Retrofit method
public interface RestApiService {
#GET("/photos")
public Call<List<Blog2>> getPopularBlog();
}
I'm trying to write an API class to send requests and handle responses from an API. Parts of the API have requests that require JSON bodies attached to the request such as this sample:
{
"Title": "string",
"Status": "string",
"ActFinish": "Date",
"ActHrs": "float",
"ActStart": "Date",
"ActualResults": "string",
"AssigneeUserId": "int",
"CustomFields": [
{
"Id": "string",
"Name": "string",
"Value": "string"
}
],
"Description": "string",
"EstFinish": "Date",
"EstHrs": "float",
"EstHrsRemaining": "float",
"EstStart": "Date",
"ExpectedResults": "string",
"FolderId": "int",
"FunctionalAreaCode": "string",
"HowFoundCode": "string",
"IssueCode": "string",
"ModuleCode": "string",
"PctComplete": "int",
"PriorityCode": "string",
"Resolution": "string",
"ResolutionCode": "string",
"SeverityCode": "string",
"SoftwareVersionCode": "string",
"StepsToRepro": "string"
}
The best way to do this I found through reading the Rest Assured documentation is with POJOs mentioned here: https://github.com/rest-assured/rest-assured/wiki/Usage#serialization
My POJO looks like this:
public class RequestDefectPost {
public String title;
public String status;
public Timestamp actFinish;
public float actHours;
public Timestamp actStart;
public String actualResults;
public int assigneeUserId;
public String[] customFields;
public String id;
public String name;
public String value;
public String description;
public Timestamp estFinish;
public float estHours;
public float estHrsRemaining;
public Timestamp estStart;
public String expectedResults;
public int folderId;
public String functionalAreaCode;
public String howFoundCode;
public String issueCode;
public String moduleCode;
public int pctComplete;
public String priorityCode;
public String resolutionCode;
public String severityCode;
public String softwareVersionCode;
public String stepsToRepro;
public RequestDefectPost(String title, String status) {
this.title = title;
this.status = status;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Timestamp getActFinish() {
return actFinish;
}
public void setActFinish(Timestamp actFinish) {
this.actFinish = actFinish;
}
public float getActHours() {
return actHours;
}
public void setActHours(float actHours) {
this.actHours = actHours;
}
public Timestamp getActStart() {
return actStart;
}
public void setActStart(Timestamp actStart) {
this.actStart = actStart;
}
public String getActualResults() {
return actualResults;
}
public void setActualResults(String actualResults) {
this.actualResults = actualResults;
}
public int getAssigneeUserId() {
return assigneeUserId;
}
public void setAssigneeUserId(int assigneeUserId) {
this.assigneeUserId = assigneeUserId;
}
public String[] getCustomFields() {
return customFields;
}
public void setCustomFields(String id, String name, String value) {
this.customFields = new String[]{this.id = id, this.name = name, this.value = value};
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Timestamp getEstFinish() {
return estFinish;
}
public void setEstFinish(Timestamp estFinish) {
this.estFinish = estFinish;
}
public float getEstHours() {
return estHours;
}
public void setEstHours(float estHours) {
this.estHours = estHours;
}
public float getEstHrsRemaining() {
return estHrsRemaining;
}
public void setEstHrsRemaining(float estHrsRemaining) {
this.estHrsRemaining = estHrsRemaining;
}
public Timestamp getEstStart() {
return estStart;
}
public void setEstStart(Timestamp estStart) {
this.estStart = estStart;
}
public String getExpectedResults() {
return expectedResults;
}
public void setExpectedResults(String expectedResults) {
this.expectedResults = expectedResults;
}
public int getFolderId() {
return folderId;
}
public void setFolderId(int folderId) {
this.folderId = folderId;
}
public String getFunctionalAreaCode() {
return functionalAreaCode;
}
public void setFunctionalAreaCode(String functionalAreaCode) {
this.functionalAreaCode = functionalAreaCode;
}
public String getHowFoundCode() {
return howFoundCode;
}
public void setHowFoundCode(String howFoundCode) {
this.howFoundCode = howFoundCode;
}
public String getIssueCode() {
return issueCode;
}
public void setIssueCode(String issueCode) {
this.issueCode = issueCode;
}
public String getModuleCode() {
return moduleCode;
}
public void setModuleCode(String moduleCode) {
this.moduleCode = moduleCode;
}
public int getPctComplete() {
return pctComplete;
}
public void setPctComplete(int pctComplete) {
this.pctComplete = pctComplete;
}
public String getPriorityCode() {
return priorityCode;
}
public void setPriorityCode(String priorityCode) {
this.priorityCode = priorityCode;
}
public String getResolutionCode() {
return resolutionCode;
}
public void setResolutionCode(String resolutionCode) {
this.resolutionCode = resolutionCode;
}
public String getSeverityCode() {
return severityCode;
}
public void setSeverityCode(String severityCode) {
this.severityCode = severityCode;
}
public String getSoftwareVersionCode() {
return softwareVersionCode;
}
public void setSoftwareVersionCode(String softwareVersionCode) {
this.softwareVersionCode = softwareVersionCode;
}
public String getStepsToRepro() {
return stepsToRepro;
}
public void setStepsToRepro(String stepsToRepro) {
this.stepsToRepro = stepsToRepro;
}
}
With my current POJO, the JSON being spit out by Rest Assured looks like this:
{
"title": "Test",
"status": "New",
"actFinish": null,
"actHours": 0.0,
"actStart": null,
"actualResults": null,
"assigneeUserId": 0,
"customFields": [
"Test",
"test",
"tesT"
],
"id": "Test",
"name": "test",
"value": "tesT",
"description": null,
"estFinish": null,
"estHours": 0.0,
"estHrsRemaining": 0.0,
"estStart": null,
"expectedResults": null,
"folderId": 0,
"functionalAreaCode": null,
"howFoundCode": null,
"issueCode": null,
"moduleCode": null,
"pctComplete": 0,
"priorityCode": null,
"resolutionCode": null,
"severityCode": null,
"softwareVersionCode": null,
"stepsToRepro": null
}
My question is how do I write the the customFields such that it is nested correctly, as outlined in the sample JSON?
You need another POJO that represents a "CustomFields". For example:
public class CustomFields {
private String Id;
private String Name;
private String Value;
<getters and setters>
}
and use List<CustomFields> CustomFields instead of String[] customFields. Also note that your JSON example doesn't use camel case for the property names so your POJO shouldn't use camel case either.
There are ways to avoid using a POJO at all in REST Assured. You can for example use a HashMap instead which could be easier in some situations.
I am creating this json string from the server as shown below and I was able to parse the string too. But when creating the json some fields like errormessage,createdDate,priority are null values. I dont want to show them in the string how can I do that?
Json Strin
{
"errormessage": null,
"createdDate": null,
"list": [{
"type": "app1",
"alternateId": "AlternateID",
"priority": null,
"description": "app for desc",
}],
"locationName": null,
"facilityManagerName": null,
"codeName": null,
"sourceKey": null,
"tablename": null,
"path": "list",
"service": "listserver",
"license": null,
"key": null,
}
expected String
{
"list": [{
"type": "app1",
"alternateId": "AlternateID",
"description": "app for desc",
}],
"path": "list",
"service": "listserver",
}
Generic Java Bean For creating the json:
public class AppObject<T> implements Serializable {
private String errormessage;
private Date createdDate;
private List<T> list;
private String locationName;
private String facilityManagerName;
private String codeName;
private Long sourceKey;
private String tablename;
private String path;
private String service;
private String license;
private Long key;
public AppObject() {
list = new ArrayList<T>();
}
public AppObject(List<T> list) {
this.list = list;
}
#XmlAnyElement(lax = true)
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
public String getLicense() {
return license;
}
public void setLicense(String license) {
this.license = license;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getService() {
return service;
}
public void setService(String service) {
this.service = service;
}
public String getTablename() {
return tablename;
}
public void setTablename(String tablename) {
this.tablename = tablename;
}
public String getErrormessage() {
return errormessage;
}
public void setErrormessage(String errormessage) {
this.errormessage = errormessage;
}
public Long getKey() {
return key;
}
public void setKey(Long key) {
this.key = key;
}
public String getLocationName() {
return locationName;
}
public void setLocationName(String locationName) {
this.locationName = locationName;
}
public String getFacilityManagerName() {
return facilityManagerName;
}
public void setFacilityManagerName(String facilityManagerName) {
this.facilityManagerName = facilityManagerName;
}
public Date getCreatedFeedFromDate() {
return createdFeedFromDate;
}
#JsonDeserialize(using = com.vxl.JsonDateDeserializer.class)
public void setCreatedFeedFromDate(Date createdFeedFromDate) {
this.createdFeedFromDate = createdFeedFromDate;
}
public Date getCreatedDate() {
return createdFeedToDate;
}
#JsonDeserialize(using = com.vxl.JsonDateDeserializer.class)
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
}
Honestly, I really wouldn't spend time on making a payload "look nice". Now if you said that you were motivated to keep the payload small for efficiency reasons I'd buy that.
Perhaps you use Jackson for serialising to JSON as well (I don't see why you are using two different libraries). I think that this question shows that Jackson's treatment of nulls can be controlled.
Change your get method. Set if(something!=null)return something; instead of return something;