Cannot deserialize out of start_array token - arrays

This is my method for POST test
public void createParagraph3() {
RestAssured.baseURI = paragraphsURL;
Map<String, Object> map = new HashMap<String, Object>();
map.put("featurePackage", Arrays.asList(new HashMap<String, String>() {{
put("name", "Test");
put("inputText", "test test");
}}));
map.put("features", Arrays.asList(new HashMap<String, Object>() {{
put("featureType", "Feature");
put("inUse", "true");
put("name", "test xyxy");
}}));
map.put("type", Arrays.asList(new HashMap<String, String>() {{
put("key", "int");
put("name", "Introduction");
}}));
RequestSpecification request = RestAssured.given();
request.header("Content-Type", "application/json");
request.body(map).toString();
Response response = request.post();
int statusCode = response.getStatusCode();
System.out.println("Response body: " + response.body().asString());
System.out.println("Status code received: " + statusCode);
}
Below I have my request on basis I'm creating my test
{
"featurePackage": {
"features": [
{
"featureType": "string",
"id": 0,
"inUse": true,
"name": "string"
}
],
"id": 0,
"name": "string",
"objectCount": 0
},
"features": [
{
"featureType": "string",
"id": 0,
"inUse": true,
"name": "string"
}
],
"id": 0,
"inputText": "string",
"objectCount": 0,
"outputHtmlText": "string",
"sourceFileName": "string",
"type": {
"key": "string",
"name": "string"
}
}
What I am doing wrong? I still received 400 response "Cannot deserialize instance". Can someone help? I have incomplete request in my method?

EDIT 1:
The root cause is that map.toString() is not a valid JSON string.
There are two ways for you to solve this problem:
use JSONObject instead of map, see this
convert map to JSON object, see this
PS: A demo about map.toString()
Map<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.put("banana", 2);
System.out.println(map.toString());
// get: {apple=1, banana=2} is NOT a valid JSON String
// but, {"apple":1,"banana":2} is a valid JSON String
EDIT 2:
Since the owner of question added some comments, I have to add the following answer.
Pom.xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.0</version>
</dependency>
Java code:
// your comment
Map<String, Object> titles = new HashMap<>();
titles.put("titles", Arrays.asList(new HashMap<String, Object>() {
{
put("id", "876");
put("title", "test");
}
}));
System.out.println(titles);
// my new answer
import com.fasterxml.jackson.databind.ObjectMapper;
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(titles);
System.out.println(json);

Related

Get cookie data from response in Logic App

In postman I can see my cookies and my values attached to them:
When I run the post in logic app, I get a response back and it works. Problem is that I have no idea how to get the cookie values from the response as I cannot see it in the response.
I want to know how do I get my cookie values from my HTTP Response.
Try this on for size.
In the Azure Portal, create a new HttpTrigger Azure Function using the .NET stack and call it HttpProxy using this code, noting that this code should work for you but may need tweaking if you want to go outside the bounds of what it does ...
https://learn.microsoft.com/en-us/azure/azure-functions/functions-create-function-app-portal
#r "Newtonsoft.Json"
using System.Net;
using System.Net.Http.Headers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public class MyKeyValuePairs
{
[JsonProperty("key")]
public string Key { get; set; }
[JsonProperty("value")]
public string Value { get; set; }
public MyKeyValuePairs()
{
Key = String.Empty;
Value = String.Empty;
}
}
public class HttpProxySettings
{
[JsonProperty("url")]
public string Url { get; set; }
[JsonProperty("method")]
public string Method { get; set; }
[JsonProperty("headers")]
public List<MyKeyValuePairs> Headers { get; set; }
public HttpProxySettings()
{
Headers = new List<MyKeyValuePairs>();
Method = "POST";
}
}
public class HttpProxyResponse
{
[JsonProperty("statusCode")]
public int StatusCode { get; set; }
[JsonProperty("body")]
public string Body { get; set; }
[JsonProperty("headers")]
public List<MyKeyValuePairs> Headers { get; set; }
[JsonProperty("cookies")]
public List<MyKeyValuePairs> Cookies { get; set; }
public HttpProxyResponse()
{
Headers = new List<MyKeyValuePairs>();
Cookies = new List<MyKeyValuePairs>();
Body = String.Empty;
}
}
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
var httpProxySettings = JsonConvert.DeserializeObject<HttpProxySettings>(requestBody);
var result = new HttpProxyResponse();
var cookiesContainer = new CookieContainer();
var httpClientHandler = new HttpClientHandler();
httpClientHandler.CookieContainer = cookiesContainer;
var httpClient = new HttpClient(httpClientHandler);
foreach (var header in httpProxySettings.Headers)
{
switch (header.Key.Trim().ToUpper())
{
case "AUTHORIZATION":
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(header.Value.Split(" ")[0], header.Value.Split(" ")[1]);
break;
case "ACCEPT":
httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue(header.Value));
break;
default:
httpClient.DefaultRequestHeaders.Add(header.Key, header.Value);
break;
}
}
var uri = new Uri(httpProxySettings.Url);
var httpMethod = HttpMethod.Get;
switch (httpProxySettings.Method.Trim().ToUpper())
{
case "POST":
httpMethod = HttpMethod.Post;
break;
default:
break;
}
var httpRequestMessage = new HttpRequestMessage(httpMethod, uri);
// Make the call and get the response.
var response = await httpClient.SendAsync(httpRequestMessage);
result.StatusCode = ((int)response.StatusCode);
foreach (var header in response.Headers)
foreach (var value in header.Value)
result.Headers.Add(new MyKeyValuePairs() { Key = header.Key, Value = value });
result.Body = await response.Content.ReadAsStringAsync();
result.Cookies = cookiesContainer.GetCookies(uri).Select(x => new MyKeyValuePairs() { Key = x.Name, Value = x.Value }).ToList();
return new OkObjectResult(result);
}
Now in LogicApps, add the Azure Functions action and select the HttpProxy function that you created in the last step.
With the body, you now need to (adjust first) pass in this as the body and select POST as the method ...
{
"url": "https://yoururl.com",
"method": "POST",
"headers": [
{
"key": "Username",
"value": "YourUsername"
},
{
"key": "Password",
"value": "YourPassword"
}
]
}
When executed, that will yield a result that also contains the cookies in the response. You'll find the body of the response is contained in the Body parameter which you can extract and parse.
This is an example of me calling a URL that is exposed by my company ...
... and yes, there's a lot there but this is the result and as you can see, there's an array of cookies towards the bottom of the response, all of the headers and the response body ...
{
"statusCode": 200,
"headers": {
"Transfer-Encoding": "chunked",
"Vary": "Accept-Encoding",
"Request-Context": "appId=cid-v1:ffaa216d-669a-4113-a9a3-a410e3ea837e",
"Date": "Wed, 23 Mar 2022 05:08:35 GMT",
"Content-Type": "application/json; charset=utf-8",
"Content-Length": "2439"
},
"body": {
"statusCode": 200,
"body": "{\"d\":{\"__metadata\":{\"id\":\"https://myurl.com/DetailsSet('0')\",\"uri\":\"https://myurl.com/DetailsSet('0')\",\"type\":\"ZSERVICE_SRV.Details\"},\"ServiceId\":\"0\",\"Username\":\"S_USERNAME\",\"Parameters\":{\"__deferred\":{\"uri\":\"https://myurl.com/DetailsSet('0')/Parameters\"}},\"Result\":{\"__deferred\":{\"uri\":\"https://myurl.com/DetailsSet('0')/Result\"}}}}",
"headers": [
{
"key": "Set-Cookie",
"value": "sap-usercontext=sap-client=010; path=/"
},
{
"key": "Set-Cookie",
"value": "SAP_SESSIONID_ECX_010=fDYXEyhV_XMmF8D0F1mBCkUwMC2qZxHsqXIADTrRZY0%3d; path=/"
},
{
"key": "Set-Cookie",
"value": "TS0185a829=01b4b1e234597142bcf7f59feffcee3fd29bd758182de666f47ecf3d1d7283cc3adf0dd443e22722dd59dd653c37195ae58e78e338; Path=/; Domain=.myurl.com"
},
{
"key": "Set-Cookie",
"value": "TS01196ab8=0105b6b7b6f79ac0e8e202d4dc042de140020b1fe2cd0e455a269a3b755938e2d4e01e888775c0e8e63f82ce5abad536ce413b412e; Path=/; Secure; HTTPOnly"
},
{
"key": "Set-Cookie",
"value": "TS01c6a478=0105b6b7b6f79ac0e8e202d4dc042de140020b1fe2cd0e455a269a3b755938e2d4e01e888775c0e8e63f82ce5abad536ce413b412e; path=/; domain=.myurl.com; HTTPonly; Secure"
},
{
"key": "x-csrf-token",
"value": "E8Kc5dp0qJYbC5eardfBXA=="
},
{
"key": "dataserviceversion",
"value": "2.0"
},
{
"key": "sap-metadata-last-modified",
"value": "Wed, 30 Sep 2020 22:05:32 GMT"
},
{
"key": "Cache-Control",
"value": "no-store, no-cache"
},
{
"key": "sap-processing-info",
"value": "ODataBEP=,crp=,st=,MedCacheHub=SHM,codeployed=,softstate="
},
{
"key": "sap-server",
"value": "true"
},
{
"key": "sap-perf-fesrec",
"value": "73461.000000"
},
{
"key": "Strict-Transport-Security",
"value": "max-age=16070400; includeSubDomains"
},
{
"key": "Vary",
"value": "Accept-Encoding"
}
],
"cookies": [
{
"key": "sap-usercontext",
"value": "sap-client=010"
},
{
"key": "SAP_SESSIONID_ECX_010",
"value": "fDYXEyhV_XMmF8D0F1mBCkUwMC2qZxHsqXIADTrRZY0%3d"
},
{
"key": "TS01196ab8",
"value": "0105b6b7b6f79ac0e8e202d4dc042de140020b1fe2cd0e455a269a3b755938e2d4e01e888775c0e8e63f82ce5abad536ce413b412e"
},
{
"key": "TS0185a829",
"value": "01b4b1e234597142bcf7f59feffcee3fd29bd758182de666f47ecf3d1d7283cc3adf0dd443e22722dd59dd653c37195ae58e78e338"
},
{
"key": "TS01c6a478",
"value": "0105b6b7b6f79ac0e8e202d4dc042de140020b1fe2cd0e455a269a3b755938e2d4e01e888775c0e8e63f82ce5abad536ce413b412e"
}
]
}
}
Now in LogicApps, you can parse that output and get your cookies as need be.

Unable to use forEach in Flutter Dart for array with just Strings

I'm trying to fill an array with the info of another array that is obtained from an API call.
I'm using the for each function of the Array with the data but I'm getting this error:
E/flutter (21633): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index'
I understand it is because I'm using the imdbID as the index and that is a String however in my response from the API all the items on the Array come as String.
Example:
{
"Title": "The Avengers",
"Year": "2012",
"Rated": "PG-13",
"Released": "04 May 2012",
"Runtime": "143 min",
"Genre": "Action, Adventure, Sci-Fi",
"Director": "Joss Whedon",
"Writer": "Joss Whedon (screenplay), Zak Penn (story), Joss Whedon (story)",
"Actors": "Robert Downey Jr., Chris Evans, Mark Ruffalo, Chris Hemsworth",
"Plot": "Earth's mightiest heroes must come together and learn to fight as a team if they are going to stop the mischievous Loki and his alien army from enslaving humanity.",
"Language": "English, Russian, Hindi",
"Country": "USA",
"Awards": "Nominated for 1 Oscar. Another 38 wins & 79 nominations.",
"Poster": "https://m.media-amazon.com/images/M/MV5BNDYxNjQyMjAtNTdiOS00NGYwLWFmNTAtNThmYjU5ZGI2YTI1XkEyXkFqcGdeQXVyMTMxODk2OTU#._V1_SX300.jpg",
"Ratings": [
{
"Source": "Internet Movie Database",
"Value": "8.0/10"
},
{
"Source": "Rotten Tomatoes",
"Value": "91%"
},
{
"Source": "Metacritic",
"Value": "69/100"
}
],
"Metascore": "69",
"imdbRating": "8.0",
"imdbVotes": "1,263,208",
"imdbID": "tt0848228",
"Type": "movie",
"DVD": "N/A",
"BoxOffice": "$623,357,910",
"Production": "Marvel Studios",
"Website": "N/A",
"Response": "True"
}
Here is my Current code for my call:
Future<void> fetchAndSetPeliculas(title, tipo) async {
var url = 'http://www.omdbapi.com/?apikey=[my API key]&t=$title';
try {
final response = await http.get(url);
final extractedData = json.decode(response.body) as Map<String, dynamic>;
if(extractedData == null){
return;
}
final List<Pelicula> loadedPeliculas = [];
extractedData.forEach((imdbID, data) {
loadedPeliculas.add(Pelicula(
imdbID: imdbID,
imdbRating: data['imdbRating'],
metaScore: data['Metascore'],
plot: data['Plot'],
poster: data['Poster'],
title: data['Title'],
type: data['Type'],
year: data['Year'],
));
});
_items = loadedPeliculas.reversed.toList();
notifyListeners();
} catch (error) {
throw (error);
}
}
So is there a way to fill the loadedPeliculas Array with the information from the API call, or move in the Response Array when there is no INT value for it?
Kind Regards.
Any specific reason for casting your response to Map<String, dynamic>. A List should work just fine.
This should work as well:
try {
final response = await http.get(url);
final extractedData = json.decode(response.body) as List;
if(extractedData == null){
return;
}
final List<Pelicula> loadedPeliculas = [];
extractedData.forEach((data) {
loadedPeliculas.add(Pelicula(
imdbID: data['imdbID'],
imdbRating: data['imdbRating'],
metaScore: data['Metascore'],
plot: data['Plot'],
poster: data['Poster'],
title: data['Title'],
type: data['Type'],
year: data['Year'],
));
});
Edit: You might not even have to add as List
Thanks Rey,
Your Answer got me to the final Answer the Problem as you Abion47 mentioned was that I was mapping the response.
Although it gave me the error on my previous Comment I was now able to move inside the JSON array using this code:
try {
final response = await http.get(url);
final extractedData = json.decode(response.body);
if (extractedData == null) {
return;
}
final List<Pelicula> loadedPeliculas = [];
final size = extractedData.length;
for (var i = 0; i < size; i++) {
loadedPeliculas.add(Pelicula(
imdbID: extractedData['Search'][i]['imdbID'],
poster: extractedData['Search'][i]['Poster'],
title: extractedData['Search'][i]['Title'],
type: extractedData['Search'][i]['Type'],
year: extractedData['Search'][i]['Year'],
));
}
Thanks to the Both of you I got it working.
Thank you so much

How to serialize api response contains list in flutter?

This is the response I am getting from server. All the properties are String and int expect data. It is a list of objects. When serializing the response it shows error. Please explain what is wrong with my code. I am from javascript background. Serialization in flutter is different from javascript.
class ResponseModel {
String image;
int row;
int column;
int position;
List<Data> data;
ResponseModel({this.image, this.row, this.column, this.position});
factory ResponseModel.fromJson(Map<String, dynamic> parsedJson) {
return ResponseModel(
image: parsedJson['image'],
row: parsedJson['row'],
column: parsedJson['column'],
position: parsedJson['position'],
);
}
}
class Data {
String imageUrl;
Data({this.imageUrl});
factory Data.fromJson(Map<String, dynamic> parsedJson) {
return Data(imageUrl: parsedJson["imageUrl"]);
}
}
[
{
"type": "image",
"row": 1,
"column": 3,
"position":"1",
"data": [
{
"imageUrl": "https://rukminim1.flixcart.com/flap/276/294/image/6dad06016c6ab319.jpg?q=90"
},
{
"imageUrl": "https://rukminim1.flixcart.com/flap/276/294/image/9ad209b0fc3d03e4.jpg?q=90"
},
{
"imageUrl": "https://rukminim1.flixcart.com/flap/276/294/image/405e10d01fae5aa5.jpg?q=90"
}
]
},
{
"type": "image",
"row": 1,
"column": 2,
"position":"3",
"data": [
{
"imageUrl": "https://rukminim1.flixcart.com/flap/414/630/image/f186565389063212.jpg?q=90"
},
{
"imageUrl": "https://rukminim1.flixcart.com/flap/414/630/image/3eda035d946b0ebf.jpg?q=90"
}
]
},
{
"type": "image",
"row": 1,
"column": 1,
"position":"2",
"data": [
{
"imageUrl": "https://rukminim1.flixcart.com/flap/1187/636/image/4436d492e2563998.jpg?q=90"
}
]
}
]
Future<dynamic> getData() async {
final response = await http.get("https://api.myjson.com/bins/1g4o04");
final parsedJson = json.decode(response.body);
final finalResponse = ResponseModel.fromJson(parsedJson);
print(finalResponse);
setState(() {
data = parsedJson;
});
}
Error image
You can use this tool and select dart Language
Its because the response is a JSON array. Which means json.decode(response.body) returns a List<dynamic> and hence the variable parsedJson is List.
You're trying to pass this List as a parameter to the ResponseModel.fromJson(Map<String, dynamic>) method which accepts a Map as the parameter.
In simple words, you're trying to pass a List where a Map is expected.
Future<dynamic> getData() async {
final response = await http.get("https://api.myjson.com/bins/1g4o04");
final parsedJson = json.decode(response.body);
List<ResponseModel> responseList = <ResponseModel>[];
parsedJson.foreach((element) {
responseList.add(ResponseModel.fromJson(element));
})
///Response list will have your data
print(responseList);
}
Your code should be something like this

How to creation of multiple json arrays at a go?

I need to create multiple Json arrays at a single instance. I have 38 rows. For 38 rows first I need to create 38 empty JSON arrays. Then in each JSON array i need to add first column of row as first object in all the arrays. Second column as 2nd object etc. Is there a way to specify the position to add the objects in each array?
[
[
{
"fileName": "123"
},
{
"id": "100"
},
{
"product": ""
}
],
[
{
"fileName": "123"
},
{
"id": "100"
},
{
"product": ""
}
]...38
]
package emp;
import javax.lang.model.element.PackageElement;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class Temp
{
public static void main(String[] args) throws JSONException {
JSONArray jsonArray = new JSONArray();
jsonArray.put(createJsonArray("name 1", "id 1", "product 1"));
jsonArray.put(createJsonArray("name 2", "id 2", "product 2"));
jsonArray.put(createJsonArray("name 3", "id 3", "product 3"));
System.out.println(jsonArray.toString());
}
public static JSONArray createJsonArray(String name, String id, String product) throws JSONException
{
JSONArray jsonArray = new JSONArray();
JSONObject jsonObject = new JSONObject();
jsonObject.put("fileName", "123");
jsonArray.put(jsonObject);
jsonObject.put("id", "123");
jsonArray.put(jsonObject);
jsonObject.put("product", "product");
jsonArray.put(jsonObject);
return jsonArray;
}
}

Get nested JSON object from a JSON Array

May i know how to get JSON object from an json array??
JSON:
[
{
"id": 1,
"user": {
"id": 20710,
"username": "abc",
"first_name": "",
"last_name": "",
},
"action": {
"name": "xxx",
"date": 19/01/01,
},
},
{
"id": 2,
"user": {
"username": "xyx",
"first_name": "xxx",
"last_name": "yyy",
},
"action": {
"name": "xxx",
"date": 19/05/01,
},
},]
I want to get username of these users in a list, but i cant get the value when i get this json from api as JSONArray.
My code:
public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
Log.d("Create Response", response.toString());
ArrayList<String> list = new ArrayList<String>();
JSONArray jsonArray = response;
try {
if (jsonArray != null) {
int len = jsonArray.length();
for (int i=0;i<len;i++){
JSONObject c=response.getJSONObject(1);
String id = c.getString(i);
HashMap<String, String> map = new HashMap<String, String>();
map.put("id", id);
feeds_List.add(map);
}
}
I cannot use
JSONObject object=JsonArray.getJSONObject("user");
here,
it only accept int for getJSONObject("user"); if it is JSONArray
You can use like this also.Suppose response String is userInfo
ArrayList<String> usernames = new ArrayList<String>();
JSONArray userList = new JSONArray(userInfo);
for (int j = 0; j < userList.length(); j++) {
JSONObject userObject = new JSONObject(userList.getString(j));
String user = userObject.getString("user");
JSONObject usernameInfo = new JSONObject(user);
usernames.add(usernameInfo.getString("username"));
}
Try this, if not working please mention me in comment.

Resources