I'm sending a request to an API, but it always responds with an error Not readable http body.
In message it returns:
exception = "class org.springframework.http.converter.HttpMessageNotReadableException";
httpCode = 400;
httpMessage = "Bad Request";
Could not read document: Unrecognized token 'product': was expecting ('true', 'false' or 'null')\n at [Source: java.io.PushbackInputStream#430128e1; line: 1, column: 9]; nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'product': was expecting ('true', 'false' or 'null')\n at [Source: java.io.PushbackInputStream#430128e1; line: 1, column: 9]
But product isn't boolean, but string.
Anyone know, what's wrong?
let api_key = Data(klic.utf8).base64EncodedString()
let parametry = ["product" : "STANDART"] as [String : Any]
let headers = ["authorization" : "Basic \(api_key)", "content-type" : "application/json", "cache-control" : "no-cache"]
Alamofire.request("https://stage.japostparcel.cz/api/v1/order/", method: .post, parameters: parametry, headers: headers).responseJSON { (response) in
//print(NSString(data: (response.request?.url)!, encoding: String.Encoding.utf8.rawValue))
print(response)
}
Your base url ends with order/ so you post something like order/?product= STANDART. I am pretty sure you need some kind of page ref in between and not /? something like
`order/order_page?product= STANDART`
So check the documentation
Related
i need to set body of the request to something like that
let param = [[["user_id", "=", 31]]]
the problem is that body of alamofire is like that [string : Any]
how can i send object [Any]to httpBody
i can't send json because only what accepted by the request is form-data like image show
When i add json raw like that
{"domain" : ["user_id","=",31]}
i'm getting error
{
"jsonrpc": "2.0",
"id": null,
"error": {
"code": 200,
"message": "Odoo Server Error",
"data": {
"name": "werkzeug.exceptions.BadRequest",
"debug": "Traceback (most recent call last):\n File \"/data/som.dev.arkeup.com/server/odoo/http.py\", line 646, in _handle_exception\n return super(JsonRequest, self)._handle_exception(exception)\n File \"/data/som.dev.arkeup.com/server/odoo/http.py\", line 307, in _handle_exception\n raise pycompat.reraise(type(exception), exception, sys.exc_info()[2])\n File \"/data/som.dev.arkeup.com/server/odoo/tools/pycompat.py\", line 87, in reraise\n raise value\n File \"/data/som.dev.arkeup.com/server/odoo/http.py\", line 683, in dispatch\n result = self._call_function(**self.params)\n File \"/data/som.dev.arkeup.com/server/odoo/http.py\", line 315, in _call_function\n raise werkzeug.exceptions.BadRequest(msg % params)\nwerkzeug.exceptions.BadRequest: 400: Bad Request\n",
"message": "",
"arguments": [],
"exception_type": "internal_error"
}
}
}
__________________EDIT
I think if i put this string it's will work [[["user_id", "=", 31]]]
but how can i pass [Any]? to body ?
_____EDIT
Here my ios code
let methodName = HTTPMethod.get
let headers = [ "Content-Type" : "application/x-www-form-urlencoded" ,"Accept-Encoding" : "application/json", "accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8"]
let data = ["domain":[[["user_id", "=", 31]]]]
manager.request(urlS!, method: methodName, parameters: data, encoding: URLEncoding.default, headers: headers)//.responseJSON{response in
.responseString(encoding: String.Encoding.utf8) { (response) -> Void in
switch (response.result)
{
case .success:
}
Thank's you for your responses
Making a request with Alamofire (swift 4) to an api endpoint (form encoded content type) and passing a username and password via login. When testing in POSTMAN, this endpoint works without errors and returns valid JSON (see below).
My swift code is as follows:
let headers = [
"content-type": "application/x-www-form-urlencoded",
"cache-control": "no-cache"
]
let parameters = [
"username": "user#user.com",
"password": "password"
]
Alamofire.request("https://xxxxx.com/api/login/", method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON { response in
print(response)
}
The response I get is as follows:
FAILURE: responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}))
Any insight would be appreciated!
Change JSONEncoding.default to URLEncoding.default as below,
Alamofire.request("https://xxxxx.com/api/login/", method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON { response in
print(response)
}
I am trying to receive an access token from PayPal's server using the authorization code in a Sandbox environment. I believe the problem is in converting curl to an Alamofire request, but I'm not sure. Any help is appreciated.
Here is my code for sending authorization to server:
func sendAuthorizationToServer(authorization: [AnyHashable: Any]) {
let jsonAuth = JSON(authorization)
let headers = [
"content-type": "application/x-www-form-urlencoded; charset=utf-8",
]
let parameters = [
"client_id": Constants.payPalSandboxID,
"client_secret": Constants.payPalSandboxSecret,
"grant_type": "authorization_code",
"redirect_uri": "urn:ietf:wg:oauth:2.0:oob",
"code": jsonAuth["response"]["code"].stringValue
]
Alamofire.request("https://api.sandbox.paypal.com/v1/oauth2/token", method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON { response in
print(response.request)
print(response.response)
print(response.data)
print(response.error)
}
}
I've checked jsonAuth["response"]["code"].stringValue and it is returning a correct authorization code.
My doubts are if it should be a .post request or a .get request, and if my credentials in the parameters are in the correct order/structure.
Here is the output of the last print statements:
Here is the SDK link for exchanging an authorization code for the access token:
https://github.com/paypal/PayPal-iOS-SDK/blob/master/docs/future_payments_server.md#exchange-authorization-code-for-refresh--access-tokens
import SwiftyJSON
import Alamofire
// ... ...
// ... ...
// ... ...
let credentialData = "\(paypalClientId):\(paypalSecret)".data(using: String.Encoding.utf8)!
let base64Credentials = credentialData.base64EncodedString(options: [])
let headers = [
"Authorization": "Basic \(base64Credentials)",
]
let params:[String: Any] = [
"grant_type": "client_credentials",
]
Alamofire.request(tokenAPI, method: .post, parameters: params, encoding: URLEncoding.default, headers: headers)
.validate()
.responseJSON { (response) in
debugPrint(response)
switch response.result {
case .success(let data):
let json = JSON(data)
let accessToken = json["access_token"].stringValue
break;
case .failure(let error):
debugPrint(error)
debugPrint(response.data)
}
}
Please note that encoding must be URLEncoding.default not the JSONEncoding.default
I'm trying to recreate a POST request that already works in Postman in Swift 3 with Alamofire 4, but i'm always getting a Status Code 400 "Bad Request". I am out of ideas about what I'm doing wrong here.
This is the request in Postman, additionally there is a username and password in the Body in JSON format:
Reading the Docs for Alamofire, I thought this should be the correct Swift code:
func login(as username: String, withPassword password: String) {
let url = "https://api2.drive-now.com/login"
let parameters: Parameters = [
"username" : username,
"password" : password
]
let loginHeaders: HTTPHeaders = [
"Accept" : "application/json;v=1.6",
"Accept-Encoding" : "gzip, deflate, sdch",
"Accept-Language" : "de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4",
"Connection" : "keep-alive",
"Host" : "api2.drive-now.com",
"Origin" : "https://de.drive-now.com",
"X-Api-Key" : "adf51226795afbc4e7575ccc124face7",
"X-Language" : "de",
"Content-Type" : "application/json"
]
Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: loginHeaders).responseJSON { response in
print("Request: \(response.request)") // original URL request
print("Response: \(response.response)") // HTTP URL response
print("Data: \(response.data)") // server data
print("Result: \(response.result)") // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
}
My console output is:
Request: Optional(https://api2.drive-now.com/login)
Response: Optional(<NSHTTPURLResponse: 0x6000000266a0> { URL: https://api2.drive-now.com/login } { status code: 400, headers {
Connection = close;
"Content-Length" = 181;
"Content-Type" = "text/html";
Date = "Tue, 13 Dec 2016 22:12:46 GMT";
Server = "nginx/1.4.6 (Ubuntu)";
} })
Data: Optional(181 bytes)
Result: FAILURE
Is there a custom session manager maybe that I have to implement? Or do you know of any debugging methods I could use here?
A friend accustomed to the API did help me resolve the issue: it was a default header field that seems to be added by Alamofire to every call. The API didn't accept calls with a "User-Agent" set (don't ask me why).
To help others who might have the same problem, I share the steps I went through to find and resolve the issue:
I made Alamofire.request(...) into a variable named postage (you can call it however you like, of course)
I added debugPrint(postage) to the end of the login-function
The output showed the additional header field
I constructed a custom SessionManager like below
var headers = Alamofire.SessionManager.defaultHTTPHeaders
headers.removeValue(forKey: "User-Agent")
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = headers
api = Alamofire.SessionManager(configuration: configuration)
I'm trying to update a boolean value using python eve, but I always receive the same error,
_issues: {deleted:must be of boolean type}
deleted: "must be of boolean type"
_status: "ERR"
I've tried sending the field as true (setting javascript type) 'True' and 'true' (as text) and 1, but the error is always the same.
startdate=2014-03-25T03%3A00%3A00.000Z&code=dsa&enddate=2014-03-31T03%3A00%3A00.000Z&name=sad¬e=&deleted=True
startdate=2014-03-25T03%3A00%3A00.000Z&code=dsa&enddate=2014-03-31T03%3A00%3A00.000Z&name=sad¬e=&deleted=true
startdate=2014-03-25T03%3A00%3A00.000Z&code=dsa&enddate=2014-03-31T03%3A00%3A00.000Z&name=sad¬e=&deleted=1
Any idea?
Regards
Gaston
settings.py
entity= {
'resource_methods': ['GET', 'POST'],
'schema': schema,
'datasource': {
'filter': {'$or':[{'deleted':{'$exists':0}},{'deleted':False}]}
}
}
schema = {
'name': {
'type': 'string',
'minlength': 1,
'maxlength': 50,
'required': True,
},
'code': {
'type': 'string',
},
'deleted':{
'type':'boolean',
'default':False
}
}
Full Request
Request URL:http://localhost:5000/campaign/532f797da54d75faabdb25d5
Request Method:PUT
Status Code:200 OK
Request Headersview source
Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,no;q=0.6,es;q=0.4
Cache-Control:no-cache
Connection:keep-alive
Content-Length:112
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Host:localhost:5000
If-Match:3c7bc93e3c7d60da62f350ac990c16e29b08660f
Origin:http://localhost:5000
Pragma:no-cache
Referer:http://localhost:5000/static/index.html
X-Requested-With:XMLHttpRequest
Form Dataview parsed
startdate=2014-03-25T03%3A00%3A00.000Z&code=dsa&enddate=2014-03-31T03%3A00%3A00.000Z&name=sad¬e=&deleted=True
Response Headersview source
Access-Control-Allow-Headers:
Access-Control-Allow-Max-Age:21600
Access-Control-Allow-Methods:HEAD, GET, PUT, POST, DELETE, OPTIONS, PATCH
Access-Control-Allow-Origin:*
Content-Length:69
Content-Type:application/json
Date:Mon, 24 Mar 2014 00:30:10 GMT
Server:Werkzeug/0.9.4 Python/2.7.5
Set-Cookie:session=eyJfcGVybWFuZW50Ijp0cn
If you change your schema to coerce deleted value to bool, you can send int or str values and have it converted to bool on insert/update
First, create a function to convert whatever comes, to bool:
to_bool = lambda v: v if type(v) is bool else str(v).lower() in ['true', '1']
Then, change the deleted in the schema to use the function to coerce values, like this:
'deleted':{
'type':'boolean',
'coerce': to_bool,
'default':False
}
With this, you can per example send deleted with values such as '0', 0, 'false' or 'False' yelding to boolean false, or '1', 1, 'true' or 'True' resulting in true
This happens only when you send the request in the content type of form-data or application/x-www-form-urlencoded. In case of AJAX requests, sending boolean value works.
var payload = {
"deleted": false
};
var xhr = $.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(payload),
dataType: "json",
url: "some url"
})
Your payload should be a dict like:
payload = {"somebool": False}
then you convert it to a json string:
payload_json = json.dumps(payload)
which results in a lowercased bool value in a string:
'{"f5only": false}'
then you shoulc be able to post or patch it:
requests.post("{0}/endpoint/".format(api_server), headers=headers, data=payload_json)