Grails - JSON param request not passing to controller - json

I would like to pass a JSON to my requete.
But not possible to find the JSON.
#Secured(['ROLE_STUDENT'])
def validate() {
println params
println request.JSON
}
Result :
[controller:student, action:validate, id:2345444]
[:]
URL :
curl -i -H "Content-Type: application/json" -X POST -d '{"studentScores":[{"id":"2","score":"17"}],"comment":"good"}' 'http://localhost:8080/myapp/studient/2345444/validate' -H 'Cookie: JSESSIONID=3CCDC701553A2208428BB7135DDA5546'
I tried with GET and POST, and with à JQuery
$.ajax({
url: urlSubmit,
type: 'POST',
data: JSON.stringify(student),
contentType:"application/json; charset=utf-8",
dataType: "json"
});
Grails 2.4.4
Java 8 (compliance level java 7)
Tomcat 8
Some plugins :
spring-security-core:2.0-RC4
spring-security-facebook:0.16.2
spring-security-oauth2-provider:2.0-RC2
Need your help

See this: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html (9.3 GET).
The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI
Request-URI being the important part here. There is no concept of body data in a GET requests.
So, change to POST and your request should work.

For first u have an error in your url in curl :)
http://localhost:8080/myapp/STUDIENT/2345444/validate
try this code
def json = JSON.stringify(params)
but I don't sure.

Related

Getting bad request error with alamofire JSON request

I have been converting this curl syntax
curl -L -X POST 'https://driver-vehicle-licensing.api.gov.uk/vehicleenquiry/v1/vehicles' \-H 'x-api-key: REPLACE WITH YOUR API KEY' \-H 'Content-Type: application/json' \-d '{"registrationNumber": "TE57VRN"}'
into Swift with Alamofire and have got this syntax
guard let url = URL(string: "https://driver-vehicle-licensing.api.gov.uk/vehicle-enquiry/v1/vehicles") else { return }
let headers : HTTPHeaders = [
"x-api-key": "mykey",
"Content-Type": "application/json"
]
let params: Parameters = [
"registrationNumber" : "myreg"
]
AF.request(url, method: .post, parameters: params, encoding: URLEncoding(destination: .httpBody), headers: headers).responseJSON(completionHandler: { response in
print(response)
})
However, I have got the output
success({
errors = (
{
code = ENQ103;
detail = "Invalid format for field - vehicle registration number";
status = 400;
title = "Bad Request";
}
);
Please could someone explain what I have done wrong. Thanks
The API expects the parameters to be sent as JSON, but you are sending as URL encoded.
Try using JSONParameterEncoder.default as the encoder instead of URL encoding.
Check Usage from the docs: POST request with JSON Parameters
let parameters: Parameters = [
"registrationNumber" : "myreg"
]
AF.request(url, method: .post, parameters: parameters, encoder: JSONParameterEncoder.default)
You have a working curl command, small (or big) tip: AlamoFire can print the request as a curl command!
In "one step":
AF.request(url, method: .post,
parameters: params,
encoding: URLEncoding(destination: .httpBody),
headers: headers)
.cURLDescription(calling: { curlCommand in
print("curlCommand1: \(curlCommand)")
}).responseJSON(completionHandler: { response in
print(response)
})
In "two steps", if you prefer to separate your calls and not chain them all:
let request = AF.request(url, method: .post,
parameters: params,
encoding: URLEncoding(destination: .httpBody),
headers: headers)
request.cURLDescription { curlCommand in
print("curlCommand2: \(curlCommand)")
}
request.responseJSON(completionHandler: { response in
print(response)
})
And you should have output:
curl -v \
-X POST \
-H "Accept-Encoding: br;q=1.0, gzip;q=0.9, deflate;q=0.8" \
-H "User-Agent: Alamofired/1.0 (...; build:1; iOS 14.5.0) Alamofire/5.4.0" \
-H "Accept-Language: en;q=1.0, fr-US;q=0.9" \
-H "Content-Type: application/json" \
-H "x-api-key: mykey" \
-d "registrationNumber=myreg" \
"https://driver-vehicle-licensing.api.gov.uk/vehicle-enquiry/v1/vehicles"
Now, if we compare with yours:
curl \
-L \
-X POST \
'https://driver-vehicle-licensing.api.gov.uk/vehicleenquiry/v1/vehicles' \
-H 'x-api-key: REPLACE WITH YOUR API KEY' \
-H 'Content-Type: application/json' \
-d '{"registrationNumber": "TE57VRN"}'
I added some \ to make it sill valid...
We shouldn't care about the order, the "Accept-Language", "User-Agent", "Accept-Encoding" headers that are added with Alamofire shouldn't be an issue.
Try your command with no -L parameter maybe to check if it's "important" (if it's --location).
And then, the difference is with the data paramater (-d). Once is JSON, the other is URL encoded.
Then, let's see your code, and URLEncoding(destination: .httpBody)
might be the culprit. Using JSONEncoding.default instead will work.
Now, if you didn't have had the curl command, just by seeing your code, I spotted it. If you think about it:
You are saying there that you will provide the parameter in body following the JSON protocol.
let headers : HTTPHeaders = ["Content-Type": "application/json"]
And later, you used URL Encoding protocol.
URLEncoding(destination: .httpBody)
Doesn't make sense, right? You're contradicting yourself.

Curl request to ansible playbook

Sample curl request.
curl -X POST \
--data '"test connection"' \
-H 'Content-type: application/json' \
-H 'Authorization: Basic asdfasdf' \
dns.com/end
Now, I'd like to send exactly the same message using curl ansible playbook.
---
- name: "Send test"
hosts: localhost
tasks:
- name: Send test
uri:
url: dns.com/end
method: POST
src: '"test connection"'
body_format: json
headers:
Content-type: "application/json"
Authorization: "Basic asdfasdf"
I'm getting an error.
You should be using the body parameter instead of src. Also, the header should be Content-Type instead of Content-type.
Just to add src is used when you want to submit the data from a file.
Solution will look something like
tasks:
- name: Send test
uri:
url: dns.com/end
method: POST
body: "test connection"
headers:
Content-Type: "application/json"
Authorization: "Basic asdfasdf"
You have mentioned body format as json and you are not passing any body to it.
You body.json file should contain something like this:
{
"name": "test connection"
}
and also you can mention status_code=201 for POST method.

(400) Bad Request when trying to send an image to my custom AutoML model via the REST API

I'm trying to implement my custom AutoML model in C# by sending images via the REST API, but I keep getting different errors.
The one I currently have is:
The remote server returned an error: (400) Bad Request.
I have taken an image and converted into a string of bytes called byteString and have created the jsonRequest object like this:
string jsonRequest = "{\"payload\":{\"image\":{\"imageBytes\":\"" + byteString + "\"},}}";
Then I'm doing a POST request like follows:
WebRequest request = WebRequest.Create(#"https://automl.googleapis.com/v1beta1/projects/PROJECT_ID/locations/us-central1/models/MODEL_ID:predict");
request.Method = "POST";
request.ContentType = "application/json";
request.Headers.Add("Authorization", "Bearer GCLOUD_ACCESS_TOKEN");
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(jsonRequest);
}
Then when it hits request.GetResponse(); if gives me the above error with no other information.
For reference, these are the snippets taken from the bottom of the PREDICT page on my custom AutoML model:
request.json:
{
"payload": {
"image": {
"imageBytes": "YOUR_IMAGE_BYTE"
},
}
}
Execute the request:
curl -X POST -H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
https://automl.googleapis.com/v1beta1/projects/PROJECT_ID/locations/us-central1/models/MODEL_ID:predict -d #request.json
Thanks guys, been stuck on this for a while.
Can you try to base64 the byte string? This is mentioned here.
In my use case, I share my vision model to my colleagues by creating a service account for them with the right role and give them this URL for prediction:
curl -X POST -H "Authorization: Bearer add_access_token " -H "Content-Type: application/json" https://automl.googleapis.com/v1beta1/projects/id_project/locations/us-central1/models/:model_idpredict -d #path_of_file_image_in_base64
I was able to solve this with RestSharp(https://www.nuget.org/packages/RestSharp) library
Example:
var client = new RestClient("https://automl.googleapis.com/v1beta1/projects/{project-id}/locations/us-central1/models/{model-id}:predict":
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", $"Bearer {Access-Token}");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"payload\":{\"image\":{\"imageBytes\":\"{Image-Base64}""}}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

Curl - POST request using JSON with query parameter

I have a URL https://mylink/apply?data= for a server which accepts the data variable as valid JSON of following properties:-
name: String with your name (required)
email: String with your email address (required)
urls: Array of strings with links
comment: String with any comment/request you might have (optional)
My JSON file "data.json" is the following:
{
"data":
{
"name": "Rogers Bell",
"email": "xxxx#gmail.com",
"urls":["https://stackoverflow.com/users/3067241/imran", "https://github.com/i4ali"],
"comment":"none"
}
}
When I use the following CURL command to send a POST request, I get error code 400 Bad Request with a message from the server Error: no data passed. indicating something wrong with my JSON format or command. Not sure what I am doing wrong here
curl -v -i -X POST -d #data.json https://mylink/apply?data= -H "Accept: application/json" -H "Content-Type: application/json" -k
I am using Windows 7 if that matters
The API is pretty weird. But if you have to read JSON file and POST its content to server as URL parameter, you can cat the file, encode it and send it in curl. Here is an example:
curl -G -X POST https://requestb.in/1n88lah1 --data-urlencode data="$(cat input.json)"
The input.json would look like:
{
"name": "Rogers Bell",
"email": "xxxx#gmail.com",
"urls":["https://stackoverflow.com/users/3067241/imran", "https://github.com/i4ali"],
"comment":"none"
}
Using Postman I was able to send this POST request with the following complete URL. Got a 200 OK response
https://mylink/apply?data={
"name": "Rogers Bell",
"email": "xxxx#gmail.com",
"urls":["https://stackoverflow.com/users/3067241/imran", "https://github.com/i4ali"],
"comment":"none"
}

How to post a json for a particular parameter using CURL

I try to do a POST request which contains number of parameters. One parameetr require a JSON file. I tried several options but i face issue with json. The parameter which requires json is 'swagger'..
Here is the curl request I try.[1] But looks like this is not accepted by server. Im getting following error;
"null is not supported"}curl: (6) Could not resolve host: swaggerimpl.json
How can i post the JSON using curl for a particular parameter?
[1]
curl -X POST -b cookies $SERVER/publisher/site/blocks/item-design/ajax/add.jag -d "action=implement&name=YoutubeFeeds&visibility=public&version=1.0.0&provider=admin&endpoint_type=http&implementation_methods=http&wsdl=&wadl=&endpointType=nonsecured&production_endpoints=http://gdata.youtube.com/feeds/api/standardfeeds&implementation_methods=endpoint" -H 'Content-Type: application/json' -d 'swagger=' #swaggerimpl.json
Edit :
Curl Command
curl -X POST -b cookies $SERVER/publisher/site/blocks/item-design/ajax/add.jag -d "action=implement&name=YoutubeFeeds&visibility=public&version=1.0.0&provider=admin&endpoint_type=http&implementation_methods=http&wsdl=&wadl=&endpointType=nonsecured&production_endpoints=http://gdata.youtube.com/feeds/api/standardfeeds&implementation_methods=endpoint" -d #swagger_impl.json -d #endpointconfig_impl.json;
Error;
at java.lang.Thread.run(Thread.java:695)
Caused by: java.lang.ClassCastException: org.mozilla.javascript.NativeJavaArray cannot be cast to java.lang.String
at
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
The suspect json file
swagger={
"apiVersion": "1.0.0",
"swaggerVersion": "1.2",
"authorizations": {
"oauth2": {
"scopes": [],
"type": "oauth2"
}
},
.........
}
The cast code:
public static boolean jsFunction_updateAPIImplementation(Context cx, Scriptable thisObj,
Object[] args, Function funObj) throws Exception, ScriptException {
boolean success = false;
if (args==null||args.length == 0) {
handleException("Invalid number of input parameters.");
}
NativeObject apiData = (NativeObject) args[0]; //This cause issue
Parameter that you are adding at the end should not contain the space. But if you remove this space then '#swagger.json' will be added as a test (not the file content). If you want to pass JSON as a parameter then you can add to the file parameter name like:
swagger={..}
It looks like workaround but curl will merge every -d parameter into the request parameters and it doesn't allow unquoted spaces.