SharePoint REST Batch Insert Request using Java
Overview:
Here we will see
- A business requirement, where employee’s pending item counts need to be updated in SharePoint.
- Here we focus on bulk Insert of items in SharePoint at a time.
- In this blog, we will come to know,
- how we can perform bulk insert in SharePoint using REST using a Java Program,
- same concept we can use in SAP-PI Java Map
- Java Code functionalities will be as follows:
- Get all pending items from One-Source system’s REST service
- INSERT received items to SharePoint using one call i.e. bulk request
- For Batch-Update, following blog can be referred:
Java-Code-Logic:
First get all employee’s item counts from Source System using its provided data sharing technique for example REST service, which returns output as following JSON String
Here, for example purpose, we try with 3 items at a time.
[
{
"employeeId": 213323,
"pendingCount": 3
},
{
"employeeId": 231499,
"pendingCount": 9
},
{
"employeeId": 205695,
"pendingCount": 2
}
]
From above Json-Result string, we need to extract “employeeId” & “pendingCount”, which to be send to SharePoint.
Next, extracted contents need to be framed in Batch-Insert-Request-Format. This is been achieved using Java function SharePoint_BULK_INSERT()
SharePoint Batch REST url is as follows:
- https://ClientDomain.sharepoint.com/teams/SPdev/AlertsCount/_api/$batch
SharePoint-REST requires following request format for Batch-Insert
--batch_b27de00f-98f2-4dcb-9fd4-efa8f57380f4
Content-Type: multipart/mixed; boundary="changeset_85050752-ccb7-40d1-a883-2ae3ac0c100c"
Content-Length: 1161
Content-Transfer-Encoding: binary
--changeset_85050752-ccb7-40d1-a883-2ae3ac0c100c
Content-Type: application/http
Content-Transfer-Encoding: binary
POST https://ClientDomain.sharepoint.com/teams/SPdev/AlertsCount/_api/web/Lists/GetByTitle('AlertCount')/Items HTTP/1.1
Content-Type: application/json;odata=verbose
{"__metadata":{"type":"SP.Data.AlertCountListItem"},"Title":"213323","PeningCount":"3"}
--changeset_85050752-ccb7-40d1-a883-2ae3ac0c100c
Content-Type: application/http
Content-Transfer-Encoding: binary
POST https://ClientDomain.sharepoint.com/teams/SPdev/AlertsCount/_api/web/Lists/GetByTitle('AlertCount')/Items HTTP/1.1
Content-Type: application/json;odata=verbose
{"__metadata":{"type":"SP.Data.AlertCountListItem"},"Title":"231499","PeningCount":"9"}
--changeset_85050752-ccb7-40d1-a883-2ae3ac0c100c
Content-Type: application/http
Content-Transfer-Encoding: binary
POST https://ClientDomain.sharepoint.com/teams/SPdev/AlertsCount/_api/web/Lists/GetByTitle('AlertCount')/Items HTTP/1.1
Content-Type: application/json;odata=verbose
{"__metadata":{"type":"SP.Data.AlertCountListItem"},"Title":"205695","PeningCount":"2"}
--changeset_85050752-ccb7-40d1-a883-2ae3ac0c100c--
--batch_b27de00f-98f2-4dcb-9fd4-efa8f57380f4
Content-Type: application/http
Content-Transfer-Encoding: binary
GET https://ClientDomain.sharepoint.com/teams/SPdev/AlertsCount/_api/web/Lists/GetByTitle('AlertCount')/Items?$orderby=Title HTTP/1.1
Accept: application/json;odata=verbose
--batch_b27de00f-98f2-4dcb-9fd4-efa8f57380f4--
Here, we require to generate unique-ID (GUID-like strings) for HTTP batch requests.
For example: following unique IDs (GUID) is been used for ChangeSetItems and BatchRequestItem:
- b27de00f-98f2-4dcb-9fd4-efa8f57380f4 used for batch
- 85050752-ccb7-40d1-a883-2ae3ac0c100c used for each item
Java function generateUUID() generates universally unique identifiers.
private static String generateUUID(){
//Generates a GUID-like string, used in HTTP batches
//Generating unique IDs | The identifiers generated by UUID are actually universally unique identifiers.
UUID idOne = UUID.randomUUID();
String idOne_Str = String.valueOf(idOne);
return idOne_Str;
}
Java function SharePoint_BULK_INSERT() prepares Batch-Insert request format for above Json-input
private static void SharePoint_BULK_INSERT(String jsonCountStr) throws IOException{
/*
Following sample JSON format required for SharePoint Insert function
[
{
"employeeId": 213323,
"pendingCount": 3
},
{
"employeeId": 231499,
"pendingCount": 9
},
{
"employeeId": 205695,
"pendingCount": 2
}
]
SharePoint REST-URL to Insert count:
https://ClientDomain.sharepoint.com/teams/SPdev/AlertsCount/_api/web/Lists/GetByTitle('AlertCount')/Items
*/
//generate uniqueId for a batch boundary
String batchGuid = generateUUID();
//generate uniqueId for each item to be inserted
String changeSetId = generateUUID();
//Begin of: Prepare Bulk Request Format for SharePoint Bulk-Insert-Query ----------------
String batchContents = "";
try {
//Parse the output-count JSON
JSONParser parser = new JSONParser(); //Jar file: json-simple-1.1.1.jar
JSONArray jsonArr = (JSONArray)parser.parse(jsonCountStr); //Returned string in JSonArray, so convert it to JSonArray
//SharePoint URL to insert one item
String endpoint_Insert = "https://ClientDomain.sharepoint.com/teams/SPdev/AlertsCount/" +
"_api/web/Lists/GetByTitle(\'AlertCount\')/Items";
//Start: changeset to insert data ----------
String batchCnt_Insert = "";
for(int i=0; i<jsonArr.size(); i++){
JSONObject jsonObj = new JSONObject();
jsonObj = (JSONObject) jsonArr.get(i); //get ith array object
String empId = (jsonObj.get("employeeId")).toString(); //get value of 'employeeId'
String pCount = (jsonObj.get("pendingCount")).toString(); //get value of 'pendingCount'
//Start:create INSERT-Statement for one Item ---------------------------
String request = "{\"__metadata\":{\"type\":\"SP.Data.AlertCountListItem\"}," +
"\"Title\":\"" + empId + "\"," +
"\"pendingCount\":\"" + pCount + "\"}";
batchCnt_Insert = batchCnt_Insert
+ "--changeset_" + changeSetId + "\n"
+ "Content-Type: application/http" + "\n"
+ "Content-Transfer-Encoding: binary" + "\n"
+ "" + "\n"
+ "POST " + endpoint_Insert + " HTTP/1.1" + "\n"
+ "Content-Type: application/json;odata=verbose" + "\n"
+ "" + "\n"
+ request + "\n"
+ "" + "\n";
//END:create INSERT-Statement for one Item ------------------------------
}
//END: changeset to insert data ----------
batchCnt_Insert = batchCnt_Insert + "--changeset_" + changeSetId + "--\n";
//create batch for creating items
batchContents = "--batch_" + batchGuid + "\n"
+ "Content-Type: multipart/mixed; boundary=\"changeset_" + changeSetId + "\"\n"
+ "Content-Length: " + batchCnt_Insert.length() + "\n"
+ "Content-Transfer-Encoding: binary" + "\n"
+ "" + "\n"
+ batchCnt_Insert + "\n";
//Start:create request in batch to get all items after all are created ---------
String endpoint = "https://ClientDomain.sharepoint.com/teams/SPdev/AlertsCount/" +
"_api/web/Lists/GetByTitle(\'AlertCount\')/Items?$orderby=Title";
batchContents = batchContents
+ "--batch_" + batchGuid + "\n"
+ "Content-Type: application/http" + "\n"
+ "Content-Transfer-Encoding: binary" + "\n"
+ "" + "\n"
+ "GET " + endpoint + " HTTP/1.1" + "\n"
+ "Accept: application/json;odata=verbose" + "\n"
+ "" + "\n";
//End:create request in batch to get all items after all are created -----------
batchContents = batchContents + "--batch_" + batchGuid + "--";
} catch (Exception e) {
System.out.println(e.getMessage());
}
//End of: Prepare Bulk Request Format for SharePoint Bulk-Insert-Query ----------------
//Call SharePoint REST to POST Item
System.out.println(batchContents);
SharePoint_BULK_POST(batchContents, batchGuid);
}
Following Java functions SharePoint_BULK_POST() posts Batch request into SharePoint
private static void SharePoint_BULK_POST(String batchRequest, String batchGuid) throws IOException{
//Get SharePoint Access Token
String accessToken = SharePoint_getAccessToken();
//POST BulkRequest to SharePoint
try {
String wsUrl = "https://ClientDomain.sharepoint.com/teams/SPdev/AlertsCount/_api/$batch";
//Create HttpURLConnection
URL url = new URL(wsUrl);
URLConnection connection = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) connection;
//Set Header
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
httpConn.setRequestMethod("POST");
httpConn.setRequestProperty("Authorization", "Bearer " + accessToken);
httpConn.setRequestProperty("Content-Type", "multipart/mixed; boundary=\"batch_"+ batchGuid +"\"");
//Send Request
DataOutputStream wr = new DataOutputStream(httpConn.getOutputStream ());
wr.writeBytes(batchRequest);
wr.flush();
wr.close();
//Read the response.
String responseStr = "";
if (httpConn.getResponseCode() == 200) {
responseStr = "HTTP Response Code: " + httpConn.getResponseCode() + ", Batch records gets inserted successfully in SharePoint.";
}else{
responseStr = "HTTP Response Code: " + httpConn.getResponseCode() +", Error while inserting Item. "+ httpConn.getResponseMessage();
}
System.out.println(responseStr);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
Following function helps to get SharePoint access token
private static String SharePoint_getAccessToken(){
/*
This function helps to get SharePoint Access Token.
SharePoint Access Token is required to authenticate SharePoint REST service while GET/POST
SharePoint url to get access token is as:
https://accounts.accesscontrol.windows.net/<tenantID>/tokens/OAuth/2
This function requires below input related to SharePoint:
1. client_id
2. client_secret
3. tenant_ID
4. client_domain
*/
String accessToken = "";
try {
System.out.println("Get SharePointAccessToken");
String wsURL = "https://accounts.accesscontrol.windows.net/"+ shp_tenantId +"/tokens/OAuth/2";
//Create HttpConenction
URL url = new URL(wsURL);
URLConnection connection = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) connection;
//Set header
httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
httpConn.setRequestMethod("POST");
//Prepare RequestData
String jsonParam =
"grant_type=client_credentials" +
"&client_id="+shp_clientId+"@"+shp_tenantId +
"&client_secret=" + shp_clientSecret +
"&resource=00000003-0000-0ff1-ce00-000000000000/"+ shp_clientDomain + ".sharepoint.com@" + shp_tenantId;
//Send Request
DataOutputStream wr = new DataOutputStream(httpConn.getOutputStream ());
wr.writeBytes(jsonParam);
wr.flush();
wr.close();
//Read the response
String httpResponseStr = "";
InputStreamReader isr = null;
if (httpConn.getResponseCode() == 200) {
isr = new InputStreamReader(httpConn.getInputStream());
} else {
isr = new InputStreamReader(httpConn.getErrorStream());
}
BufferedReader in = new BufferedReader(isr);
String strLine = "";
while ((strLine = in.readLine()) != null) {
httpResponseStr = httpResponseStr + strLine;
}
//Extracting accessToken from httpResponseStr which is a JSON format string
/*
Sample HTTP Response String(httpResponseStr) is as below:
{"token_type":"Bearer","expires_in":"3599","not_before":"1509537628","expires_on":"1509541528","resource":"","access_token":"xyz"}
*/
JSONParser parser = new JSONParser(); //Jar file: json-simple-1.1.1.jar
JSONObject jsonObj = (JSONObject)parser.parse(httpResponseStr);
accessToken = (jsonObj.get("access_token")).toString(); //get value of element
} catch (Exception e) {
System.out.println(e.getMessage());
}
return accessToken;
}
Post insert, in following SharePoint Screen, where we can see our items
<<<<< Parent blog reference….. Integrate SharePoint using SAP PI