【问题标题】:Java Webdav File SynchronizationJava Webdav 文件同步
【发布时间】:2014-08-25 20:32:03
【问题描述】:

我在strato 有一个云存储,即hidrive。它使用webdav 协议。请注意,它基于HTTP。他们提供的client application 很差而且有问题,所以我尝试了各种其他同步工具,但没有一个能按我需要的方式工作。

因此,我尝试使用Sardine 项目在Java 中实现它。是否有将本地源文件夹硬拷贝到外部云文件夹的代码?我没有在那个方向找到任何东西。

下面的代码应该是上传文件...

Sardine sardine = SardineFactory.begin("username", "password");

InputStream fis = new FileInputStream(new File("some/file/test.txt"));
sardine.put("https://webdav.hidrive.strato.com/users/username/Backup", fis);

...但会引发异常:

Exception in thread "main" com.github.sardine.impl.SardineException: Unexpected response (301 Moved Permanently)
    at com.github.sardine.impl.handler.ValidatingResponseHandler.validateResponse(ValidatingResponseHandler.java:48)
    at com.github.sardine.impl.handler.VoidResponseHandler.handleResponse(VoidResponseHandler.java:34)
    at com.github.sardine.impl.handler.VoidResponseHandler.handleResponse(VoidResponseHandler.java:1)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:218)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:160)
    at com.github.sardine.impl.SardineImpl.execute(SardineImpl.java:828)
    at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:755)
    at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:738)
    at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:726)
    at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:696)
    at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:689)
    at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:682)
    at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:676)

打印出该目录中的文件夹有效,因此连接/身份验证确实成功:

List<DavResource> resources = sardine.list("https://webdav.hidrive.strato.com/users/username/Backup");

for (DavResource res : resources)
{
    System.out.println(res);
}

请帮助我修复我的代码或将我链接到一些适合我的目的的文件同步库。

【问题讨论】:

    标签: java webdav sardine hidrive


    【解决方案1】:

    Sardine(内部)使用 HttpClient。这里有类似的问题,您可以在其中找到答案Httpclient 4, error 302. How to redirect?

    【讨论】:

    • 如何使用Sardine?有一个 SardineRedirectStrategy 类,但 Sardine 类中没有更改重定向策略的方法。没有这方面的例子。
    • 不是 Sardine 方面的专家,但如果您查看 GitHub (SardineImpl.java) 上的 Sardine 源代码,您会看到他们对通过 HttpClientBuilder 获得的 HttpClient 究竟做了什么。因此,如果 Sardine 本身没有其他公共 API,您可以通过装饰此类来修改行为。
    【解决方案2】:

    在调用 put() 之前尝试将 InputStream obj 转换为字节数组。像下面这样,

    byte[] fisByte = IOUtils.toByteArray(fis);
    sardine.put("https://webdav.hidrive.strato.com/users/username/Backup", fisByte);
    

    它对我有用。让我知道。

    【讨论】:

    • 不幸的是,这并没有改变任何东西。
    【解决方案3】:

    我不得不扩展“org.apache.http.impl.client.LaxRedirectStrategy”以及 org.apache.http.impl.client.DefaultRedirectStrategy 的 getRedirect() 方法,并处理所需的方法:PUT, MKOL等。默认情况下只重定向 GET。

    看起来像这样:

    private static final String[] REDIRECT_METHODS = new String[] { HttpGet.METHOD_NAME, HttpPost.METHOD_NAME, HttpHead.METHOD_NAME, HttpPut.METHOD_NAME, HttpDelete.METHOD_NAME, HttpMkCol.METHOD_NAME };

    isRedirectable-方法

    for (final String m : REDIRECT_METHODS) {
      if (m.equalsIgnoreCase(method)) {
        System.out.println("isRedirectable true");
        return true;
      }
    }
    
    return method.equalsIgnoreCase(HttpPropFind.METHOD_NAME);
    

    getRedirect-方法:

    final URI uri = getLocationURI(request, response, context);
    final String method = request.getRequestLine().getMethod();
    if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
      return new HttpHead(uri);
    } else if (method.equalsIgnoreCase(HttpGet.METHOD_NAME)) {
      return new HttpGet(uri);
    } else if (method.equalsIgnoreCase(HttpPut.METHOD_NAME)) {
    
      HttpPut httpPut = new HttpPut(uri);
      httpPut.setEntity(((HttpEntityEnclosingRequest) request).getEntity());
      return httpPut;
    } else if (method.equalsIgnoreCase("MKCOL")) {
      return new HttpMkCol(uri);
    } else if (method.equalsIgnoreCase("DELETE")) {
      return new HttpDelete(uri);
    
    } else {
      final int status = response.getStatusLine().getStatusCode();
    
      if (status == HttpStatus.SC_TEMPORARY_REDIRECT) {
        return RequestBuilder.copy(request).setUri(uri).build();
      } else {
        return new HttpGet(uri);
      }
    }
    

    这对我有用。

    【讨论】:

      猜你喜欢
      • 2014-11-09
      • 1970-01-01
      • 2014-08-01
      • 1970-01-01
      • 2015-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多