How to send a JSON payload with REST API in Grails? - json

I am trying to call a REST API with JSON payload using Grails and getting error below.
I have already converted the object to JSON earlier here and passing it in. Not sure what am I missing.
SpotifyService.groovy
#Transactional
class SpotifyService implements EventPublisher {
String spotifyServiceBaseUrl = 'http://localhost:9999'
String username = "abcd"
String password = "defg"
void createSoldOrder(ItemDetails itemDetails) {
println("into the createSoldOrder method......")
String orderId = "100-200-ABC"
String soldDate = itemDetails.order.orderDate
String partnerUniqueId = itemDetails.customer.billingAddress.email
def monthEndDate = new Date() + 30
String commitEndDate = monthEndDate.toString()
String product = "premium-month"
String soldMetadata = "Partner's metadata connected to the sold order"
String partnerDeals = "hardbundle*3,standalone"
NewOrder newOrder = new NewOrder(orderId: orderId, soldDate: soldDate, partnerUniqueId: partnerUniqueId,
commitEndDate: commitEndDate, product: product, soldMetadata: soldMetadata,
partnerDeals: partnerDeals)
println("newOrder: " + newOrder)
String newOrderJsonPayload = new JsonBuilder(newOrder).toPrettyString()
println("newOrderJsonPayload: " + newOrderJsonPayload)
placeSpotifyOrder(newOrderJsonPayload)
}
void placeSpotifyOrder(String newOrderJsonPayload) {
println("into the placeSpotifyOrder method........")
String restUrl = spotifyServiceBaseUrl + "/order-sold"
println restUrl
RestBuilder rest = new RestBuilder()
RestResponse restResponse = rest.post(restUrl) {
auth username, password
json {
newOrderJsonPayload
}
}
if (restResponse.statusCode.value()) {
println(restResponse.text)
}
null
}
}
Error:
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '{
"product": "premium-month",
"orderId": "100-200-ABC",
"soldMetadata": "Partner's metadata connected to the sold order",
"partnerUniqueId": "success#simulator.amazonses.com",
"commitEndDate": "Sat Mar 24 16:51:37 EDT 2018",
"soldDate": "2017-08-03T20:07:27+0000",
"partnerDeals": "hardbundle*3,standalone"
}' with class 'java.lang.String' to class 'grails.converters.JSON'
at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnSAM(DefaultTypeTransformation.java:405)
at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnNumber(DefaultTypeTransformation.java:319)
at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:232)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.asType(DefaultGroovyMethods.java:15669)
at org.codehaus.groovy.runtime.StringGroovyMethods.asType(StringGroovyMethods.java:195)
at org.codehaus.groovy.runtime.dgm$1048.doMethodInvoke(Unknown Source)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at org.codehaus.groovy.runtime.InvokerHelper.invokePojoMethod(InvokerHelper.java:913)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:904)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:168)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.asType(ScriptBytecodeAdapter.java:591)
at grails.web.JSONBuilder.build(JSONBuilder.groovy:42)
at grails.plugins.rest.client.RequestCustomizer.json(RequestCustomizer.groovy:195)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1433)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:384)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:69)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:166)
at com.synapsegroupinc.spotifyintegrator.SpotifyService$__tt__placeSpotifyOrder_closure4.doCall(SpotifyService.groovy:50)

Create a new class with all the properties you need in the json object. Create an instance of the class and populate its properties. Then use objInstance as JSON to covert it to json.

I think your problem connected with Method json{}. The method is overloaded. If you want to send payload as json string you should change your code in placeSpotifyOrder as following:
RestResponse restResponse = rest.post(restUrl) {
auth (username, password)
json (newOrderJsonPayload)
}

Related

json to collection (list) in SpringBoot

I'm trying to get a list of orders from another service(url) with #GetMapping.
I can't get the json objects and convert them to a list.I keep getting these and similar errors:
org.springframework.web.client.HttpServerErrorException$InternalServerError:
500 Server Error: [java.lang.IllegalStateException: Not a JSON Object: null at com.google.gson.JsonElement.getAsJsonObject(JsonElement.java:91)
What should I do? please help me for how many days i can't find the right solution.
#Autowired
private final RestTemplate restTemplate;
#Value("${baseUrl}")
private String baseUrl;
public OrdersController(OrdersService ordersService, TradesService tradesService, RestTemplate restTemplate) {
this.ordersService = ordersService;
this.tradesService = tradesService;
this.restTemplate = restTemplate;
}
#GetMapping (value ="/restDeneme", produces="application/json")
public List <Orders> getOrders(){
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>(headers);
ResponseEntity<List<Orders>> response = restTemplate.exchange(
baseUrl , HttpMethod.GET,entity,
new ParameterizedTypeReference<List<Orders>>() {});
return response.getBody();
}
You should try to receive the data as a JSON object
for a JSON format like this;
{
"Kml": {
"bicak": "AWAKEN YOUR SENSES",
"jobsearch": "JOB SEARCH",
"contact": "CONTACT",
"video": "ENCHANTING BEACHSCAPES",
"createprofile": "CREATE PROFILE"
}
}
You can call it like this;
String loudScreaming = json.getJSONObject("Kml").getString("bicak");

how to parse JSON file using rest API and spring boot

I'm new to this, and I want to read JSON file imported with rest api and parse it with spring boot.
I worked with CSV file with his method :
#RequestMapping(value = "/import", method = RequestMethod.POST)
public String handleFileUpload(#RequestParam("file") MultipartFile multipartFile) throws IOException {
String name = multipartFile.getOriginalFilename();
System.out.println("File name: "+name);
byte[] bytes = multipartFile.getBytes();
System.out.println("File uploaded content:\n" + new String(bytes));
return "file uploaded";
}
Now i want to parse a JSON File :
[
{
"name":"John",
"city":"Berlin",
"cars":[
"audi",
"bmw"
],
"job":"Teacher"
},
{
"name":"Mark",
"city":"Oslo",
"cars":[
"VW",
"Toyata"
],
"job":"Doctor"
}
]
I have try it to parse this file with java and it works for me but I dont know how to get it with rest api
This method to parse te file JSON and it works
public static void main(String[] args) throws FileNotFoundException,
IOException, ParseException {
JSONParser parser = new JSONParser();
JSONArray jsonArray = (JSONArray) parser.parse(new FileReader(
"D:/PFE 2018/testjsonfile.json"));
for (Object o : jsonArray) {
JSONObject person = (JSONObject) o;
String strName = (String) person.get("name");
System.out.println("Name::::" + strName);
String strCity = (String) person.get("city");
System.out.println("City::::" + strCity);
JSONArray arrays = (JSONArray) person.get("cars");
for (Object object : arrays) {
System.out.println("cars::::" + object);
}
String strJob = (String) person.get("job");
System.out.println("Job::::" + strJob);
System.out.println();
}
}
now how to reuse this methode with rest api
It depends what you want to do with your JSON (it's not entirely clear in your question).
In general, good practice with Spring Boot is to use Jackson either:
binding your JSON with a POJO if you expect your JSON to have a known format or
mapping your JSON in a tree.
Examples for the described behaviours can be found in this article for instance.

updating JSON Object in spring restful web services

I want to pass a json object for the update function but its doesn't accept the json object and get an error. The error is:
the code is:
(value = "/UpdateUser/", method = RequestMethod.PUT , consumes=MediaType.APPLICATION_JSON_VALUE)
public void UpdateUser(JSONObject RequiredObject)throws UnknownHostException {
// RequiredObject=new HashMap<>();
System.out.println("hello into update " + RequiredObject);
// readJSON.UpdateUser(RequiredObject);
}
you have to receive the body of your request as a #RequestBody and you can receive this json object as a User object directly
#RequestMapping(value = "/UpdateUser/", method = RequestMethod.PUT ,
consumes=MediaType.APPLICATION_JSON_VALUE)
public void UpdateUser(#RequestBody User user) throws UnknownHostException {
// RequiredObject=new HashMap<>();
System.out.println("hello into update " + RequiredObject);
//readJSON.UpdateUser(RequiredObject);
}

ibm mobilefirst Adapter - convert JSONObject to POJO class

Anyone knows - How to convert JSONObject to POJO class?
I have created an Adapter which i would like to convert it to Pojo before i send it to Client.
1) my ResourceAdapterResource.java (Adapter)
#POST
#Path("profiles/{userid}/{password}")
#Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public JSONObject getStatus(#PathParam("userid") String userid, #PathParam("password") String password) throws IOException {
Map<String, Object> maps = new HashMap<String,Object>();
map.put("userid", userid);
map.put("password",password);
// json Object will get the value from SOAP Adapter Service
JSONObject obj = soapAdapterService(maps);
/** Question here, how to add to POJO.. I have code here but not work, null values**/
// set to Object Pojo Employee
Employee emp = new Employee();
emp.setUserId(String.valueOf(obj.get("userId")));
emp.setUserStatus((String.valueOf(obj.get("userStatus")));
// when I logging its show Empty.
logger.info("User ID from service : " + emp.getUserId());
logger.info("Status Id from service : " + emp.getUserStatus());
return obj;
}
2.) Pojo Class - Employee
import java.io.Serializable;
#SuppressWarnings("serial")
public class Employee implements Serializable{
private String userid;
private String userStatus;
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid= userid;
}
public String getUserStatus() {
return userStatus;
}
public void setUserStaus(String userStatus) {
this.userStatus= userStatus;
}
}
When I tested using Swagger - MobileFirst Console restful testing, it return the JsonObject with successfully return Body with data from the services.
But when i check log info ( message.log ) - server logs, the status is null.
User ID from service : null
Status Id from service : null
Seems its JSON Java IBM API , does it have ObjectMapper like Jackson API to map the JsonObject to POJO Class.
Results from Swagger
{
"statusReason": "OK",
"responseHeaders": {
"Content-Length": "1849",
"Content-Language": "en-US",
"Date": "Thu, 23 Mar 2017 01:40:33 GMT",
"X-Powered-By": "Servlet/3.0",
"Content-Type": "text/xml; charset=utf-8"
},
"isSuccessful": true,
"responseTime": 28,
"totalTime": 33,
"warnings": [],
"Envelope": {
"soapenv": "http://schemas.xmlsoap.org/soap/envelope/",
"Body": {
"checkEmployeeLoginResponse": {
"a": "http://com.fndong.my/employee_Login/",
"loginEmployeeResp": {
"Employee": {
"idmpuUserName": "fndong",
"Status": "A",
"userid": "fndong",
"Password": "AohIeNooBHfedOVvjcYpJANgPQ1qq73WKhHvch0VQtg#=",
"PwdCount": "1",
"rEmail": "fndong#gmail.com"
},
"sessionId": "%3F",
"statusCode": "0"
}
}
}
},
"errors": [],
"info": [],
"statusCode": 200
}
Then I followed your suggestion to cast to String:
String objUserId = (String) objectAuth.get("userid");
The Results still null, does it require to indicate the json restful result by call the body function "loginEmployeeResp", because the data JSon Object are from service SOAP.
Clearly your String.valueOf(obj.get("userId")) is returning null or empty, so the question is, which part of it?
You can log obj.get("userId") and see if that is empty, in which case the response doesn't contain what you expect.
But I suspect the issue is the String.valueOf() conversion not doing what you expect. It looks like the JSONObject in MobileFirst is com.ibm.json.java.JSONObject, and when I search on that, the example I found simply casts to String:
emp.setUserId((String) obj.get("userId"));
Edit: now that you've added the Swagger results, I'd say your obj.get("userId") probably is returning null itself. Did you check that?
For one thing, "userId" isn't "userid". The capitalization matters.
But more importantly, "userid" is nested deep in the JSON, so I don't think just getting it from the top level JSONObject is going to work. I think you'll have to do something like:
JSONObject envelope = (JSONObject) obj.get("Envelope");
JSONObject body = (JSONObject) envelope.get("Body");
JSONObject response = (JSONObject) body.get("checkEmployeeLoginResponse");
JSONObject resp = (JSONObject) response.get("loginEmployeeResp");
JSONObject employee = (JSONObject) resp.get("Employee");
emp.setUserId((String) employee.get("userid"));
emp.setUserStatus((String) employee.get("status"));
(Regrettably, with that particular IBM JSON4J, I don't think there's a way to do a more automatic unmarshalling of JSON into Java objects.)

how to call web api in controller and return into view MVC4

I have a project using MVC4, i want to ask how to get data from webapi and return into view.
Model
public class Name
{
public Int32 NameId { get; set; }
public String FirstName{ get; set; }
public String LastName{ get; set; }
public String CreatedBy { get; set; }
}
public class IListMyProject
{
public List<Name> Names { get; set; }
}
I can list all in my Index.cshtml using this code
public ActionResult Index()
{
string securityToken = repo.GetTokens();
if (securityToken != null)
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "webapiurl/api/Name/Get?$orderby=LastName&$top=10");
string authHeader = System.Net.HttpRequestHeader.Authorization.ToString();
httpRequestMessage.Headers.Add(authHeader, string.Format("JWT {0}", securityToken));
var response = client.SendAsync(httpRequestMessage)
.ContinueWith((postTask) => postTask.Result.EnsureSuccessStatusCode())
.Result;
if (response.IsSuccessStatusCode)
{
model.Names = response.Content.ReadAsAsync<IList<Name>>().Result.ToList();
}
}
return View("Index", model);
}
i can return my view. and now i have another view called Details.cshtml with this code :
public ActionResult Details(string id)
{
string securityToken = repo.GetTokens();
if (securityToken != null)
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "webapiurl/api/Name/GetById/"+id+"");
string authHeader = System.Net.HttpRequestHeader.Authorization.ToString();
httpRequestMessage.Headers.Add(authHeader, string.Format("JWT {0}", securityToken));
var response = client.SendAsync(httpRequestMessage)
.ContinueWith((postTask) => postTask.Result.EnsureSuccessStatusCode())
.Result;
if (response.IsSuccessStatusCode)
{
model.Names = response.Content.ReadAsAsync<IList<Name>>().Result.ToList();
}
}
return View(model);
}
For this Detail, my Json looks like this:
application/json, text/json
{
"NameId": 1,
"FirstName": "This is First Name",
"LastName": "This is Last Name",
"CreatedBy": "This is Created By"
}
when i run it, i get this error :
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.IList`1[Models.Name]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'NameId', line 1, position 10.
How do i fix this, im new to webapi. i wonder why do if i list all (for index, i use api/get) it works, but when i want to show it in detail, it doesn't work.
thank for help
Regards
EDIT
when i debug in
model.Names = response.Content.ReadAsAsync<IList<Name>>().Result.ToList();
its says Null, is there something wrong when i try to get the response ?
The issue is that:
{
"NameId": 1,
"FirstName": "This is First Name",
"LastName": "This is Last Name",
"CreatedBy": "This is Created By"
}
can't be deserialized as an IList. The JSON you have above is just one name, not a collection of Names. So Json.NET deserialization will fail.
Make sure that your Web API controller returns an IList, or change your MVC code to read the content as a single Name. A collection of names in JSON would look like this instead:
[{
"NameId": 1,
"FirstName": "This is First Name",
"LastName": "This is Last Name",
"CreatedBy": "This is Created By"
},
{
"NameId": 2,
"FirstName": "This is First Name",
"LastName": "This is Last Name",
"CreatedBy": "This is Created By"
}]
The Web API is returning a single object of type Name, not a collections of Name. I do not see where you define model. I added a definition of type Name. Try this.
public ActionResult Details(string id)
{
string securityToken = repo.GetTokens();
Name model;
if (securityToken != null)
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "webapiurl/api/Name/GetById/"+id+"");
string authHeader = System.Net.HttpRequestHeader.Authorization.ToString();
httpRequestMessage.Headers.Add(authHeader, string.Format("JWT {0}", securityToken));
var response = client.SendAsync(httpRequestMessage)
.ContinueWith((postTask) => postTask.Result.EnsureSuccessStatusCode())
.Result;
if (response.IsSuccessStatusCode)
{
model = response.Content.ReadAsAsync<Name>();
}
}
return View(model);
}
The issue seems to be the fact that your JSON returns only 1 record while you are Reading the result as IList<Name>. Changing it to simply Name should fix the problem.
However you question is: "how to call web api in controller and return into view MVC4"
I recommend you to look at http://restsharp.org/ You can simplify your code to:
public ActionResult Details(string id)
{
string securityToken = repo.GetTokens();
Name model;
if (securityToken != null)
{
var client = new RestClient("");
var request = new RestRequest("webapiurl/api/Name/GetById/"+id, HttpMethod.Get);
string authHeader = System.Net.HttpRequestHeader.Authorization.ToString();
request.AddHeader(authHeader, string.Format("JWT {0}", securityToken));
var model = client.Execute<Name>(request);
}
return View(model);
}