How do I upload a document to SharePoint with Java?

I can think of different options:

  • Mapping the Document library to a file drive and just save the file like any other file in the file system.
  • Using HTTP WebDAV protocol.

...and for the NTLM authentication part:

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


In addition to Sacha's suggestions, you can use the SharePoint SOAP web services. Each SharePoint site exposes a bunch of web services via the path http://<Site>/_vti_bin/.

In your case, you probably want the Lists web service (http://<Site>/_vti_bin/Lists.asmx). You can grab the WSDL from http://<Site>/_vti_bin/Lists.asmx?WSDL. The WSS 3.0 SDK has details on how to use the web service (you'll probably want to use the UpdateListItems and AddAttachment methods).

All that said, Sacha's first option (mapping a document library to a drive) is probably the easiest way assuming you can get around the NTLM issues.

If you're using Windows you can simply navigate to a UNC path for a document library. For example, if the browser URL for your document library is:

http://<Site>/Foo/BarDocs/Forms/AllItems.aspx

you can simply type the corresponding UNC path in the Windows Explorer address bar:

\\<Site>\Foo\BarDocs

and then drag and drop files to this location. If you'd like you can map this location to a drive letter using Windows Explorer or the SUBST.EXE command-line utility.


Okay ... after several hours of work and biting myself through the "documentation" MicroSoft provides and all the hints randomly spread over the 'net, I've managed to write some sample code to browse the content of a SharePoint server: Navigating SharePoint Folders With Axis2.

Next stop: Uploading something.


An other solution is to use HTTP PUT method to send a file directly to the Sharepoint.

For that you can use Apache HTTP Client:

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.2.3</version>
</dependency>

And to permit NTLMv2 authentication you need JCIF library.

<dependency>
   <groupId>jcifs</groupId>
   <artifactId>jcifs</artifactId>
   <version>1.3.17</version>
</dependency>

First we need to write a wrapper to permit Apache HTTP Client to use JCIF for NTLMv2 support :

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());
    }
}

Reference

The main code to execute HTTP PUT with authentication:

    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) {
      //...
    }