6

I Know there are several post on sharepoint.stackexchange/stack overflow for this. But I didn't get from any of the post how to achieve this. I have access of share point (I mean share point credentials are same as my windows credential )

So, without using any Tool if I am hitting this URLfrom browser

https://myCompany.sharepoint.com/sites/abcd/_api/web/GetFolderByServerRelativeUrl('xyz')/Files('file1.xlsx')/$value

I am able to download the file.
But How I can achieve it using Java Restful API call (Not SOAP call)?
Will plain Java will be enough or we need any Third Party (not commercial Jar) to connect to shaare point from Java ?
How we can upload a local file using Java to share point?

4 Answers 4

6

For connecting to share point using rest Api 1st we need to request client id, client secret for a share point library.
Step 1 - once you got client id and secret follow steps mentioned at - https://www.ktskumar.com/2017/01/access-sharepoint-online-using-postman/ to generate access token. using access token we can connect to share point using Rest Api or Java.
Download a file -

url: http://site url/_api/web/GetFolderByServerRelativeUrl('/Folder Name')/Files('file name')/$value
method: GET
headers:
    Authorization: "Bearer " + accessToken // what we got in step 1

Upload File : -
if your share point don't have any approval work flow then :-

url: http://site url/_api/web/GetFolderByServerRelativeUrl('/Folder Name')/Files/add(url='a.txt',overwrite=true)
method: POST
body: "Contents of file"
Headers: 
    Authorization: "Bearer " + accessToken
    content-length:length of post body

If your share point library have approval work flow then we have to follow these steps: -
Step a) - upload file using Post request as I mentioned above
Step b) - check in last uploaded file using post request

url: http://site url/_api/web/GetFileByServerRelativeUrl('/Folder Name/file name')/CheckIn(comment='Comment',checkintype=0)
method: POST
headers:
    Authorization: "Bearer " + accessToken

Step c)- update approval status of recent uploaded file follow this answer or post - https://sharepoint.stackexchange.com/a/253137/79002
Best blog to read :- https://blogs.sap.com/2018/02/01/consume-sharepoint-rest-to-create-a-file-using-java-sap-pi-udf/

1
  • To anyone who is looking for a way to get the Access Token from Sharepoint via Java, check this post! Commented Sep 3 at 8:54
2

This Code is working perfectly to upload file up to 249MB using SP online. You need to add "httpclient-4.3.6" this jar in your build path.

package test;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.FileEntity;
import org.apache.http.impl.client.DefaultHttpClient;

public class fileUpload {
private static void executeRequest(HttpPost httpPost) {
    try {
        HttpClient client = new DefaultHttpClient();
        HttpResponse response = client.execute(httpPost);
        System.out.println("Response Code:  " + response.getStatusLine().getStatusCode());
    }  catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void executeMultiPartRequest(String urlString, File file) throws IOException {
    HttpPost postRequest = new HttpPost(urlString);
    postRequest = addHeader(postRequest, "Access Token");
    try {
        postRequest.setEntity(new FileEntity(file));
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    executeRequest(postRequest);
}

private static HttpPost addHeader(HttpPost httpPost, String accessToken) {
    httpPost.addHeader("Accept", "application/json;odata=verbose");
    httpPost.setHeader("Authorization", "Bearer " + accessToken);
    return httpPost;
}

public static void main(String args[]) throws IOException {
    fileUpload fileUpload = new fileUpload();
    File file = new File("C:\\users\\bgulati\\Desktop\\test.docx");
    fileUpload.executeMultiPartRequest(
            "Here Goes the URL", file);

}
}
0

I do not how to do it but these links below will definitely lead you to your answer.

How to call the SharePoint rest API using Java web application?

Connect to Sharepoint Online REST API using Java

1
  • 1
    I have already gone through both links but no Luck :( Commented Oct 14, 2018 at 13:18
0

To anyone looking for a Java implementation using RestTemplate:

I figured out how to upload a file to Sharepoint, since I had the same necessity.

First of all, we need to retrieve our Bearer Token:

SharepointResponse class

@Getter
@Setter
public class SharepointResponse {
    @JsonProperty("token_type")
    private String tokenType;
    @JsonProperty("expires_in")
    private int expiration;
    @JsonProperty("ext_expires_in")
    private int extExpiration;
    @JsonProperty("access_token")
    private String accessToken;
}

Imports and global variables/constants

import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
import java.util.Collections;

@Autowired
RestTemplate restTemplate;

@Value("${tenant-id}") // you can retrieve them from application.properties
private String tenantId;
@Value("${client-id}")
private String clientId;
@Value("${client-secret}")
private String clientSecret;
@Value("${site-id}")
private String siteId;

private static final int CHUNK_SIZE = 5 * 1024 * 1024;

Code snippet

String url = "https://login.microsoftonline.com/" + tenantId + "/oauth2/v2.0/token";
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_FORM_URLENCODED));
headers.set(
        "Authorization",
        "Basic " + new String(
                Base64.encodeBase64(
                        (clientId + ":" + clientSecret)
                                .getBytes(StandardCharsets.US_ASCII)
                )
        )
);
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("grant_type", "client_credentials");
body.add("scope", "https://graph.microsoft.com/.default");
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(body, headers);
ResponseEntity<SharepointResponse> response = restTemplate.exchange(url, HttpMethod.POST, entity, SharepointResponse.class);
if (response.getStatusCodeValue() == 200) {
    String token = response.getBody().getAccessToken();
    doUpload(token);
} else {
    // DO SOMETHING - retrieving token failed
}

Now, we need the Site Id. We can retrieve it by performing a GET at this endpoint:

https://graph.microsoft.com/v1.0/sites/<YOUR_HOST.sharepoint.com>:/sites/<YOUR_SITE>?$select=id

We need to put a Bearer Authentication header, with the token we retrieved earlier.

After that, we have two choices:

  1. Perform a PUT request to https://graph.microsoft.com/v1.0/sites/<YOUR_SITE_ID>/drive/root:/<OUTPUT_FILE_NAME>:/content
    NOTE, the maximum upload size is 4MB!
  2. Perform a POST request to https://graph.microsoft.com/v1.0/sites/<YOUR_SITE_ID>/drive/root:/<OUTPUT_FILE_NAME>:/createUploadSession and then perform a PUT request to the uploadUrl we obtained earlier

In the Java code below, I will show you the second option.

doUpdate() method

public void doUpdate(String token){
    String fileName = "output_file_name.txt";
    String sessionCreationUrl = "https://graph.microsoft.com/v1.0/sites/" + siteId + "/drive/root:/" + fileName + ":/createUploadSession";
    String sessionUrl = createUploadSession(token, sessionCreationUrl);
    if (sessionUrl != null) {
        uploadFile(sessionUrl, "/path/to/file_to_upload", token);
    } else {
        // DO SOMETHING - creating session failed
    }
}

createUploadSession() method

private String createUploadSession(String accessToken, String url){
    HttpHeaders headers = new HttpHeaders();
    headers.setBearerAuth(accessToken);
    headers.setContentType(MediaType.APPLICATION_JSON);

    // Request body for creating upload session
    Map<String, Object> body = Collections.emptyMap();

    HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(body, headers);

    ResponseEntity<Map> response = restTemplate.postForEntity(url, requestEntity, Map.class);

    if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
        return (String) response.getBody().get("uploadUrl");
    }

    return null;
}

uploadFile() method

private void uploadFileInChunks(String sessionUrl, String filePath, String accessToken) throws IOException {
    File file = new File(filePath);
    FileInputStream fis = new FileInputStream(file);
    byte[] buffer = new byte[CHUNK_SIZE];

    long fileSize = file.length();
    long bytesRemaining = fileSize;
    long offset = 0;

    while (bytesRemaining > 0) {
        int bytesRead = fis.read(buffer, 0, CHUNK_SIZE);

        if (bytesRead <= 0) {
            break;
        }

        byte[] chunk = new byte[bytesRead];
        System.arraycopy(buffer, 0, chunk, 0, bytesRead);

        HttpHeaders headers = new HttpHeaders();
        headers.setBearerAuth(accessToken);
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

        // Set the content range header
        String contentRange = "bytes " + offset + "-" + (offset + bytesRead - 1) + "/" + fileSize;
        headers.set("Content-Range", contentRange);

        HttpEntity<byte[]> chunkEntity = new HttpEntity<>(chunk, headers);

        ResponseEntity<String> response = restTemplate.exchange(sessionUrl, HttpMethod.PUT, chunkEntity, String.class);

        if (!response.getStatusCode().is2xxSuccessful()) {
            // DO SOMETHING - upload failed
        }

        offset += bytesRead;
        bytesRemaining -= bytesRead;
    }

    fis.close();
}

This was also answered on Stack Overflow, at this link.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.