Я создаю несколько больших файлов (экспорт БД) с помощью Java, и мне нужно разместить их где-нибудь на нашем сервере SharePoint. Прямо сейчас я делаю это с IE, но я бы хотел автоматизировать и этот шаг.
Я поискал в Интернете и нашел несколько советов по использованию SOAP, но пока не совсем понимаю, на чем основывается все это. Может ли кто-нибудь предоставить мне образец кода или рецепт того, что мне нужно делать?
Обратите внимание: сервер SharePoint запрашивает аутентификацию домена NT. Я даже не могу войти в Firefox :(
РЕДАКТИРОВАТЬ




Могу придумать разные варианты:
... и для части аутентификации NTLM:
В дополнение к Предложения Саши вы можете использовать веб-службы SharePoint SOAP. Каждый сайт SharePoint предоставляет набор веб-сервисов по пути http://<Site>/_vti_bin/.
В вашем случае вам, вероятно, понадобится Списки веб-сервисов (http://<Site>/_vti_bin/Lists.asmx). Вы можете получить WSDL с http://<Site>/_vti_bin/Lists.asmx?WSDL. WSS 3.0 SDK содержит подробную информацию о том, как использовать веб-службу (вы, вероятно, захотите использовать методы UpdateListItems и AddAttachment).
С учетом всего сказанного, первый вариант Саши (сопоставление библиотеки документов с диском), вероятно, является самым простым способом, если вы можете обойти проблемы NTLM.
Если вы используете Windows, вы можете просто перейти к UNC-пути к библиотеке документов. Например, если URL-адрес браузера для вашей библиотеки документов:
http://<Site>/Foo/BarDocs/Forms/AllItems.aspx
вы можете просто ввести соответствующий UNC-путь в адресной строке Windows Explorer:
\\<Site>\Foo\BarDocs
а затем перетащите файлы в это место. Если вы хотите, вы можете сопоставить это местоположение с буквой диска с помощью проводника Windows или служебной программы командной строки SUBST.EXE.
Загрузка WSDL работает, но также нет информации о версии: /
Я понимаю, что это значительно позже, но путь UNC у меня сработал. Я смог использовать этот путь с API ввода-вывода Java для записи документов непосредственно в Sharepoint. +1
Хорошо ... после нескольких часов работы и изучения «документации», которую предоставляет MicroSoft, и всех подсказок, случайным образом разнесенных по сети, мне удалось написать пример кода для просмотра содержимого сервера SharePoint: Навигация по папкам SharePoint с помощью Axis2.
Следующая остановка: загрузка чего-либо.
Другое решение - использовать HTTP PUT метод для отправки файла непосредственно в Sharepoint.
Для этого вы можете использовать HTTP-клиент Apache:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.3</version>
</dependency>
А чтобы разрешить аутентификацию NTLMv2, вам понадобится библиотека JCIF.
<dependency>
<groupId>jcifs</groupId>
<artifactId>jcifs</artifactId>
<version>1.3.17</version>
</dependency>
Сначала нам нужно написать оболочку, чтобы разрешить HTTP-клиенту Apache использовать JCIF для поддержки NTLMv2:
public final class JCIFSEngine implements NTLMEngine {
private static final int TYPE_1_FLAGS =
NtlmFlags.NTLMSSP_NEGOTIATE_56
| NtlmFlags.NTLMSSP_NEGOTIATE_128
| NtlmFlags.NTLMSSP_NEGOTIATE_NTLM2
| NtlmFlags.NTLMSSP_NEGOTIATE_ALWAYS_SIGN
| NtlmFlags.NTLMSSP_REQUEST_TARGET;
@Override
public String generateType1Msg(final String domain, final String workstation)
throws NTLMEngineException {
final Type1Message type1Message = new Type1Message(TYPE_1_FLAGS, domain, workstation);
return Base64.encode(type1Message.toByteArray());
}
@Override
public String generateType3Msg(final String username, final String password,
final String domain, final String workstation, final String challenge)
throws NTLMEngineException {
Type2Message type2Message;
try {
type2Message = new Type2Message(Base64.decode(challenge));
} catch (final IOException exception) {
throw new NTLMEngineException("Invalid NTLM type 2 message", exception);
}
final int type2Flags = type2Message.getFlags();
final int type3Flags = type2Flags
& (0xffffffff ^ (NtlmFlags.NTLMSSP_TARGET_TYPE_DOMAIN | NtlmFlags.NTLMSSP_TARGET_TYPE_SERVER));
final Type3Message type3Message = new Type3Message(type2Message, password, domain,
username, workstation, type3Flags);
return Base64.encode(type3Message.toByteArray());
}
}
Основной код для выполнения HTTP PUT с аутентификацией:
try {
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
DefaultHttpClient httpclient = new DefaultHttpClient(params);
//Register JCIF NTLMv2 to manage ntlm auth.
httpclient.getAuthSchemes().register("ntlm", new AuthSchemeFactory() {
@Override
public AuthScheme newInstance(HttpParams hp) {
return new NTLMScheme(new JCIFSEngine());
}
});
//Provide login/password
httpclient.getCredentialsProvider().setCredentials(
AuthScope.ANY,
new NTCredentials([LOGIN], [PASSWORD], "", [DOMAIN]));
//Create HTTP PUT Request
HttpPut request = new HttpPut("http://[server]/[site]/[folder]/[fileName]");
request.setEntity(new FileEntity([File]));
return httpclient.execute(request);
} catch (IOException ex) {
//...
}
Можно ли использовать это решение с HTTP PUT и overwrite = true?
Думаю, мой подход может вам помочь.
Первоначально я создал учетную запись sharepoint и выполнил процедуру по этой ссылке (http://www.ktskumar.com/2017/01/access-sharepoint-online-using-postman/), чтобы получить необходимые учетные данные для REST API. как только я получил учетные данные, все, что мне было нужно, это следующая зависимость и код:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5</version>
</dependency>
Поскольку я использовал аутентификацию OAUTH2, код для получения токена доступа помогает для других операций CRUD.
/* OAuth2 authentication to get access token */
public String getSharePointAccessToken() throws ClientProtocolException, IOException
{
/* Initializing variables */
String grant_type = RcConstants.GRANT_TYPE;
String client_id = RcConstants.CLIENT_ID;
String client_secret = RcConstants.CLIENT_SECRET;
String resource = RcConstants.RESOURCE;
String url = RcConstants.OAUTH_URL + RcConstants.URL_PARAMETER + "/tokens/OAuth/2";
/*
* NOTE: RcConstants.OAUTH_URL =
* https://accounts.accesscontrol.windows.net/ RcConstants.URL_PARAMETER
* = Bearer Realm from
* (http://www.ktskumar.com/2017/01/access-sharepoint-online-using-
* postman/) Figure 6.
*/
/* Building URL */
HttpClient client = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(url);
post.setHeader("Content-Type", "application/x-www-form-urlencoded");
/* Adding URL Parameters */
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
urlParameters.add(new BasicNameValuePair("grant_type", grant_type));
urlParameters.add(new BasicNameValuePair("client_id", client_id));
urlParameters.add(new BasicNameValuePair("client_secret", client_secret));
urlParameters.add(new BasicNameValuePair("resource", resource));
post.setEntity(new UrlEncodedFormEntity(urlParameters));
/* Executing the post request */
HttpResponse response = client.execute(post);
logger.debug("Response Code : " + response.getStatusLine().getStatusCode());
String json_string = EntityUtils.toString(response.getEntity());
JSONObject temp1 = new JSONObject(json_string);
if (temp1 != null)
{
/* Returning access token */
return temp1.get("access_token").toString();
}
return RcConstants.OAUTH_FAIL_MESSAGE;
}
Как только мы получим токен доступа, мы можем загрузить его, используя следующий метод:
public String putRecordInSharePoint(File file) throws ClientProtocolException, IOException
{
/* Token variable declaration */
String token = getSharePointAccessToken();
/* Null or fail check */
if (!token.equalsIgnoreCase(RcConstants.OAUTH_FAIL_MESSAGE))
{
/* Upload path and file name declaration */
String Url_parameter = "Add(url='" + file.getName() + "',overwrite=true)";
String url = RcConstants.UPLOAD_FOLDER_URL + Url_parameter;
/*
* NOTE: RcConstants.UPLOAD_FOLDER_URL =
* https://<your_domain>.sharepoint.com/_api/web/
* GetFolderByServerRelativeUrl('/Shared%20Documents/<FolderName>')/
* Files/
*/
/* Building URL */
HttpClient client = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(url);
post.setHeader("Authorization", "Bearer " + token);
post.setHeader("accept", "application/json;odata=verbose");
/* Declaring File Entity */
post.setEntity(new FileEntity(file));
/* Executing the post request */
HttpResponse response = client.execute(post);
logger.debug("Response Code : " + response.getStatusLine().getStatusCode());
if (response.getStatusLine().getStatusCode() == HttpStatus.OK.value()|| response.getStatusLine().getStatusCode() == HttpStatus.ACCEPTED.value())
{
/* Returning Success Message */
return RcConstants.UPLOAD_SUCCESS_MESSAGE;
}
else
{
/* Returning Failure Message */
return RcConstants.UPLOAD_FAIL_MESSAGE;
}
}
return token;
}
будет ли загружен и этот чек в файле?
@ MonkeyD.Luffy в вашем общем исходном коде, что такое "RcConstants". Я понимаю, что это Java-класс, в котором есть все константы, о которых я думаю. не могли бы вы привести пример того, что мы должны сохранить в этом постоянном файле. например, каким должно быть значение "GRANT_TYPE", "RESOURCE" из вашего постоянного файла?
Мне удалось загрузить и загрузить файлы в sharepoint с помощью этого кода, используя встроенную идентификацию Windows, возможно, это поможет.
public class HttpClient {
HttpClient() { }
public static void download(final String source, final File resultingFile) {
CloseableHttpClient client = WinHttpClients.createSystem();
HttpGet httpRequest = new HttpGet(source);
CloseableHttpResponse httpResponse = null;
try {
httpResponse = client.execute(httpRequest);
HttpEntity entity = httpResponse.getEntity();
if (httpResponse.getStatusLine() != null && httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
LOGGER.warn(httpResponse.getStatusLine());
}else {
LOGGER.debug(httpResponse.getStatusLine());
FileUtils.touch(resultingFile);
InputStream is = entity.getContent();
File outFile = new File(resultingFile.getAbsolutePath());
FileOutputStream fos = new FileOutputStream(outFile);
int inByte;
while ((inByte = is.read()) != -1) {
fos.write(inByte);
}
is.close();
fos.close();
client.close();
}
} catch (ClientProtocolException e) {
LOGGER.warn(e);
} catch (UnsupportedOperationException e) {
LOGGER.warn(e);
} catch (IOException e) {
LOGGER.warn(e);
}
}
public static void upload(final File source, final String destination) {
CloseableHttpClient httpclient = WinHttpClients.createSystem();
HttpPut httpRequest = new HttpPut(destination);
httpRequest.setEntity(new FileEntity(new File(source.getPath())));
CloseableHttpResponse httpResponse = null;
try {
httpResponse = httpclient.execute(httpRequest);
EntityUtils.consume(httpResponse.getEntity());
if (httpResponse.getStatusLine() != null && httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_CREATED) {
LOGGER.debug(httpResponse.getStatusLine());
LOGGER.info("Upload of " + source.getName() + " via HTTP-Client succeeded.");
} else if (httpResponse.getStatusLine() != null && httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
LOGGER.debug(httpResponse.getStatusLine());
}else {
LOGGER.warn("Uploading " + source.getName() + " failed.");
LOGGER.warn(httpResponse.getStatusLine().getStatusCode() + ": " + httpResponse.getStatusLine().getReasonPhrase());
}
} catch (IOException e) {
LOGGER.warn(e);
LOGGER.warn(e.getMessage());
}
return;
}
}
WinHttpClients:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient-win</artifactId>
<version>4.4</version>
</dependency>
Путь:
org.apache.http.impl.client.WinHttpClients
Описание:
Заводские методы для экземпляров CloseableHttpClient настроены на использование встроенной проверки подлинности Windows по умолчанию.
будет ли загружен и этот чек в файле?
Здесь используются нестандартные классы, такие как WinHttpClients. Отредактируйте свой ответ и укажите необходимые зависимости.
Да, это проверка в файлах
В последнее время ваш код очень помог, независимо от того, помог ли он исходному пользователю. Я обновил зависимость, так как та, которую вы опубликовали, не работает.
Последняя сборка моего инструмента фактически использует httpclient и httpclient-win на v4.5.6.
UNC не работает; с каких это пор это доступно? У меня XP, но я понятия не имею, какая версия SP используется.