How would be the class that matches the following json :
'''{
"id1" : {
"apiToCall" : ["200", "400", "500"],
"apiToCall2" : ["100"],
"apiToCall5" : ["600", "300"]
},
"id2" : {
"apiToCall10" : ["300"],
"apiToCall8" : ["600", "700", "500"]
},
"id3" : {
"apiToCall80" : ["200", "400", "500"]
}
}'''
I want to send this object in POST method using spring rest, but my issue is that i have dynamic attributes.
So i don't know how to create the class that manages this case.
HttpEntity<String> entity = new HttpEntity(reqJsonStr, headers);
KeyPoint : "HttpEntity<String>" means type of request(reqJsonStr) is string.
RestTemplate restTemplate = new RestTemplate();
String reqURL = \"https://www.request_url.com/restapi/\";
String reqJsonStr = \"{"
+ " "\"id1\" : {"
+ " \"apiToCall\" : [\"200\", \"400\", \"500\"],"
+ " \"apiToCall2\" : [\"100\"],"
+ " \"apiToCall5\" : [\"600\", \"300\"]"
+ " },"
+ " \"id2\" : {"
+ " \"apiToCall10\" : [\"300\"],"
+ " \"apiToCall8\" : [\"600\", \"700\", \"500\"]"
+ " },"
+ " \"id3\" : {"
+ " \"apiToCall80\" : [\"200\", \"400\", \"500\"]"
+ " }"
+ "}";
headers headers = new headers();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(reqJsonStr, headers);
String responseStr = restTemplate.exchange(reqURL, reqJsonStr, HttpMethod.POST, String.class);
I am not sure if it will work or not but it can be
Map<String, Map<String, List<String>>
Related
i have java sample code that insert 2 basic documents
#Container
private final ElasticsearchContainer elasticContainer = DataApiElasticSearchContainer.getInstance();
HttpEntity<String> entity_post = new HttpEntity<>("{\"man_name\": \"Hello world!\"}", headers);
HttpEntity<String> entity_post2 = new HttpEntity<>("{\"man_name\": \"Hello world666!\"}", headers);
HttpEntity<String> entity_get = new HttpEntity<>("{\n" +
" \"aggs\": {\n" +
" \"genres\": {\n" +
" \"terms\": { \"field\": \"man_name\" } \n" +
" }\n" +
" }\n" +
"}" +
"}", headers);
ResponseEntity<String> response_post =
restTemplate.exchange("http://" + elasticContainer.getHttpHostAddress() + "/bookindex/man_name",
HttpMethod.POST, entity_post,String.class);
assertThat(response_post.getStatusCode()).isEqualTo(HttpStatus.CREATED);
ResponseEntity<String> response_post2 =
restTemplate.exchange("http://" + elasticContainer.getHttpHostAddress() + "/bookindex/man_name",
HttpMethod.POST, entity_post2,String.class);
assertThat(response_post2.getStatusCode()).isEqualTo(HttpStatus.CREATED);
ResponseEntity<String> response =
restTemplate.exchange("http://" + elasticContainer.getHttpHostAddress() + "/bookindex/_search",
HttpMethod.GET, entity_get, String.class);
System.out.println(response.getBody());
But i have this output from my get body
{"took":36,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":0,"relation":"eq"},"max_score":null,"hits":[]}}
i want list of man_name values like this : ["Hello world!", "Hello world666!"]
If I get you question right, There is nothing wrong with your code and every time you execute the code you will receive the log that your two documents ingested successfully in one shard but if you want to get the list of your ingested documents as you may know you need to add query Api such below at the end of your http request . In this manner you will receive the list of your documents.
curl -XGET "http://localhost:9200/yourindexname/_search" -H 'Content-Type: application/json' -d'{ "query": {"match_all": {}}}'
[
{
countryCode: "CN",
countryCallingCode: "+86",
codeRule: "^1\d{10}$"
},
{
countryCode: "US",
countryCallingCode: "+1",
codeRule: "^\d{10}$"
}
]
So I define the model like this in Kotlin
data class CountryCallingCode(
val countryCode: String,
val countryCallingCode: String,
val codeRule: String? = null
)
This is what the backend document defines the response.
codeRule is regex expression to verify a phone number.
I stuck in convert the String to List.
I pasted them to Android Studio, and it shows like:
String response = "[\n" +
" {\n" +
" countryCode: \"CN\",\n" +
" countryCallingCode: \"+86\",\n" +
//" codeRule: \"^1\\d{10}$\"\n" +
" },\n" +
" {\n" +
" countryCode: \"US\",\n" +
" countryCallingCode: \"+1\",\n" +
//" codeRule: \"^\\d{10}$\"\n" +
" }\n" +
"]";
The following codes do not work.
Converting code 1:
Gson gson = new Gson()
CountryCallingCode[] countryCallingCodeList = gson.fromJson(response, CountryCallingCode[].class);
And I think the following codes are the same, correct me if I am wrong.
Converting code 2:
ArrayList<CountryCallingCode> countryCallingCodeList = (ArrayList<CountryCallingCode>)gson.fromJson(response, ArrayList.class);
Converting Code 3
Gson gson = new Gson();
Type type = new TypeToken<List<CountryCallingCode>>() {
}.getType();
List<CountryCallingCode> countryCallingCodeList = gson.fromJson(response, type);
Then I use https://jsoneditoronline.org/ to reformat my json.
I tried to remove the codeRule, and pasted to the Android Studio, it also tells me I am wrong, it shows CountryCode causes SyntaxException.
String reponse = "[\n" +
" {\n" +
" countryCode: \"CN\",\n" +
" countryCallingCode: \"+86\"\n" +
" },\n" +
" {\n" +
" countryCode: \"US\",\n" +
" countryCallingCode: \"+1\"\n" +
" }\n" +
"]";
Only I compress the jsonstring to oneline, I could convert the jsonstring to the array/ArrayList.
String response = "[{\"countryCode\":\"CN\",\"countryCallingCode\":\"+86\"},{\"countryCode\":\"US\",\"countryCallingCode\":\"+1\"}]";
Does anyone know
Q1:
How to deal with codeRule?
Q2:
Why couldn't I pasted the origin JsonString to the Android Studio?
Why I must compress the JsonString into one line string?
Updated:
Origin one line json string:
[{"countryCode":"CN","countryCallingCode":"+86", codeRule: "^1\d{10}$"},{"countryCode":"US","countryCallingCode":"+1", codeRule: "^\d{10}$"}]
Pasted result json string:
String response = "[{\"countryCode\":\"CN\",\"countryCallingCode\":\"+86\", codeRule: \"^1\\d{10}$\"},{\"countryCode\":\"US\",\"countryCallingCode\":\"+1\", codeRule: \"^\\d{10}$\"}]";
Code:
Gson gson = new Gson();
/* Convertion 1 */
CountryCallingCode[] countryCallingCodeList = gson.fromJson(response, CountryCallingCode[].class);
Error:
result = {JsonSyntaxException#7237} Method threw 'com.google.gson.JsonSyntaxException' exception.
cause = {MalformedJsonException#7241} "com.google.gson.stream.MalformedJsonException: Invalid escape sequence at line 1 column 65 path $[0].codeRule"
detailMessage = "com.google.gson.stream.MalformedJsonException: Invalid escape sequence at line 1 column 65 path $[0].codeRule"
stackState = null
stackTrace = {StackTraceElement[28]#7243}
suppressedExceptions = {Collections$EmptyList#7244} size = 0
shadow$_klass_ = {Class#1694} "class com.google.gson.JsonSyntaxException"
shadow$_monitor_ = -2082115852
This is more of a comment than an answer, but I need more space to explain - if your version of Java supports it, can you try creating your response with a raw string like this:
String response = `[
{
countryCode: "CN",
countryCallingCode: "+86",
codeRule: "^1\d{10}$"
},
{
countryCode: "US",
countryCallingCode: "+1",
codeRule: "^\d{10}$"
}
]`
Or if possible use Kotlin, which uses """ to delimit raw strings. It will be much more readable and might help you spot mistakes
I am trying to use appium backdoor in appium-java client, but exceptions are thrown due to invalid syntax. can someone help me in validating this issue?
driver.executeScript("mobile:backdoor", "{target: 'com.learn.android.Settings', methods: [{name: 'setclient' , args: [{value: '10.10.10.10:1010', type: 'java.lang.String'}] }, {name: 'setserver', args: [{value: '19.19.19.19:1919', type: 'java.lang.String'}] }] }");
I tried using hashmap but still, I couldn't able to succeed
HashMap<String, Object> param = new HashMap<String, Object>();
param.put("target", "com.learn.android.Settings");
param.put("methods", "[{\n" +
" \t\t\"name\": \"setclient\",\n" +
" \t\t\"args\": [{\n" +
" \t\t\t\"value\": \"10.10.10.10:1010\",\n" +
" \t\t\t\"type\": \"java.lang.String\"\n" +
" \t\t}]\n" +
" \t},\n" +
" \t{\n" +
" \t\t\"name\": \"setserver\",\n" +
" \t\t\"args\": [{\n" +
" \t\t\t\"value\": \"19.19.19.19:1919\",\n" +
" \t\t\t\"type\": \"java.lang.String\"\n" +
" \t\t}]\n" +
" \t}\n" +
" ]");
driver.executeScript("mobile:backdoor", param);
appreciate your support.
Able to find the answer
ImmutableMap<String, Object> scriptArgs = ImmutableMap.of(
"target", "application",
"methods", Arrays.asList(ImmutableMap.of(
"name", "setclient",
"args", Arrays.asList(ImmutableMap.of(
"value", "2.2.2.2",
"type", "String"
))
))
);
driver.executeScript("mobile: backdoor", scriptArgs);
I have already tried http://www.jsonschema2pojo.org/ to solve this but it hasn't worked. I am trying to create a Json response class for this Json format:
{
"Structure1": [
[
"StringValue1",
"StringValue2"
],
[
"StringValue1",
"StringValue2"
]
],
"Structure2": [
[
"StringValue1",
"StringValue2"
]
],
"Structure3": [
[
"StringValue1",
"StringValue2"
]
]
}
Here is what my current class looks like:
public class Response {
private HashMap<String, ArrayList<ArrayList<String>>> map = new HashMap<String, ArrayList<ArrayList<String>>>();
public HashMap<String, ArrayList<ArrayList<String>>> getMap() {
return map;
}
public void setFile11Txt(HashMap<String, ArrayList<ArrayList<String>>> map) {
this.map = map;
}
}
To parse I am doing
Response response = gson.fromJson(response, Response.class);
The returned map ends up being empty, what am I doing wrong?
I suggest the following code:
String jsonString = "{\n" +
" \"Structure1\": [\n" +
" [\n" +
" \"StringValue1\",\n" +
" \"StringValue2\"\n" +
" ],\n" +
" [\n" +
" \"StringValue1\",\n" +
" \"StringValue2\"\n" +
" ]\n" +
" ],\n" +
" \"Structure2\": [\n" +
" [\n" +
" \"StringValue1\",\n" +
" \"StringValue2\"\n" +
" ]\n" +
" ],\n" +
" \"Structure3\": [\n" +
" [\n" +
" \"StringValue1\",\n" +
" \"StringValue2\"\n" +
" ]\n" +
" ]\n" +
" }";
Map<String, ArrayList<String>> myMap = gson.fromJson(jsonString, HashMap.class);
Debug screenshot as the following:
Hope this helps!
Your Response represents and object that contains a HashMap in a field named map, but your JSON represents just a Map. You do not need to have an enclosing object, just deserialize the HashMap directly --
HashMap<String, ArrayList<ArrayList<String>>> map;
Type mapType = new TypeToken<HashMap<String, ArrayList<ArrayList<String>>>>() {}.getType();
map = gson.fromJson(response, mapType);
TypeToken objtype= new TypeToken<Response>() {}.getType();
Response responseobj= new Gson().fromJson(responsestring, objtype);
use Typetoken to parse Gson Object back to original one
I have the following JSON in my android application and I'm using Springs for android RestTemplate. Is it somehow possible to fetch only internal list from this json ? Currently I have to create a wrapper object and then I can fetch List<Cast> casts; from it - it's a bit inconvenient.
{
"id": 550,
"cast": [
{
"cast_id": 4,
"character": "The Narrator",
"credit_id": "52fe4250c3a36847f80149f3",
"id": 819,
"name": "Edward Norton",
"order": 0,
"profile_path": "/iUiePUAQKN4GY6jorH9m23cbVli.jpg"
}
]
}
I know two solutions to solve this :
What you've done : Wrapping the list using a class
Write you're own JSON Deserializer, take a look here http://wiki.fasterxml.com/JacksonHowToCustomDeserializers
But I think the ultimate solution is in this post:
Spring/json: Convert a typed collection like List<MyPojo>
If Cast is a POJO you could try use the Jackson ObjectMapper class like this
ObjectMapper mapper = new ObjectMapper();
String jsonStr = ...
List<Cast> casts = mapper.readValue(jsonStr, new TypeReference<List<Cast>>(){});
You can grab the field, cast, and convert it like so:
final String json = "{\n" +
" \"id\": 550,\n" +
" \"cast\": [\n" +
" {\n" +
" \"cast_id\": 4,\n" +
" \"character\": \"The Narrator\",\n" +
" \"credit_id\": \"52fe4250c3a36847f80149f3\",\n" +
" \"id\": 819,\n" +
" \"name\": \"Edward Norton\",\n" +
" \"order\": 0,\n" +
" \"profile_path\": \"/iUiePUAQKN4GY6jorH9m23cbVli.jpg\"\n" +
" }\n" +
" ]\n" +
"}";
final List<Cast> casts;
try {
final JsonNode cast = objectMapper.readTree(json).get("cast");
casts = objectMapper.convertValue(cast, new TypeReference<List<Cast>>() {});
} catch (IOException e) {
throw Throwables.propagate(e);
}