Receiving Unexpected Token Error When Passing Graphql query as JSON string - java

Thanks in advance for the help. I'm testing a GRAPHQL API using rest assured on testng in java.
I am trying to send agraphQL object disguised as JSON as a post, but when trying to package the string up as a JSON object I am getting the following error:
SyntaxError: Unexpected token B<br> at Object.parse (native)<br> at parse (/app/node_modules/body-parser/lib/types/json.js:88:17)<br> at /app/node_modules/body-parser/lib/read.js:116:18<br> at invokeCallback (/app/node_modules/raw-body/index.js:262:16)<br> at done (/app/node_modules/raw-body/index.js:251:7)<br> at IncomingMessage.onEnd (/app/node_modules/raw-body/index.js:307:7)<br> at emitNone (events.js:80:13)<br> at IncomingMessage.emit (events.js:179:7)<br> at endReadableNT (_stream_readable.js:913:12)<br> at _combinedTickCallback (internal/process/next_tick.js:74:11)<br> at process._tickDomainCallback (internal/process/next_tick.js:122:9)
The JSON object I am trying to create is here:
"{\"query\":\"{marketBySlug(slug: \"Boston\") {countryCode}}\"}"
I've figured out that my problem is the escaped quotes identifying Boston as a string are breaking the internally constructed Graphql query string, but I'm not sure how to get around this.

Try this:
"{\"query\":\"{marketBySlug(slug: \\\"Boston\\\") {countryCode}}\"}"

Instead of messing with strings and escaping, you should use parameterized queries. Your code will look like this:
String query =
"query MarketBySlug($slug: String!) {\n" +
" marketBySlug(slug: $slug) {\n" +
" countryCode\n" +
" }\n" +
"}";
Map<String, Object> variables = new HashMap<>();
variables.put("slug", slug);
given()
.body(new QueryDto(query, variables))
.when()
.post("/graphql")
.then()
.contentType(JSON)
.statusCode(HttpStatus.OK.value())
.body("data.marketBySlug.countryCode", equalTo(countryCode));
QueryDto is just a simple dto with the two fields (query and variables), setters and getters.

Related

ElasticSearch SearchTemplate request Java API

I'm stuck with a SearchTemplate request, until now I've been able to write queries through the QueryBuilder and execute them calling the "search" method of the RestHighLevelClient java client, but when I try to execute the searchTemplate method I get a parse exception from the server "request body or source parameter is required".
So far I've been reading the documentation but nothing, the guide about the SearchTemplate is very poor.
This is how I'm currently trying to follow the basic steps from the official documentation:
SearchTemplateRequest request = new SearchTemplateRequest();
request.setRequest(new SearchRequest(indexPI));
request.setScriptType(ScriptType.INLINE);
request.setScript( "{" +
" \"query\": { \"match\" : { \"{{field}}\" : \"{{value}}\" } }," +
" \"size\" : \"{{size}}\"" +
"}");
Map<String, Object> scriptParams = new HashMap<>();
scriptParams.put("from","");
scriptParams.put("size","");
scriptParams.put("field", "title");
scriptParams.put("value", "elasticsearch");
scriptParams.put("size", 5);
request.setScriptParams(scriptParams);
SearchTemplateResponse response = elasticSearchClient.searchTemplate(request,
RequestOptions.DEFAULT);
The error I get:
Elasticsearch exception [type=parse_exception, reason=request body or source parameter is required]
At this point, I'm trying to understand how to set the request body for the above request and actually wondering if it is possible to do.
Any clue about what is missing besides the "unsettable" request body from the exception?

elasticsearch wildcard search java

I am using java low level REST client api.
I am fetching particular fields on matching or related datas from elasticsearch by using wildcards.
I am struck with it getting data as well as searching data with wildcard.
How to fetch result in java list .
Here is my code:
HttpEntity entity1 = new NStringEntity( "{\n" + " \"query\" : {\n" + " \"wildcard\": { \"Content\":\"java *\"} \n" + "} \n"+ "}",ContentType.APPLICATION_JSON);
Response response = restClient.performRequest("GET", "/test/_search",Collections.singletonMap("pretty", "true"), entity1);
System.out.println(EntityUtils.toString(response.getEnti‌​ty()));
Could you please help me out? Thank you!

Getting an unespected extra escape character on Java Restful API JSON result string

I am creating a restful api(service) using maven and jersey. My Repository attributeMasterRepository retuns the data in String format.
JSONObject attribute = new JSONObject();
attribute.put("Product_Brand", attributeMasterRepository.getProductBrand(cluster, CouchbaseBucket.RangePlan));
attribute.put("Product_Type", attributeMasterRepository.getProductType(cluster, CouchbaseBucket.RangePlan));
String attributeStr = "[" + attribute.toString() + "]";
return attributeStr;
My above code in the Service layer returns an unexpected "\" on the string.
I need to get rid of the "\".
Here is my Output:
{
"Product_Type":
"[{\"active\":true,\"description\":\"ALL IN ONES\",\"id\":2},
{\"active\":true,\"description\":\"ACCESSORIES\",\"id\":1}]",
"Product_Brand":
"[{\"active\":false,\"brand\":\"101 DALMATIANS\",\"id\":1}]"
}
Could you please let me know on how to get the "\" removed.
Thanks,
IRK
You did not state which libraries you use, but also you can just replace the \ characters:
json.replaceAll("\\\\", "");
Similar questions:
Removing "\" in json object string
JSONObject.toString: how NOT to escape slashes

How to return JsonArray in a Java Response object

I'm trying to implement java based web-service server which returns to Json and java script based web-service client. Here is my java part :
#Path("/myapp")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public class MyRecommender {
#POST
#Path("/recs")
public Response getRecommendations() {
//Assume recommendation List contains some Recommendation objects
//I removed it for simplicity.
List<Recommendation> recommendation;
JsonArrayBuilder builder = Json.createArrayBuilder();
for (Recommendation rec : recommendations) {
builder.add(Json.createObjectBuilder().add("firstPersonName", "\"" + rec.getFirstPerson().getName() + "\"")
.add("firsPersonURL", "\"" + rec.getFirstPerson().getURL() + "\"")
.add("secondPersonName", "\"" + rec.getSecondPerson().getName() + "\"")
.add("secondPersonURL", "\"" + rec.getSecondPerson().getURL() + "\"")
.add("score", "\"" + rec.getSimilarity() + "\""));
}
JsonArray jsonData = builder.build();
return Response.ok(jsonData, MediaType.APPLICATION_JSON).header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "POST").allow("OPTIONS").build();
}
}
}
Now, when I call this function from my js client, I got :
POST http://localhost:8080/myapp/recs 500 (Request failed.)
But when I replace the for loop and return with the following code snipped I got response in my js correctly.
Changed part :
// remove for loop and change jsonData type.
String jsonData = "{\"name\":\"John\"}";
return Response.ok(jsonData, MediaType.APPLICATION_JSON).header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "POST").allow("OPTIONS").build();
So, I wonder what might be problem ? Since its my first time with web-services, I have some difficulty to debug my code.
EDIT
By the way, I get also another error when I try to first version of getRecommendations() functions(with loop)
XMLHttpRequest cannot load http://localhost:8080/myapp/recs.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:3000' is therefore not allowed access.
The response had HTTP status code 500.
But as I said, When I remove the loop and put second code snipped into getRecommendations() functions, both of the errors are gone and I get the response in my website.
EDIT2
When I changed the loop and return statement of getRecommendations() function with the below I again get the same errors
JsonObject value = Json.createObjectBuilder()
.add("name", "John").build();
return Response.ok(value, MediaType.APPLICATION_JSON).header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "POST").allow("OPTIONS").build();
EDIT 3
As far as I understood, createObjectBuilder().build() or JsonArrayBuilder.build() return an JSON object and below of this build statement in my getRecommendations() function is not even run. So, I think my problem how could I give Access-Control-Allow-Origin permission to this object?
If it is ok to use a third Party Library, using Google's Gson could be an efficient solution in this case. When converting Models to JSON it is quite handy.
What you can do is something like this.
ArrayList<Recommendation> recommendationList = new ArrayList<Recommendation>();
Gson gson = new Gson();
String jsonData = gson.toJson(reccomendationList);
To use it as a dependency in your POM file you could do this.
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.3.1</version>
<scope>compile</scope>
</dependency>
You should try simplest approach:
return Response.ok().entity(recommendation).header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "POST").allow("OPTIONS").build();

Java : How to handle POST request without form?

I'm sending a http post request from javascript, with some json data.
Javascript
var data = {text : "I neeed to store this string in database"}
var xhr= new XMLHttpRequest();
xhr.open("POST","http://localhost:9000/postJson" , true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
xhr.send(data);
xhr.setRequestHeader("Connection", "close");
//Also, I've tried a jquery POST
//$.post('postJson', {'data=' : JSON.stringify(data)});
//But this doesn't make a request at all. What am I messing up here?
Route
POST /postJson controllers.Application.postJson()
Controller
public static Result postJson(){
//What should I write here to get the data
//I've tried the below but values is showing null
RequestBody rb=request().body();
final Map<String,String[]> values=rb.asFormUrlEncoded();
}
What is the way to parse the POST request body?
Much thanks!
Retreive the request body directly as JSON... no need to complicate your life.
public static Result postJson() {
JsonNode rb = request().body().asJson();
//manipulate the result
String textForDBInsertion = rb.get("text").asText(); //retreives the value for the text key as String
Logger.debug("text for insertion: " + textForDBInsertion
+ "JSON from request: " + rb);
return ok(rb);
}
Also, I recommend you use the AdvancedRestClient Chrome plugin for testing. This way you can eliminate from the equation client-side code errors.
Cheers!

Categories