java - 如何使 Jackrabbit WebDAV servlet 允许使用 Microsoft Word 进行编辑?

标签 java ms-word webdav jackrabbit jackrabbit-oak

我正在尝试通过 servlet 公开 Jackrabbit Oak 存储库。虽然我能够成功检索和编辑 .docx文件与 LibreOffice Writer,Microsoft Word 不起作用。

我正在利用:

  • Jackrabbit Oak 版本 1.8.4
  • Jackrabbit 版本 2.17.5
  • LibreOffice Writer 版本 6.1.3.2

无法运行的 Word 版本是:

  • 版本 1708
  • Microsoft Office 365 专业增强版。

我通过使用打开文档对话框并输入 http://localhost:8080/helloworld-singleton/repository/default/test.docx 在两个编辑器中以类似方式访问文档。

我使用 OpenSecurityProvider 设置了一个简单的 servlet公开一个存储库,该存储库复制简单 .docx 文档的本地副本:

public class SimpleWebdavServlet extends SimpleWebdavServlet {
  private static Repository repository;

  public Repository getRepository() {
    return getRepositoryInternal();
  }

  static Repository getRepositoryInternal() {
    try {
      if (repository == null) {
        Jcr jcr = new Jcr().with(new OpenSecurityProvider());
        repository = jcr.createRepository();
        Session session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));

        Node rootNode = session.getRootNode();
        if (!rootNode.hasNode("test.docx")) {
          importFile(session, rootNode);
        }
        session.save();
      }
    } catch (FileNotFoundException | RepositoryException e) {
      e.printStackTrace();
    }
    return repository;
  }

  private static void importFile(Session session, Node rootNode) throws FileNotFoundException, RepositoryException {
    FileInputStream is = new FileInputStream(new File("C:\\test.docx"));
    ValueFactory valueFactory = session.getValueFactory();
    Binary contentValue = valueFactory.createBinary(is);
    Node fileNode = rootNode.addNode("test.docx", "nt:file");
    fileNode.addMixin("mix:referenceable");
    Node resNode = fileNode.addNode("jcr:content", "nt:resource");
    resNode.setProperty("jcr:mimeType", "application/octet-stream");
    resNode.setProperty("jcr:data", contentValue);
    Calendar lastModified = Calendar.getInstance();
    lastModified.setTimeInMillis(lastModified.getTimeInMillis());
    resNode.setProperty("jcr:lastModified", lastModified);
    session.save();
  }
}

此 servlet 通过以下配置 web.xml :

<web-app>
  <display-name>Jackrabbit Webdav</display-name>
  <servlet>
    <servlet-name>Webdav</servlet-name>
    <servlet-class>org.jboss.as.quickstarts.singleton.SimpleWebdavServlet</servlet-class>
    <init-param>
      <param-name>resource-path-prefix</param-name>
      <param-value>/repository</param-value>
    </init-param>
    <init-param>
      <param-name>missing-auth-mapping</param-name>
      <param-value>admin:admin</param-value>
    </init-param>
    <init-param>
      <param-name>resource-config</param-name>
      <param-value>/WEB-INF/config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>Webdav</servlet-name>
    <url-pattern>/repository/*</url-pattern>
  </servlet-mapping>
</web-app>

使用此代码,我希望能够在 Word 中打开文档,对其进行编辑,并将更改保存到服务器 - 就像在 LibreOffice Writer 中一样。

使用 Word 时,文档会使用 protected View 打开,尝试保存更改时,系统只会提示您保存其本地副本。

我尝试为另一个 JCR 实现 ModeShape 制作一个类似的 servlet,并且通过 Word 保存文档时没有遇到任何问题。

作为在 Jackrabbit 内部调试时的一个可能的解释,编辑器之间的一个显着差异是 LibreOffice Writer 发送 nullAuthorization标题,而 Word 发送 BearerAuthorization它的几个请求的 header 。由于 org.apache.jackrabbit.webdav.DavException: Unable to decode authorization. 异常(exception),所有这些请求都将被忽略。

有人知道为什么 Word 在这种情况下不能按预期工作吗?

最佳答案

我确认 jackrabbit-jcr-server 不支持“授权:承载”。 BasicCredentialsProvider 类仅支持“login:password”base64 编码的基本身份验证。

出于测试目的,我修改了 getCredentials() 方法,以在收到承载授权时强制使用“admin/admin”进行基本身份验证:

...
if (authStr.length >= 2 && authStr[0].equalsIgnoreCase(HttpServletRequest.BASIC_AUTH)) {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    Base64.decode(authStr[1].toCharArray(), out);
    String decAuthStr = out.toString("ISO-8859-1");
    int pos = decAuthStr.indexOf(':');
    String userid = decAuthStr.substring(0, pos);
    String passwd = decAuthStr.substring(pos + 1);
    return new SimpleCredentials(userid, passwd.toCharArray());
} else if (authStr.length >= 1 && authStr[0].equalsIgnoreCase("Bearer")) {
    return new SimpleCredentials("admin", "admin".toCharArray());
}
throw new ServletException("Unable to decode authorization.");
...

之后我重新编译了jackrabbit-jcr-server(使用maven)并重新部署它,然后用MS Word直接编辑就可以了。

现在应该做一个更好的实现......

关于java - 如何使 Jackrabbit WebDAV servlet 允许使用 Microsoft Word 进行编辑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54018827/

相关文章:

java - 如何从 WebDAV 服务器找到文件校验和(MD5 或...)

macos - 通过命令行挂载网络卷是 OS X

java - 如何将 SPDY 与 HttpClient 4 一起使用?

c# - 在 office 2010 中将受密码保护的 OpenXml Word 文档重新保存为受密码保护的二进制 Word 时显示错误

java - 如果字符串大于 6 个字符,代码会给出重复值。适合 1-6 个字符的字符串...

C# DocX : Inserting new numbered list continues numbering

python - 将代码复制到word文档中并保持格式

objective-c - WTClient 中的 PROPFIND 请求

Java无法将子类对象添加到列表中

java - 如何路由到最近的 RMI 服务器?