Как загрузить документ в SharePoint с помощью Java?

Я создаю несколько больших файлов (экспорт БД) с помощью Java, и мне нужно разместить их где-нибудь на нашем сервере SharePoint. Прямо сейчас я делаю это с IE, но я бы хотел автоматизировать и этот шаг.

Я поискал в Интернете и нашел несколько советов по использованию SOAP, но пока не совсем понимаю, на чем основывается все это. Может ли кто-нибудь предоставить мне образец кода или рецепт того, что мне нужно делать?

Обратите внимание: сервер SharePoint запрашивает аутентификацию домена NT. Я даже не могу войти в Firefox :(

РЕДАКТИРОВАТЬ

  • Как преобразовать страшный URL-адрес в IE в путь WebDAV?
  • Есть ли «проводник» WebDAV, который я могу использовать, прежде чем разрушить производственную систему своим кодом? Я попробовал "DAV Explorer 0.91" из http://www.davexplorer.org/, но он не может подключиться (вероятно, из-за аутентификации домена NT).
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
16
0
43 521
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Могу придумать разные варианты:

  • Сопоставьте библиотеку документов с файловым диском и просто сохраните файл, как любой другой файл в файловой системе.
  • По протоколу HTTP WebDAV.

... и для части аутентификации NTLM:

http://www.luigidragone.com/networking/ntlm.html

В дополнение к Предложения Саши вы можете использовать веб-службы 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.

UNC не работает; с каких это пор это доступно? У меня XP, но я понятия не имею, какая версия SP используется.

Aaron Digulla 24.11.2008 19:45

Загрузка WSDL работает, но также нет информации о версии: /

Aaron Digulla 24.11.2008 19:47

Я понимаю, что это значительно позже, но путь UNC у меня сработал. Я смог использовать этот путь с API ввода-вывода Java для записи документов непосредственно в Sharepoint. +1

RustyTheBoyRobot 06.12.2012 02:41
Ответ принят как подходящий

Хорошо ... после нескольких часов работы и изучения «документации», которую предоставляет 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?

Daniel Rodríguez 17.01.2018 16:29

Думаю, мой подход может вам помочь.

Первоначально я создал учетную запись 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;
}

будет ли загружен и этот чек в файле?

CodingOwl 26.06.2018 16:25

@ MonkeyD.Luffy в вашем общем исходном коде, что такое "RcConstants". Я понимаю, что это Java-класс, в котором есть все константы, о которых я думаю. не могли бы вы привести пример того, что мы должны сохранить в этом постоянном файле. например, каким должно быть значение "GRANT_TYPE", "RESOURCE" из вашего постоянного файла?

Anurag_BEHS 20.10.2018 16:57

Мне удалось загрузить и загрузить файлы в 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 по умолчанию.

будет ли загружен и этот чек в файле?

CodingOwl 26.06.2018 16:25

Здесь используются нестандартные классы, такие как WinHttpClients. Отредактируйте свой ответ и укажите необходимые зависимости.

Aaron Digulla 03.07.2018 18:01

Да, это проверка в файлах

go4X 02.08.2018 18:22

В последнее время ваш код очень помог, независимо от того, помог ли он исходному пользователю. Я обновил зависимость, так как та, которую вы опубликовали, не работает.

JoshDM 03.04.2019 00:43

Последняя сборка моего инструмента фактически использует httpclient и httpclient-win на v4.5.6.

go4X 18.04.2019 16:06

Другие вопросы по теме