如何在 android 上使用 Graph API 将文件上传到 Sharepoint 站点的文档库
How to upload files to sharepoint site's document library using Graph API on android
我正在开发一个 android 应用程序 (Java Android),它需要将 excel 文件上传到 Sharepoint 站点的库,开始我使用了这个示例使用图表 API : https://github.com/microsoftgraph/android-java-connect-sample
此示例将图片上传到用户的 One Drive 存储库。
所以,多亏了 graph explorer,我更改了查询,这样图片就进入了我网站的库并且它可以工作,但是当我从我的 android 应用程序执行查询时,我得到了这个错误:403 error
我的代码:
public void uploadPictureToOneDrive(byte[] picture, ICallback<DriveItem> callback) {
try {
String id = new String("groupeeiffage.sharepoint.com,1f99a971-b596-4c9b-ba31-784d70c05f49,88ea0abd-a92d-412c-b047-86744a64c0ea");
mGraphServiceClient
.getSites(id)
.getDrive()
.getRoot()
.getItemWithPath("me.png")
.getContent()
.buildRequest()
.put(picture, callback);
} catch (Exception ex) {
showException(ex, "exception on upload picture to OneDrive ","Upload picture failed", "The upload picture method failed");
}
}
我知道这是授权问题,但我在 Microsoft 文档中迷路了。我如何允许我的应用程序使用 Graph API 将文件上传到共享点?
如果有人已经做过类似的事情,我真的很想得到一些帮助。
作为解决方法,我们可以使用 SharePoint REST API 在 Android 中上传文件。
- 从 Microsoft 身份验证门户获取安全令牌:
public String receiveSecurityToken() throws TransformerException, URISyntaxException {
RequestEntity<String> requestEntity =
new RequestEntity<>(buildSecurityTokenRequestEnvelope(),
HttpMethod.POST,
new URI("https://login.microsoftonline.com/extSTS.srf"));
ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
DOMResult result = new DOMResult();
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new StringSource(responseEntity.getBody()), result);
Document definitionDocument = (Document) result.getNode();
String securityToken = xPathExpression.evaluateAsString(definitionDocument);
if (StringUtils.isBlank(securityToken)) {
throw new SharePointAuthenticationException("Unable to authenticate: empty token");
}
return securityToken;
}
发送到门户的信封格式如下:
<s:Envelope
xmlns:s="http://www.w3.org/2003/05/soap-envelope"
xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1">https://login.microsoftonline.com/extSTS.srf</a:To>
<o:Security s:mustUnderstand="1"
xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:UsernameToken>
<o:Username>[username]</o:Username>
<o:Password>[password]</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body>
<t:RequestSecurityToken
xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
<wsp:AppliesTo
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<a:EndpointReference>
<a:Address>[SharePoint domain address]</a:Address>
</a:EndpointReference>
</wsp:AppliesTo>
<t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType>
<t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
<t:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</t:TokenType>
</t:RequestSecurityToken>
</s:Body>
</s:Envelope>
- 从 SharePoint Online 服务器获取 cookie:
public List<String> getSignInCookies(String securityToken) throws TransformerException, URISyntaxException {
RequestEntity<String> requestEntity =
new RequestEntity<>(securityToken,
HttpMethod.POST,
new URI("[SharePoint domain address]/_forms/default.aspx?wa=wsignin1.0"));
ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
HttpHeaders headers = responseEntity.getHeaders();
List<String> cookies = headers.get("Set-Cookie");
if (CollectionUtils.isEmpty(cookies)) {
throw new SharePointSignInException("Unable to sign in: no cookies returned in response");
}
return cookies;
}
- 获取 SharePoint Online 服务器请求的签名 (FormDigestValue):
public String getFormDigestValue(List<String> cookies) throws IOException, URISyntaxException,
TransformerException, JSONException {
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Cookie", Joiner.on(';').join(cookies));
headers.add("Accept", "application/json;odata=verbose");
headers.add("X-ClientService-ClientTag", "SDK-JAVA");
RequestEntity<String> requestEntity = new RequestEntity<>(headers,
HttpMethod.POST, new URI("[SharePoint domain address]/_api/contextinfo"));
ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
JSONObject json = new JSONObject(responseEntity.getBody());
return json.getJSONObject("d")
.getJSONObject("GetContextWebInformation").getString("FormDigestValue");
}
最后,我们可以调用 REST API 来上传文件,如下所示。
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
X-RequestDigest: form digest value
content-length:length of post body
public String performHttpRequest(String path, String json, boolean isUpdate) throws Exception {
String securityToken = receiveSecurityToken();
List<String> cookies = getSignInCookies(securityToken);
String formDigestValue = getFormDigestValue(cookies);
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Cookie", Joiner.on(';').join(cookies));
headers.add("Content-type", "application/json;odata=verbose");
headers.add("X-RequestDigest", formDigestValue);
RequestEntity<String> requestEntity = new RequestEntity<>(json,
headers, HttpMethod.POST, new URI(path));
ResponseEntity<String> responseEntity =
restTemplate.exchange(requestEntity, String.class);
return responseEntity.getBody();
}
更多信息供您参考:
我正在开发一个 android 应用程序 (Java Android),它需要将 excel 文件上传到 Sharepoint 站点的库,开始我使用了这个示例使用图表 API : https://github.com/microsoftgraph/android-java-connect-sample 此示例将图片上传到用户的 One Drive 存储库。
所以,多亏了 graph explorer,我更改了查询,这样图片就进入了我网站的库并且它可以工作,但是当我从我的 android 应用程序执行查询时,我得到了这个错误:403 error
我的代码:
public void uploadPictureToOneDrive(byte[] picture, ICallback<DriveItem> callback) {
try {
String id = new String("groupeeiffage.sharepoint.com,1f99a971-b596-4c9b-ba31-784d70c05f49,88ea0abd-a92d-412c-b047-86744a64c0ea");
mGraphServiceClient
.getSites(id)
.getDrive()
.getRoot()
.getItemWithPath("me.png")
.getContent()
.buildRequest()
.put(picture, callback);
} catch (Exception ex) {
showException(ex, "exception on upload picture to OneDrive ","Upload picture failed", "The upload picture method failed");
}
}
我知道这是授权问题,但我在 Microsoft 文档中迷路了。我如何允许我的应用程序使用 Graph API 将文件上传到共享点?
如果有人已经做过类似的事情,我真的很想得到一些帮助。
作为解决方法,我们可以使用 SharePoint REST API 在 Android 中上传文件。
- 从 Microsoft 身份验证门户获取安全令牌:
public String receiveSecurityToken() throws TransformerException, URISyntaxException {
RequestEntity<String> requestEntity =
new RequestEntity<>(buildSecurityTokenRequestEnvelope(),
HttpMethod.POST,
new URI("https://login.microsoftonline.com/extSTS.srf"));
ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
DOMResult result = new DOMResult();
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new StringSource(responseEntity.getBody()), result);
Document definitionDocument = (Document) result.getNode();
String securityToken = xPathExpression.evaluateAsString(definitionDocument);
if (StringUtils.isBlank(securityToken)) {
throw new SharePointAuthenticationException("Unable to authenticate: empty token");
}
return securityToken;
}
发送到门户的信封格式如下:
<s:Envelope
xmlns:s="http://www.w3.org/2003/05/soap-envelope"
xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1">https://login.microsoftonline.com/extSTS.srf</a:To>
<o:Security s:mustUnderstand="1"
xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:UsernameToken>
<o:Username>[username]</o:Username>
<o:Password>[password]</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body>
<t:RequestSecurityToken
xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
<wsp:AppliesTo
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<a:EndpointReference>
<a:Address>[SharePoint domain address]</a:Address>
</a:EndpointReference>
</wsp:AppliesTo>
<t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType>
<t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
<t:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</t:TokenType>
</t:RequestSecurityToken>
</s:Body>
</s:Envelope>
- 从 SharePoint Online 服务器获取 cookie:
public List<String> getSignInCookies(String securityToken) throws TransformerException, URISyntaxException {
RequestEntity<String> requestEntity =
new RequestEntity<>(securityToken,
HttpMethod.POST,
new URI("[SharePoint domain address]/_forms/default.aspx?wa=wsignin1.0"));
ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
HttpHeaders headers = responseEntity.getHeaders();
List<String> cookies = headers.get("Set-Cookie");
if (CollectionUtils.isEmpty(cookies)) {
throw new SharePointSignInException("Unable to sign in: no cookies returned in response");
}
return cookies;
}
- 获取 SharePoint Online 服务器请求的签名 (FormDigestValue):
public String getFormDigestValue(List<String> cookies) throws IOException, URISyntaxException,
TransformerException, JSONException {
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Cookie", Joiner.on(';').join(cookies));
headers.add("Accept", "application/json;odata=verbose");
headers.add("X-ClientService-ClientTag", "SDK-JAVA");
RequestEntity<String> requestEntity = new RequestEntity<>(headers,
HttpMethod.POST, new URI("[SharePoint domain address]/_api/contextinfo"));
ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
JSONObject json = new JSONObject(responseEntity.getBody());
return json.getJSONObject("d")
.getJSONObject("GetContextWebInformation").getString("FormDigestValue");
}
最后,我们可以调用 REST API 来上传文件,如下所示。
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
X-RequestDigest: form digest value
content-length:length of post body
public String performHttpRequest(String path, String json, boolean isUpdate) throws Exception {
String securityToken = receiveSecurityToken();
List<String> cookies = getSignInCookies(securityToken);
String formDigestValue = getFormDigestValue(cookies);
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Cookie", Joiner.on(';').join(cookies));
headers.add("Content-type", "application/json;odata=verbose");
headers.add("X-RequestDigest", formDigestValue);
RequestEntity<String> requestEntity = new RequestEntity<>(json,
headers, HttpMethod.POST, new URI(path));
ResponseEntity<String> responseEntity =
restTemplate.exchange(requestEntity, String.class);
return responseEntity.getBody();
}
更多信息供您参考: