IBM MobileFirst Sending JSON Body from iOS SDK to Java Adapter - ibm-mobilefirst

Using IBM Mobile First PlatForm Version 7.1 I am trying to call a Java Adapter from iOS Application using following code.
[[WLResourceRequest requestWithURL:url method:WLHttpMethodPost] sendWithJSON:#{#"one":#"two"} completionHandler:^(WLResponse *response, NSError *error) {
NSLog(#"%#",response);
NSLog(#"%#",error);
}];
Java Method on adapter side looks as following.
#POST
#Consumes("application/json")
#Produces("application/json")
public String hello(JSONObject body){
return body.toString();
}
But I get Following error in response
2016-04-20 11:31:15.520 mbs-call[15092:3787968] Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: unsupported media type (415)" UserInfo={com.alamofire.serialization.response.error.response= { URL: http:/0.0.0.0:10080/mbs-api/adapters/basicadpt/users } { status code: 415, headers {
Connection = Close;
"Content-Language" = "en-US";
"Content-Length" = 0;
Date = "Wed, 20 Apr 2016 02:31:15 GMT";
"X-Powered-By" = "Servlet/3.0";
} }, NSErrorFailingURLKey=http://0.0.0.0:10080/mbs-api/adapters/basicadpt/users, com.alamofire.serialization.response.error.data=<>, NSLocalizedDescription=Request failed: unsupported media type (415)}
And it seems that in iOS SDK it adds header application/x-www-url-form-urlencoded in request when any method is called.
I have following 2 questions.
How to pass JSON Body to Java adapter?
Behaviour of sendWithJSON is different on iOS and Android. On Android it seems to add application/json header when we call adapter. Is that a bug or part of behaviour?

I believe this is a bug. I think that using sendWithJSON should automatically assume that the content type is application/json.
I suggest that you open a support request (PMR) so that they can improve the experience.
In the meantime, I found an easy workaround:
[request addHeaderValue:#"application/json" forName:#"Content-Type"]
Or in Swift:
request.addHeaderValue("application/json", forName: "Content-Type")

I had this same issue with the cordova version of an application.
var userIDTag = 'some_string';
var subTag = [userIDTag]; //<- this worked
var subTag = userIDTag; //<- this failed with the above error
var subTag = '[\'' + some_string + '\']'; //<- this also failed with the above error
The below is what I ended up doing for a Cordova app.
function subscribeByTag(userIDTag) {
var subTag = [userIDTag];
console.log("subTag: " + subTag);
WLAuthorizationManager.obtainAccessToken("push.mobileclient").then(
MFPPush.subscribe(
subTag,
function(subTag) {
navigator.notification.alert("Subscribed successfully");
},
function(failureResponse){
navigator.notification.alert("Failed to subscribe");
console.log("Failedtosubscribe:" + JSON.stringify(failureResponse));
}
)
);
}

Related

TRON not using request.header

I am using Xcode 8.3.3 (8E3004b)
I am using TRON (which includes Alamofire) to make HTTP Request to my REST API.
I have been successful getting a simple API working with this setup. I am trying to connect to a different API, which requires me to set the headers. It is this API that is throwing a Status 415 server error.
I have the following code to make the request via TRON. According to the TRON Github page, I should be ae to set the header like this:
request.headers = ["Content-Type":"application/json"]
I have also tried:
request.headerBuilder.headers(forAuthorizationRequirement: AuthorizationRequirement.allowed, including: ["Content-Type":"application/json"])
I tried adding a few different ways of writing that, but nothing seems to work.
Here's a bigger section of the code so you can see the context
let urlSubfix = "\(Constant.REST_MOBILE)\(Constant.REGISTER)"
let request: APIRequest<RegisterApiResult, JSONError> = tron.request(urlSubfix)
request.method = .put
// request.headers = ["Content-Type":"application/json"]
let header = request.headerBuilder.headers(forAuthorizationRequirement: AuthorizationRequirement.allowed, including: ["Content-Type":"application/json"])
request.headers = header
request.perform(withSuccess: { (registerApiResult) in
print("Successfully fetched our json object")
completion(registerApiResult)
}) { (err) in
print("Failed to fetch json...", err)
}
Here is the actual error from my log:
Failed to fetch json... APIError<JSONError>(request: Optional(http://www.slsdist.com/eslsd5/rest/mobileservice/register), response: Optional(<NSHTTPURLResponse: 0x618000028c20> { URL: http://www.slsdist.com/eslsd5/rest/mobileservice/register } { status code: 415, headers {
"Content-Length" = 0;
Date = "Sat, 22 Jul 2017 22:23:14 GMT";
Server = "Microsoft-IIS/7.5";
"X-Powered-By" = "Undertow/1, ASP.NET";
} }), data: Optional(0 bytes), error: Optional(Alamofire.AFError.responseValidationFailed(Alamofire.AFError.ResponseValidationFailureReason.unacceptableStatusCode(415))), errorModel: Optional(Go_Cart.Service.JSONError))
As you can see I have tried to set the headers a couple different ways, but neither of them seems to take affect. Any help or advice from anyone would be helpful.
Thanks in advance.

Native iOS application Development using Worklight API and JSON parser with HTTP Adapter

WLProcedureInvocationData *myInvocationData = [[WLProcedureInvocationData alloc] initWithAdapterName:#"myRESTAdapter" procedureName:#"getAgents"];
MyInvokeListener *invokeListener = [[MyInvokeListener alloc] initWithController: self];
[[WLClient sharedInstance] invokeProcedure:myInvocationData withDelegate:invokeListener];
[__NSDictionaryI WLJSONRepresentation]: unrecognized selector sent to
instance
I am trying to fetch the response using JSON service with HTTP Adapter in Worklight. When i deploy the API and proceeds further then am getting the above exception..
Note: The service am using only to fetch details with out any parameter parsing...
Adapter code:
function getAgents() {
var input = {
method : 'get',
returnedContentType : 'json',
path : 'myApp/agents'
};
return WL.Server.invokeHttp(input);
}
Can anyone help on this?
Thanks in advance

OSX - AFNetworking sending text even with JSON Serializer set

I have an issue with AFNetworking and AFJSONRequestSerializer. I try to access an API, and the request contains a text/plain header. Here's my code :
class BaseService {
var manager: AFHTTPRequestOperationManager!
init() {
manager = AFHTTPRequestOperationManager()
manager.responseSerializer = AFJSONResponseSerializer()
manager.requestSerializer = AFJSONRequestSerializer(writingOptions: NSJSONWritingOptions.allZeros)
}
}
class UserService: BaseService {
func startNewEntry(name: String) {
let params = [
"time_entry": [
"description": name,
"created_with": "fooBar"
]
]
manager.POST(
"endpoint",
parameters: params,
success: { (operation, response) -> Void in
let json = JSON(response)
println("OK")
println(json)
Context.shared.entries.getFromJSON(json)
}) { (operation, error) -> Void in
println("-- ERROR --")
println(operation)
println(error)
}
}
Do you know this issue ?
No, this code will create a request with a content type of application/json. But I wonder if you perhaps mislead by an error message that said:
Request failed: unacceptable content-type: text/html
If you got that, that's not telling you that that the request had an unacceptable content type, but rather that the request failed because the response was text/html. And this is a very common issue: If server code that is attempting to create a JSON response fails for some reason, sometimes the error message isn't JSON, but rather it's HTML.
I would suggest adding the following inside the failure block of your POST method in order to see what this text/html response was:
if operation.responseData != nil {
println(NSString(data: operation.responseData, encoding: NSUTF8StringEncoding))
}
This way, if you get a text error message from the server (e.g. the request was malformed or what have you), you'll be able to read the HTML response you got back.

Consuming Analytics from Parse.com in an IOS App

I am generating custom Parse Analytic events in the background cloud code based on Save events from my ios app . I can also see it in the Analytic panel on Parse.com.
How do I access it in my ios app ?
I get the following error when I try
Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: bad request (400)" UserInfo=0x7a9697e0 {com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x7a956d00> { URL: https://api.parse.com/1/events/commentsAnalytics } { status code: 400, headers {
"Access-Control-Allow-Methods" = "*";
"Access-Control-Allow-Origin" = "*";
Connection = "keep-alive";
"Content-Length" = 36;
"Content-Type" = "application/json; charset=utf-8";
Date = "Fri, 23 Jan 2015 06:43:38 GMT";
Server = "nginx/1.6.0";
"X-Parse-Platform" = G1;
"X-Runtime" = "0.007086";
} }, NSErrorFailingURLKey=https://api.parse.com/1/events/commentsAnalytics, NSLocalizedDescription=Request failed: bad request (400),
Check if you are adding the keys (X-Parse-Application-Id and X-Parse-REST-API-Key) of your application in the request header. Here is an example with Alamofire.
Example
var request = NSMutableURLRequest(URL: NSURL(string: "https://api.parse.com/1/events/Buy")!)
request.HTTPMethod = "POST"
request.setValue("<APPLICATION-KEY>", forHTTPHeaderField: "X-Parse-Application-Id")
request.setValue("<REST-KEY>", forHTTPHeaderField: "X-Parse-REST-API-Key")
var parameter: NSDictionary = ["dimensions" :["product" : ["name" : "macpro", "price" : "350"]]]
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(parameter, options: nil, error: nil)
Alamofire.request(request).response { (request, response, result, error) -> Void in
// handle response
println("\(request) \t \(response) \t \(result) \t \(error) ")
}
Checking
to check the event, go to your application panel in the parse ...
...click "Custom Breakdown"...
and customize your chart.

dojo jax-rs call issue

I'm trying to call a REST webservice using dojo toolkit it seems that the call is encountring some isues this is the call with dojo
dojo.xhrGet({
url: 'http://localhost:9080/TestJMSWeb/jaxrs/categories/all',
handleAs: 'json',
timeout: 2000,
load: callback
});
var callback = dojo.hitch(this, function(data) {
var massagedData = {
label: 'categorie',
identifier: 'id',
items: data
}
this.store = new dojo.data.ItemFileReadStore({data: massagedData});
});
the webservice code is here
#GET
#Path("/all")
#Produces("application/json")
public JSONArray getAllCategories() throws IOException {
final List<Categorie> allCategories = manager.getCategories();
if (allCategories == null || allCategories.isEmpty())
throw new WebApplicationException(ErrorUtil.jSONArrayResponse(Status.NO_CONTENT, "No category found"));
JSONArray jsonArray = jsonCustomerArray(allCategories);
return jsonArray;
}
when I call the webservice I get an error message
ResourceRegis I org.apache.wink.server.internal.registry.ResourceRegistry filterDispatchMethods The system cannot find any method in the ressources.CategorieRessouce class that supports OPTIONS. Verify that a method exists.
[4/24/12 1:23:41:531 GMT] 0000002f SystemErr R 0 TestJMSWeb INFO [WebContainer : 0] openjpa.Runtime - OpenJPA dynamically loaded a validation provider.
it seems that is trying to call the ressource with the OPTIONS method while I'm using the .xhrGet function what is the problem?
Here is a link describing the problem: http://engin.bzzzt.biz/2010/01/22/first-dojo-impression/
The guy talks about how if it is a cross domain request (which I believe yours is, because of the ports), and the request contains some Access-Control-* HTTP headers, than browsers will send the request as OPTIONS instead of GET.
Dojo adds the Access-Control-* headers when it determines you are making a cross domain request. You can try to fix this yourself by going to dojo/_base/xhr.js and commenting out the following lines (723 to 729):
// FIXME: is this appropriate for all content types?
if(args.contentType !== false){
xhr.setRequestHeader("Content-Type", args.contentType || _defaultContentType);
}
if(!args.headers || !("X-Requested-With" in args.headers)){
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
}
I haven't tried this fix yet so please let me know if it works!