I can't seem to get the POST parameters to come through from an AJAX javascript POST. The error is:
#6angl7689 - Internal server error, for request [POST /myRoute] ->
play.core.ActionInvoker$$anonfun$receive$1$$anon$1: Execution exception [[NoSuchElementException: None.get]]
Route:
POST /myRoute controllers.Application.testPost
Controller code:
def myForm = Form(
tuple(
"valOne" -> text,
"valTwo" -> text))
def testPost() = Action { implicit request =>
val (valOne, valTwo) = myForm.bindFromRequest.get // Errors here
println("valOne: " + valOne)
println("valTwo: " + valTwo)
Ok
}
CoffeeScript client-side:
params =
valOne: 'valOne'
valTwo: 'valTwo'
$.ajax
type: 'POST'
url: '/myRoute'
data: params
Update your client code,
$.ajax(
type: 'POST'
url: '/myRoute'
data: {valOne: 'valOne', valTwo: 'valTwo'}
);
This should work
Related
I am trying to call Microsoft Graph API on groovy script using Java libraries. However, even though partly success, I still have some serious issues using it within my current project, so I think about trying to call the the REST API using groovy-wslite.
This is my current code for getting access token:
def authorizeHost = "https://login.microsoftonline.com"
def authorizePath = "/${azureSetting.getTenantID()}/oauth2/v2.0/authorize?"
try {
RESTClient client = new RESTClient(authorizeHost)
def params = [
"client_id":azureSetting.getClientID(),
"scope": "https://graph.microsoft.com/.default",
"response_type": "code"
]
def response = client.post(
path: authorizePath,
)
{
type ContentType.JSON
json params
}
LOGGER.info("Success: " + (response.statusCode == 200));
LOGGER.info("Output: (" + response.contentType + ") " + response.text);
} catch (RESTClientException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
LOGGER.info("Error: " + sw.toString());
}
The response from the log:
AADSTS900144: The request body must contain the following parameter: 'client_id'.
How can I change the above code, so that Microsoft Graph REST API can recognize my sending content and send back the access token.
UPDATE: After trying around, I found out that the body os post method should be as below:
type "application/x-www-form-urlencoded"
urlenc client_id: azureSetting.getClientID(),
scope: "https://graph.microsoft.com/.default",
response_type: "code"
according to doc https://learn.microsoft.com/en-us/graph/auth-v2-user#token-request your request should have Content-Type: application/x-www-form-urlencoded
you are trying to send json instead
here is your code but pointing to a test httpbin.org server and it could show what exactly you are sending to server
there is a minor change: ContentType.JSON -> ContentType.URLENC
#Grab(group='com.github.groovy-wslite', module='groovy-wslite', version='1.1.3', transitive=false)
import wslite.rest.*
//just for test
def azureSetting = [ getClientID:{-> "12345"} ]
def LOGGER = [info:{x-> println x}]
//redefined host and url
def authorizeHost = "HTTP://httpbin.org"
def authorizePath = "/post"
try {
RESTClient client = new RESTClient(authorizeHost)
def params = [
"client_id":azureSetting.getClientID(),
"scope": "https://graph.microsoft.com/.default",
"response_type": "code"
]
def response = client.post(
path: authorizePath,
)
{
type ContentType.URLENC // <-- THE ONLY CHANGE IN YOUR CODE
json params
}
LOGGER.info("Success: " + (response.statusCode == 200));
LOGGER.info("Output: (" + response.contentType + ") " + response.text);
} catch (RESTClientException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
LOGGER.info("Error: " + sw.toString());
}
I have this code as client for a POST API
#Produces("image/png")
#Post("/marketplaces/{marketplaceId}/banking/accreditation/holders/{holderId}/documents?type={type}")
fun saveIndividualDocumentHolder(
#Header("Authorization") authorization: String,
#PathVariable marketplaceId: String,
#PathVariable holderId: String,
#PathVariable type: String,
#Body image: String
): HttpResponse<HolderDocumentResponse>
The API expects an image file as "image/png", "image/jpg". I am getting {415 Unsupported media type: text/plain"}
I send 'the file' using:
fun saveIndividualDocumentHolder(holderId: String, type: String, file: MultipartBody): HttpResponse<HolderDocumentResponse> {
val contentType = "image/png"
val httpResponse = client.saveIndividualDocumentHolder(authorization, marketplaceId, holderId, type, file.toString())
if (httpResponse.status != HttpStatus.CREATED) throw RuntimeException("HTTP status: ${httpResponse.status}" )
val response = httpResponse.body()?: throw RuntimeException("No body")
return httpResponse
}
I have picked the file from my 'internal endpoint' using MultipartBody. Then I convert this file to a String as Body request.
I am new to all these things, could you please elucidate?
I am using a rest client to do Post
My code is
def postRequest() {
def message = "{ \"fields\": { \"project\": { \"id\": \"001\" },\"summary\": \"Test Issue For Jira Integration\",\"description\": \"Creating of an issue for for projects and issue types using the REST API\", \"issuetype\": { \"id\": \"5\" } }}"
// POST
def post = new URL("https://jira/rest/api/latest/issue").openConnection();
//def message = '{"message":"this is a message"}'
post.setRequestMethod("POST")
String userpass = "user:pass" ;
String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userpass.getBytes()));
post.setRequestProperty ("Authorization", basicAuth);
post.setDoOutput(true)
post.setRequestProperty("Content-Type", "application/json")
post.getOutputStream().write(message.getBytes("UTF-8"));
def postRC = post.getResponseCode();
println(postRC);
if(postRC.equals(201)) {
println(post.getInputStream().getText());
}else
{
println(post.getInputStream().getText());
print(postRC)
}
}
I am getting 400 error code , where its getting wrong
I am successfully able to do the get request with URL
400 = bad request.
it means server tried to validate your post data and it's wrong.
usually this response contains body with explanation...
for 400+ status codes the body comes through getErrorStream() and not through getInputStream()
So, I would do it like this:
def postRequest(url, message) {
def post = new URL(url).openConnection();
//def message = '{"message":"this is a message"}'
post.setRequestMethod("POST")
String userpass = "user:pass" ;
String basicAuth = "Basic " + userpass.getBytes("UTF-8").encodeBase64()
post.setRequestProperty("Authorization", basicAuth);
post.setRequestProperty("Content-Type", "application/json")
post.setDoOutput(true)
if( !(message instanceof String) )message = new groovy.json.JsonBuilder(message).toPrettyString()
post.getOutputStream().write(message.getBytes("UTF-8"))
def response=[:]
response.code = post.getResponseCode()
response.message = post.getResponseMessage()
if( response.code>=400 ){
try{
response.body = post.getErrorStream()?.getText("UTF-8")
}catch(e){}
}else{
response.body = post.getInputStream()?.getText("UTF-8")
}
assert response.code in [200,201] : "http call failure ${response.code}: ${ response.body ?: response.message }"
return response
}
def msg = [
fields: [
project : [ id: "001" ],
summary : "Test Issue For Jira Integration",
description : "Creating of an issue for for projects and issue types using the REST API",
issuetype : [ id: "5" ]
]
]
def r = postRequest("http://httpbin.org/post", msg)
println r
The issue was related to certificate , I have to bypass the certificate validation and its working fine. Since both the application are under same network and behind same company's firewall , I have bypass the certificate validations.
Adding the skipping certificate validation part to the above code is working for me
Although the problem seems to be easy, but I am unable to get a OK 200 response while trying to register an Instance.
def register(InstanceString: String) : server.Route = {
post
{
log.debug(s"POST /register has been called, parameter is: $InstanceString")
try {
val paramInstance : Instance = InstanceString.parseJson.convertTo[Instance](instanceFormat)
handler.handleRegister(paramInstance) match {
case Success(id) =>
complete{id.toString}
}}}
Above is the method that executes the request.
Following is its API configuration:
paths:
/register:
post:
tags:
- Basic Operations
summary: Register a new instance at the registry
operationId: addInstance
parameters:
- in: body
name: InstanceToRegister
required: true
schema:
$ref: '#/definitions/Instance'
responses:
'200':
description: The ID of the registered instance
schema:
type: integer
format: int64
example: 42
Following is the test case that I am trying to execute but I get 400 Bad Request did not equal 200 OK.
"The Server" should {
"Successfully Register" in {
Post("/register", HttpEntity(ContentTypes.`application/json`,"""{"InstanceString":"hallo"}""")) ~> Route.seal(routes) ~> check {
assert(status === StatusCodes.OK)
Try this:
Post("/register", requestBody.toJson).withHeaders("if Any") ~> Route.seal(routes) ~> check {
status shouldBe StatusCodes.OK
}
I can see that you have Json reader for your request body, so use Json writer like this new InstanceString("hello").toJson you get request body.
I see that your your request content type is application/json and you are passing String.
As of 10.04.2012,
There is a short paragraph in the Facebook developer document for 'batch request' entitled: Batch calls with JSONP, which reads:
"The Batch API supports JSONP, just like the rest of the Graph API -
the JSONP callback function is specified using the 'callback' query string
or form post parameter."
I thought that meant you can also do a batch request using JSONP from Javascript (which will be a GET request, as JSONP works only as a GET request), so I tried that, with adding a 'batch' parameter (containing objects describing requests for batch as in the doc) to the query string. Response from FB server was:
Only POST is allowed for batch requests
So, questions:
1. What did they mean in that paragraph?
2. Is there a way to do an asynchronous batch request from Javascript?
I get the same. Sample code is
jQuery.support.cors = true;
var AjaxRequest = jQuery.ajax( {
url: "http://graph.facebook.com/",
type: "POST",
contentType: "application/x-www-form-urlencoded",
data: { "access_token": AccessToken, "batch": BatchRequest },
dataType: "jsonp",
error: function( jqXHR, textStatus, errorThrown ) {
... show error stuff
},
success: function( Return, textStatus, jqXHR ) {
showLog( "Return " + JSON.stringify( Return ) );
showLog( "textStatus " + textStatus );
showLog( "jqXHR " + JSON.stringify( jqXHR ) );
if ( Return.error ) {
... go away
}
else {
... use the data
}
}
} ); // eo ajax request
which gives
Return {"error":3,"error_description":"Only POST is allowed for batch requests"}
textStatus success
jqXHR {"readyState":4,"status":200,"statusText":"success"}
i.e. it successfully sends back an error message. JSONP translates the POST type to a GET, which Facebook doesn't support...
To answer qu.2 you can use FB.api to do asynchronous batch request in javascript. I was trying out JSONP because IE8 keeps hanging on the return from Facebook with FB.api.