I tried to submit data to an endpoint but it said the data size was too large, so I changed the method to POST and received the error:
This API does not support parsing form-encoded input.
Next I changed the type to application/json, still with post and now I am getting:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "parseError",
"message": "Parse Error"
}
],
"code": 400,
"message": "Parse Error"
}
}
What is the best way to post a large amount of data, i.e. 2730 bytes to an endpoint and have it handle it properly? In my case the field in question is of type Text as I am over the 500 character limit for app engine to hold in a String.
Also, as with many things, this works great on my local machine, it only gives this error on the live app engine instance.
Thanks!
Not sure if your problem is related, but I received the "This API does not support parsing form-encoded input." error when I was attempting to use curl to send a POST message like this:
curl -X POST -d '{"name": "Foo"}' http://foo.appspot.com/_ah/api/foo/1/endpoint
The problem was that I was not setting the content type. curl POSTs with Content-Type: application/x-www-form-urlencoded if it's not specified on the command line. Google cloud endpoints don't accept this content type.
When I changed the curl invocation to include the content type, it worked:
curl -X POST -d '{"name": "Foo"}' --header "Content-Type: application/json" http://foo.appspot.com/_ah/api/foo/1/endpoint
Related
I am trying to implement call functionality using nexmo api in my spring MVC project, but I keep on getting the below exception
com.vonage.client.VonageResponseParseException: Unable to parse response.
at com.vonage.client.AbstractMethod.execute(AbstractMethod.java:105) ~[client-6.1.0.jar:6.1.0]
at com.vonage.client.voice.CallsEndpoint.post(CallsEndpoint.java:57) ~[client-6.1.0.jar:6.1.0]
at com.vonage.client.voice.VoiceClient.createCall(VoiceClient.java:61) ~[client-6.1.0.jar:6.1.0]
.............................
Caused by: org.apache.http.client.HttpResponseException: Bad Request
at org.apache.http.impl.client.AbstractResponseHandler.handleResponse(AbstractResponseHandler.java:69) ~[httpclient-4.5.1.jar:4.5.1]
at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:65) ~[httpclient-4.5.1.jar:4.5.1]
at com.vonage.client.voice.CreateCallMethod.parseResponse(CreateCallMethod.java:57) ~[client-6.1.0.jar:6.1.0]
at com.vonage.client.voice.CreateCallMethod.parseResponse(CreateCallMethod.java:32) ~[client-6.1.0.jar:6.1.0]
at com.vonage.client.AbstractMethod.execute(AbstractMethod.java:102) ~[client-6.1.0.jar:6.1.0]
... 51 more
Below is my code logic
VonageClient client = VonageClient.builder().applicationId(APPLICATION_ID).privateKeyContents(PRIVATE_KEY).build();
Ncco ncco = new Ncco(TalkAction.builder("message").build());
Call call = new Call(TO_NUMBER, FROM_NUMBER, ncco);
CallEvent result = client.getVoiceClient().createCall(call);
Although inbound calls work using curl command below
curl -X POST https://api.nexmo.com/v1/calls\
-H "Authorization: Bearer "$JWT\
-H "Content-Type: application/json"\
-d '{"to":[{"type": "phone","number": "TO_NUMBER"}],
"from": {"type": "phone","number": "FROM_NUMBER"},
"ncco": [
{
"action": "talk",
"text": "This is a text to speech call from Vonage"
}
]}'
The code provided here appears to work fine on the 5.6.0 version of the nexmo client - I would make sure you're all the way up to date.
That error is suggesting that the content being passed to the nexmo API is bad so it's probably worth turning on some logging if this continues to be a problem after upgrading here's an example of how to turn on logging. this will allow you to see exactly what it's passing along and perhaps find out what the issue is.
This question already has answers here:
HttpMediaTypeNotAcceptableException: Could not find acceptable representation in exceptionhandler
(2 answers)
Closed 2 years ago.
I have the following controller class:
#RestController
#RequestMapping(value = "/query")
public class QueryController {
#Autowired
private QueryService queryService;
// this post API works perfectly fine
#PostMapping(value = "/submit")
public void submitQuery(#Valid #RequestBody Query query) {
queryService.submit(query);
}
// this API is throwing the error
#GetMapping(value = "/find/email/{email:.+}")
public List<Query> fetchByEmail(#PathVariable("email") String email) {
return queryService.fetchByEmail(email);
}
}
I am sending the the following cURL request:
curl -X GET http://localhost:8562/query/find/email/abc#gmail.com -H 'Content-Type: application/json'
In the debug mode, I can see the request has arrived at the controller with the expected emailId that I have sent in the request. The DAO layer search has also happened and it has returned 1 record, but the API throws the following error:
{
"timestamp": 1569655451392,
"status": 406,
"error": "Not Acceptable",
"message": "Could not find acceptable representation",
"path": "/query/find/email/abc#gmail.com"
}
Can someone please help?
Note: I am using springBootVersion = '2.0.5.RELEASE'
Edit: The GET API is the one that is throwing the error. Any request that does not have the dot character (.) works fine. The following request does not throw any error:
curl -X GET http://localhost:8562/query/find/email/abc#gmail -H 'Content-Type: application/json'
Edit-2: Attaching the debug screenshot below:
From this point, if I run the code, I get the following error:
{"timestamp":1569657676774,"status":406,"error":"Not Acceptable","message":"Could not find acceptable representation","path":"/query/find/email/rishi2893#gmail.com"}
HTTP 406 Not-Acceptable means that the server cannot produce a response in a format that the client can understand.
You have to send the Accept header so as to notify the server for the acceptable formats that your client can understand and to ensure that your server can produce such formats.
curl -H "Accept: application/json" ...
In addition to the above, when the Content-Type header is sent in a request, it specifies the media type of the request being sent from the client. A Content-Type header should be used in POST/PUT requests. It does not make sense in a GET request as you should not have a body in such requests.
In this ElasticSearch document it explains how to submit a query:
GET /_search
{
"query": {
"match" : {
"message" : "this is a test"
}
}
}
But a GET doesn't have a body, it's just a link to get a document.
The related CURL in the documentation:
curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"match" : {
"message" : "this is a test"
}
}
}
'
If I read the meaning of -d in CURL documentation, it says
-d, --data
(HTTP) Sends the specified data in a POST request to the HTTP server,
in the same way that a browser does when a user has filled in an HTML
form and presses the submit button.
Meaning that the GET should be converted to a POST? I'm confused, from a Java program do I need to submit a GET or a POST to the ElasticSearch engine?
Elasticsearch _search endpoint does support GET and POST Request Type, as GET does not work with every programm. So you can just use POST instead.
I am making a curl request to endpoint with following option curl --data {"foo" : "bar"} for POST request
However I want to implement a default behavior for missing data, ie curl without --data should also work for POST request.
Currently if data is missing it returns: "error":400,"errorCode":"INVALID_JSON". I do not want that.
Is it possible ?
Does it have any annotation to support optional data.?
This question already has answers here:
HTTP GET with request body
(23 answers)
Closed 7 years ago.
I don't understand why this curl invocation gives me a 400 bad request.
curl -v -XGET -H "Content-Type:application/json" -d '{"match":{"first":"james"}}' http://localhost:8080/geocon/search/
Considered that this is the code part who should handle everything
#Path(Paths.SEARCH)
public class SearchService {
#GET
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public String search(#DefaultValue(NO_TYPE) #QueryParam("type") String type, String query) {
// do interesting stuff with the query
System.out.println(type);
System.out.println(query);
return //the result of the query
}
Obviously, I don't see in the console the two print lines and the answer from the web service is 400 Bad request
If I change the verb in curl and in the code (POST instead of GET), the results are OK and everything works as it should.
Why?
Can't I use GET passing data? If you think about it, I am not modifying stuff, I'd just receive data so GET should be the most RESTful translation for it.
You are allowed to send a body with a GET request, but it must not have any semantics; it should essentially be ignored. Not doing so violates the HTTP/1.1 specification. I suggest avoiding this practice because no one expects a request body with a GET request.
Now I'm not sure if the MVC framework you're using is stricter in the sense that it automatically rejects any GET request sent with a body, because in general a server can accept a GET request with a body, but is just supposed to ignore it.
Hence, what you're doing is not RESTful. The only way you can pass in data through a GET is through query parameters.
UPDATE
This is in response to your comment.
You could expose an explicit resource called searchResult or search. To create a searchResult or search resource instance, you pass in a body that is essentially a query. If you are using semantic media types (as you should for proper RESTfulness), your search-result resource could have the media type application/vnd.myservice.search-result+json and the query can have the media type application/vnd.myservice.search-query+json. Then, you can POST a request to /searchResults that has a request body that contains the complex query. The media-type of the response would be application/vnd.myservice.search-result+json and it can contain the search results.
So how does this play out? A search query comes in and you parse out the body and run the query. Then you should persist the results (not for ever; give it some sane TTL value). Once you have done that, you return a 303 See Other with a Location header that has a link to the search results (maybe something like /searchResults/4334, where 4334 is the id of this particular result). The client can then access this URI to retrieve the search results. If the client requests a search result that has expired (i.e., the server cleaned it up because the TTL expired), then the server should respond with a 410 Gone.
Also read this for more pointers.
It seems that syntax you are using has a typo.Try using the below ones for json and xml format. -XGET is wrong. it should be -X GET.
For xml
curl -H "Accept: application/xml" -H "Content-Type: application/xml" -X GET http://hostname/resource
For JSON
curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET http://hostname/resource