on 05-15-2015 5:34 PM
Hi,
I'm developing a native android app with NetWeaver Gateway, OData sdk, SMP 3.0 SP 04 y SMP sdk SP05. I'm trying to execute a batch request from android with store concept so, I make a read request first, with a created batchItem (which is working on the rest client as on android, both return a satus 200 Ok. Img 1. for GET Method in rest Client) for the store object to gets the CSRF-Token, then I create an entity, assign its properties and create a batchItem2, to execute the batch request but with the same store object. I've read that with OnlineStore concept you don't need to manually set the X-CSRF-Token header, that store autmatically from request #1 (read request) gets it and the pass it to the second request (post request). I'll post a part of my code so anyone can tell me what I'm doing wrong or if the concept is bad an I really have to get the CSRF token manually an then put the X-CSRF-Token header manually.
Img 1. GET Method. 200 Ok.
Img 2. POST Method. 202 Accepted. And every changeset gets a 201 Created.
In my android code I have, based on the following two blogs: https://scn.sap.com/thread/3732019 on the answers of , , , and the 's blog.
StoreOpenListener openListener = StoreOpenListener.getInstance();
OnlineODataStore store = openListener.getStore();
ODataRequestParamBatch requestParamBatch = new ODataRequestParamBatchDefaultImpl();
ODataEntity newEntity = new ODataEntityDefaultImpl("MY_SERVICE_SRV.MarcacionImprMat");
newEntity.getProperties().put("IPedido", new ODataPropertyDefaultImpl("IPedido", "333333"));
newEntity.getProperties().put("Maktx", new ODataPropertyDefaultImpl("Maktx", "123 Main street"));
// Create batch item for GET Method
ODataRequestParamSingle batchItem = new ODataRequestParamSingleDefaultImpl();
batchItem.setResourcePath("MarcacionImprMatSet(Matnr='123456',IUsuario='READ_GW')");
batchItem.setMode(ODataRequestParamSingle.Mode.Read);
batchItem.setCustomTag("Read operation");
// Add batch item to batch request
requestParamBatch.add(batchItem);
ODataResponse oDataResponse = store.executeRequest(batchItem); //The response is 200 Ok
// Create batch item for POST method
ODataRequestParamSingle batchItem2 = new ODataRequestParamSingleDefaultImpl();
// Allocate OData Entity
batchItem2.setResourcePath("MarcacionImprMatSet(Matnr='123456',IUsuario='READ_GW')");
batchItem2.setMode(ODataRequestParamSingle.Mode.Create);
batchItem2.setCustomTag("Create operation");
batchItem2.setPayload(newEntity);
// // Add headers
Map<String, String> createHeaders = new HashMap<String, String>();
createHeaders.put("content-type", "multipart/mixed; boundary=batch");
batchItem2.setOptions(createHeaders);
// // Create change set
ODataRequestChangeSet changeSetItem = new ODataRequestChangeSetDefaultImpl();
// // Add batch item to change set.
// // You can add more batch items to the same change set as long as they are CUD operations
changeSetItem.add(batchItem2);
// // Add batch item to batch request
requestParamBatch.add(changeSetItem);
// Send request synchronously
oDataResponse = store.executeRequest(requestParamBatch);
// Check http status response for batch request.
// Status code should be "202 Accepted"
Map<ODataResponse.Headers, String> headerMap = oDataResponse.getHeaders(); //Here the response is 403 Forbidden.
if (headerMap != null) {
String code = headerMap.get(ODataResponse.Headers.Code);
}
If I send a POST request from Advanced Rest Client without the X-CSRF-TOKEN header or empty it gives me the 403 Forbidden error and says that is "csrf token validation failed". So I think that, that's the source of the problem.
Thanks in advance.
Best regards.
--
Ana Velásquez
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Ana, your code seems correct and the test with the REST client confirms your backend supports batch.
Two suggestions:
1. Add the X-CSRF-Tokent to the online store
Regarding the below statement:
"I've read that with OnlineStore concept you don't need to manually set the X-CSRF-Token header, that store automatically from request #1 (read request) gets it and the pass it to the second request (post request). "
With the online store you do need to set the X-CSRF-Token header. If you look at the sample code in SAP/sap_mobile_native_android · GitHub download UsingOnlineAPI and look at the following classes:
- XCSRFTokenRequestFilter: this filter preprocess the request to send the X-CSRF-Token: Fetch
- XCSRFTokenResponseFilter: this filter process the response and get the value of the XCSRF token
- OnlineManager adds the filters the the HTTPConversationManager to open the online store.
On the other hand, it's the offline store that handles the X-CSRF-Token for you, not the online store.
2. Upgrade server and SDK to the latest version
I have tested the batch with the latest and it's working, earliest releases may contain bugs.
SMP 3.0 server SP07 PL02
SMP 3.0 SDK SP08 PL01
Best regards
Claudia
I'm using the XCSRFTokenRequestFilter and XCSRFTokenResponseFilter classes and adding the filters to the HttpConversationManager, now the 403 error code no appear, but what happend now is: anything appears, the oDataResponde object is null, neither headers, response array or type are filled. I'm really starting to think to move to RequestBuilder because I don't know what else to try with OnlineOdata.
Best regards,
--
Ana Velasquez
Hi Ana,
That's a step forward in the right direction, have you upgraded to the latest SDK and Server?
Looking forward, SAP is adding more features to the store concept. Most of the classes from previous versions are marked as deprecated.
I would recommend downloading the latest versions and trying your code again.
Hope this helps,
Claudia
In the beginning you said you have passed X-CSRF-TOKEN value for POST (most precisely for BATCH). Then you say
If I send a POST request from Advanced Rest Client without the X-CSRF-TOKEN header or empty it gives me the 403 Forbidden error and says that is "csrf token validation failed".
I really couldn't understood this. Can you provide some points on this?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Sorry for the late response. Yes, I'm passing the X-CSRF-TOKEN for POST, in the rest client, and it's working fine, the response is 202 Accepted, as shown in the Img 2. What I say at the end is that I make a test to try to understand the error that Android is giving me, so I make the test sending the POST without the X-CSRF-TOKEN (in rest client), and as in Android, the error is 403. That's why I think that the possible cause of the error in android is the X-CSRF-TOKEN.
, I've already did the "How To...Consume OData Services in Online Mode (Android)" and I'm able to consume my OData's, the problem appears just when I try to make the batch request. thank you for the suggestion, do you know if in SP07 or SP08 the batch request works differently from SP05?
Best regards,
--
Ana Velásquez
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Ana,
Sorry. I don't know about Android. I just can help about Server. But because you can use READ and POST in REST Client, so your Server do not have any problem ( just my opinion).
If you have time, i think you should follow these blog:
- http://scn.sap.com/docs/DOC-60634.
Hope this can help.
Best Regards,
Sao Vu.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
84 | |
10 | |
10 | |
10 | |
7 | |
6 | |
6 | |
5 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.