首页 > 解决方案 > Sharepoint 使用 JAVA 批量上传

问题描述

我有一个现有的 API 到 SharePoint API 的单一列表。新要求是使用相同的 API 上传多个数据。我们正在使用 NTLM 身份验证访问。在同一代码中,当我尝试传递多个项目时,它仍然保存唯一的第一个项目。我已经通过多个帖子解决了这个问题,但无法解决其中一个是批量上传共享点,我尝试了这个,但这里的身份验证不同,请建议我如何在我的代码中实现这一点。
以下是上传 1 个列表项的代码。

public class RESTApiUtil {

   public static void main(String[] args) throws Exception {

        String jsonInputString = "{ \"__metadata\": { \"type\": \"SP.Data.Raffle_x005f_Draw_x005f_RegistrationListItem\" },"
            + "\"Title\": \"title1\",\"Employee_Email\": \"employee1@gmail.com\","
            + "\"Employee_Name\": \"empName\",\"Registration_Date\": \"12-06-2019\",\"Employee_No\": \"123\"},"+
            "{ \"__metadata\": { \"type\": \"SP.Data.Raffle_x005f_Draw_x005f_RegistrationListItem\" },"
            + "\"Title\": \"title2\",\"Employee_Email\": \"employee2@gmail.com\","
            + "\"Employee_Name\": \"empName2\",\"Registration_Date\": \"12-06-2019\",\"Employee_No\": \"1234\"}";

         System.out.println(callPostAPI(
         "http://host/_api/contextinfo",
         "http://host/_api/web/lists/getbytitle('Registration')/items",
         "userName", "password",
         "domain",jsonInputString));

    }


    public static String callPostAPI(String digestUrl, String postApiUrl, final String userName, final String password,
            final String domain, String postBody) {
        StringBuffer response = new StringBuffer();
        try {
            String requestDigest = getRequestDigest(digestUrl, postApiUrl, userName, password, domain,"");
            String cookie = getCookieValue(postApiUrl, userName, password, domain, requestDigest, "");
            if(cookie!=null&&!"".equals(cookie)) {
                requestDigest = getRequestDigest(digestUrl, postApiUrl, userName, password, domain,cookie);
                if (requestDigest != null && !"".equals(requestDigest)) {
                    response.append(sendPostRequest(postApiUrl, userName, password, domain, requestDigest, postBody));
                } else {
                    response.append("Failed To Get Request Digest");
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return response.toString();
    }


    @SuppressWarnings({ "rawtypes", "unchecked" })
    private static String getRequestDigest(String urlStr,String postApiUrl, final String userName, final String password, final String domain,String cookie) {

        String response = "";
        DefaultHttpClient httpclient = new DefaultHttpClient();

        try {

            int port = 80;
            String serverName = "";

            int endIndex = 0;
            int index = urlStr.indexOf("/");
            int count=0;
            while(index >= 0) {
               count++;
               index = urlStr.indexOf("/", index+1);
               if(count==2) {
                   endIndex = index;
                   break;
               }
            }
            String splitedServerName = urlStr.substring(urlStr.indexOf("//")+2,endIndex);
            serverName = splitedServerName;
            if(splitedServerName.contains(":")) {
                serverName = splitedServerName.split(":")[0];
                port = Integer.valueOf(splitedServerName.split(":")[1]);
            }

            NTCredentials creds = new NTCredentials(userName, password, domain, domain);
            httpclient.getCredentialsProvider().setCredentials(new AuthScope(serverName, port), creds);

            List authpref = new ArrayList();
            authpref.add(AuthPolicy.NTLM);

            httpclient.getParams().setParameter(AuthPNames.TARGET_AUTH_PREF, authpref);
            HttpHost target = new HttpHost(serverName, port, "http");
            HttpPost httpPost = new HttpPost(urlStr);
            httpPost.setHeader("Accept", "application/json;odata=verbose");
            httpPost.setHeader("Content-Type", "application/json;odata=verbose");
            if(!"".equals(cookie))
                httpPost.setHeader("Cookie", cookie);

            HttpContext localContext = new BasicHttpContext();
            HttpResponse response1 = httpclient.execute(target,httpPost, localContext);


            StringBuilder output = new StringBuilder();
            InputStream stream = response1.getEntity().getContent();
            BufferedReader in = new BufferedReader(new InputStreamReader(stream));
            String str = "";
            while ((str = in.readLine()) != null) {
                output.append(str);
            }
            in.close();

            JSONObject obj = new JSONObject(output.toString());
            JSONObject obj1 = obj.getJSONObject("d");
            JSONObject obj2 = obj1.getJSONObject("GetContextWebInformation");
            response = obj2.getString("FormDigestValue");


            return response;


        } catch (Exception e) {
            e.printStackTrace();
        }

        return response;

    }

    private static String sendPostRequest(String postUrl, String userName, String password, String domain, String digest,
            String postBody) throws IOException {

        String response = "";
        DefaultHttpClient httpclient = new DefaultHttpClient();

        try {

            int port = 80;
            String serverName = "";

            int endIndex = 0;
            int index = postUrl.indexOf("/");
            int count=0;
            while(index >= 0) {
               count++;
               index = postUrl.indexOf("/", index+1);
               if(count==2) {
                   endIndex = index;
                   break;
               }
            }
            String splitedServerName = postUrl.substring(postUrl.indexOf("//")+2,endIndex);
            serverName = splitedServerName;
            if(splitedServerName.contains(":")) {
                serverName = splitedServerName.split(":")[0];
                port = Integer.valueOf(splitedServerName.split(":")[1]);
            }

            NTCredentials creds = new NTCredentials(userName, password, domain, domain);
            httpclient.getCredentialsProvider().setCredentials(new AuthScope(serverName, port), creds);

            List authpref = new ArrayList();
            authpref.add(AuthPolicy.NTLM);

            httpclient.getParams().setParameter(AuthPNames.TARGET_AUTH_PREF, authpref);
            HttpHost target = new HttpHost(serverName, port, "http");
            HttpPost httpPost = new HttpPost(postUrl);
            httpPost.setHeader("Accept", "application/json;odata=verbose");
            httpPost.setHeader("Content-Type", "application/json;odata=verbose");
            httpPost.setHeader("X-RequestDigest", digest);

            System.out.println("postbody "+postBody);
                                //Jar file: json-simple-1.1.1.jar

        /*  String[] data= postBody.split("},");
            for(int i=0;i<data.length;i++) {
                String str=data[i].toString();
                System.out.println("Struing "+str);
             }*/


            StringEntity params =new StringEntity(postBody);
            httpPost.setEntity(params);


            HttpContext localContext = new BasicHttpContext();
            HttpResponse response1 = httpclient.execute(target,httpPost, localContext);

            StringBuilder output = new StringBuilder();
            InputStream stream = response1.getEntity().getContent();
            BufferedReader in = new BufferedReader(new InputStreamReader(stream));
            String str = "";
            while ((str = in.readLine()) != null) {
                output.append(str);
            }

            return output.toString();


        } catch (Exception e) {
            e.printStackTrace();
        }

        return response;

    }



    private static String getCookieValue(String postUrl, String userName, String password, String domain, String digest,
            String postBody) throws IOException {

        String response = "";
        DefaultHttpClient httpclient = new DefaultHttpClient();

        try {

            int port = 80;
            String serverName = "";

            int endIndex = 0;
            int index = postUrl.indexOf("/");
            int count=0;
            while(index >= 0) {
               count++;
               index = postUrl.indexOf("/", index+1);
               if(count==2) {
                   endIndex = index;
                   break;
               }
            }
            String splitedServerName = postUrl.substring(postUrl.indexOf("//")+2,endIndex);
            serverName = splitedServerName;
            if(splitedServerName.contains(":")) {
                serverName = splitedServerName.split(":")[0];
                port = Integer.valueOf(splitedServerName.split(":")[1]);
            }

            NTCredentials creds = new NTCredentials(userName, password, domain, domain);
            httpclient.getCredentialsProvider().setCredentials(new AuthScope(serverName, port), creds);

            List authpref = new ArrayList();
            authpref.add(AuthPolicy.NTLM);

            httpclient.getParams().setParameter(AuthPNames.TARGET_AUTH_PREF, authpref);
            HttpHost target = new HttpHost(serverName, port, "http");
            HttpPost httpPost = new HttpPost(postUrl);
            httpPost.setHeader("Accept", "application/json;odata=verbose");
            httpPost.setHeader("Content-Type", "application/json;odata=verbose");
            httpPost.setHeader("X-RequestDigest", digest);

            StringEntity params =new StringEntity(postBody);
            httpPost.setEntity(params);

            HttpContext localContext = new BasicHttpContext();
            HttpResponse response1 = httpclient.execute(target,httpPost, localContext);

             Header[] headers = response1.getAllHeaders();
                for (Header header: headers) {
                    if(header.getName()!=null) {
                    if("Set-Cookie".equals(header.getName())) {
                        response = header.getValue().substring(0, header.getValue().indexOf(";"));
                        if(response.contains("WSS_KeepSessionAuthenticated"))
                            break;
                    }
                    }
                }


        } catch (Exception e) {
            e.printStackTrace();
        }

        return response;

    }

}  

更新
我已经更新了我根据帖子创建批处理数据的代码,并尝试在 setEntity() 方法中传递它。

StringEntity params =new StringEntity(getData(postBody,postUrl));
            httpPost.setEntity(params);  
private static String getData(String postBody, String postUrl) {
        //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           
            JSONObject obj = new JSONObject(postBody);                      
            String[] data= JSONObject.getNames(obj);
            JSONArray jsonArr = obj.toJSONArray(new JSONArray(data));   //Returned string in JSonArray, so convert it to JSonArray

            //SharePoint URL to insert one item     
            String endpoint_Insert = postUrl;       

            //Start: changeset to insert data ----------            
            String batchCnt_Insert = "";
            for(int i=0; i<jsonArr.length(); i++){              
                JSONObject jsonObj =  new JSONObject();
                jsonObj = (JSONObject) jsonArr.get(i);                      //get ith array object  
                String title  = (jsonObj.get("tytle")).toString();  
                String employeeEmail = (jsonObj.get("employeEmail")).toString();    
                String employeeName= (jsonObj.get("employeeName")).toString();
                String employeeNo= (jsonObj.get("employeeNo")).toString();
                String registrationDate =(jsonObj.get("registrationDate")).toString();

                //Start:create INSERT-Statement for one Item ---------------------------                
                String request = "{ \"__metadata\": { \"type\": \"SP.Data.Raffle_x005f_Draw_x005f_RegistrationListItem\" },"
                        + "\"Title\": \""+title+"\",\"Employee_Email\": \""+employeeEmail+"\","
                        + "\"Employee_Name\": \""+employeeName+"\",\"Registration_Date\": \""+registrationDate+"\",\"Employee_No\": \""+employeeNo+"\"}";

                batchCnt_Insert = batchCnt_Insert 
                        + "--changeset_" + changeSetId + "\n"
                        + "Content-Type: application/http" + "\n"
                        + "Content-Transfer-Encoding: binary" + "\n"
                        + "" + "\n"
                        + "POST " + endpoint_Insert + " \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";
        }catch (Exception e) {
            // TODO: handle exception
        }

        return batchContents;
    }
    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;
    }  

我收到以下错误。

postbody {"__metadata": { "type": "SP.Data.RegistrationListItem" },"Title": "New title","Name": "test@gmail.com","Email": "test"},{"__metadata": { "type": "SP.Data.RegistrationListItem" },"Title": "New title","Name": "test@gmail.com","Email": "test"}
{"error":{"code":"-1, Microsoft.SharePoint.Client.InvalidClientQueryException","message":{"lang":"en-US","value":"A node of type 'EndOfInput' was read from the JSON reader when trying to read the start of an entry. A 'StartObject' node was expected."}}}

标签: javasharepointhttp-posthttpconnection

解决方案


在您的代码中,您没有以 Sharepoint REST API 要求的格式发布数据。

预期格式 -

--batch_b27de00f-98f2-4dcb-9fd4-efa8f57380f4 内容类型:多部分/混合;边界="changeset_85050752-ccb7-40d1-a883-2ae3ac0c100c" 内容长度:1161 内容传输编码:二进制

--changeset_85050752-ccb7-40d1-a883-2ae3ac0c100c 内容类型:application/http 内容传输编码:二进制

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 内容类型:application/http 内容传输编码:二进制

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"}

您发布的代码示例中似乎缺少一些必需的部分 - 例如。您在哪里将 MIME 类型指定为多部分/混合?为什么不在 URL 中使用 $batch 端点?

Sharepoint REST API 具有严格的请求/响应格式,您必须遵守该格式才能使其正常工作。要了解规格,请参阅详细的文档链接。您关注的此链接包含有关如何创建批量插入的示例代码


推荐阅读