如何使用 Java 代码将文档添加到 Alfresco 存储库?

How to add a document to the Alfresco Repository with Java code?

编辑:显然我必须制作一个 AMP 并将其映射到 Alfresco.war。但是现在我不能访问我写的代码,所以我想我将不得不使用 Webscripts 之类的。有人可以提供一个示例,说明如何使用 Java 支持的网络脚本将文档添加到 Alfresco 存储库吗?

原始问题:

我在 google 范围内搜索了一种使用 Java 代码将文档添加到 Alfresco 存储库的方法。但是我找不到可行的方法。我知道如何将文档添加到存储库:使用 NodeService。但问题是我无法获得 NodeService 的实例。我试过用@Autowired 注入它,我试过使用 bean,我试过使用 ApplicationContext。 None 的方法...

方式一:
注入 class:

@Autowired
NodeService nodeService

方式二:
在役-context.xml:

<bean id="somerandombeanname" class="management.FileManager" >
    <property name="moduleId" value="${project.artifactId}" />
    <property name="serviceRegistry" ref="ServiceRegistry" />
    <property name="nodeService" ref="NodeService" />
    <property name="transactionService" ref="TransactionService" />
    <property name="contentService" ref="ContentService" />
</bean>

在 class 中,我为所有服务和 serviceRegistry 添加了 getter 和 setter:

private NodeService nodeService;

public void setNodeService(NodeService nodeService) {
        this.nodeService = nodeService;
}

方式三:

appContext = new ClassPathXmlApplicationContext("classpath:alfresco/application-context.xml");

serviceRegistry = (ServiceRegistry) appContext.getBean(ServiceRegistry.SERVICE_REGISTRY);

nodeService = serviceRegistry.getNodeService();

方法#1 和#2 给了我一个 NullPointerException,只是声明 NodeService 为空。由于 AlfrescoRuntimeException,方式 #3 给出了一英里长的 StackTrace,因为它未能初始化密钥库:

Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ssl.keyStore' defined in class path resource [alfresco/encryption-context.xml]: Invocation of init method failed; nested exception is org.alfresco.error.AlfrescoRuntimeException: 04180000 Failed to initialize keystore:
Location: E:/Alfresco/alf_data/keystore/ssl.keystore
Provider: null
Type:     JCEKS
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1513)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:293)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:633)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at management.FileManager.<init>(FileManager.java:36)
    at simple.start.main(start.java:25)
    ... 5 more
Caused by: org.alfresco.error.AlfrescoRuntimeException: 04180000 Failed to initialize keystore:
Location: E:/Alfresco/alf_data/keystore/ssl.keystore
Provider: null
Type:     JCEKS
    at org.alfresco.encryption.AlfrescoKeyStoreImpl.loadKeyStore(AlfrescoKeyStoreImpl.java:566)
    at org.alfresco.encryption.AlfrescoKeyStoreImpl.safeInit(AlfrescoKeyStoreImpl.java:537)
    at org.alfresco.encryption.AlfrescoKeyStoreImpl.init(AlfrescoKeyStoreImpl.java:122)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1639)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1580)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1510)
    ... 18 more
Caused by: java.lang.IllegalArgumentException: name
    at sun.misc.URLClassPath$Loader.findResource(URLClassPath.java:494)
    at sun.misc.URLClassPath.findResource(URLClassPath.java:176)
    at java.net.URLClassLoader.run(URLClassLoader.java:551)
    at java.net.URLClassLoader.run(URLClassLoader.java:549)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findResource(URLClassLoader.java:548)
    at java.lang.ClassLoader.getResource(ClassLoader.java:1147)
    at org.springframework.core.io.ClassPathResource.resolveURL(ClassPathResource.java:147)
    at org.springframework.core.io.ClassPathResource.exists(ClassPathResource.java:135)
    at org.alfresco.encryption.SpringKeyResourceLoader.getSafeInputStream(SpringKeyResourceLoader.java:67)
    at org.alfresco.encryption.SpringKeyResourceLoader.loadKeyMetaData(SpringKeyResourceLoader.java:133)
    at org.alfresco.encryption.AlfrescoKeyStoreImpl$KeyInfoManager.loadKeyMetaData(AlfrescoKeyStoreImpl.java:1016)
    at org.alfresco.encryption.AlfrescoKeyStoreImpl$KeyInfoManager.<init>(AlfrescoKeyStoreImpl.java:998)
    at org.alfresco.encryption.AlfrescoKeyStoreImpl.getKeyInfoManager(AlfrescoKeyStoreImpl.java:395)
    at org.alfresco.encryption.AlfrescoKeyStoreImpl.loadKeyStore(AlfrescoKeyStoreImpl.java:560)
    ... 27 more

是的,密钥库存在,是的,我已经重新生成了一个新的密钥库。

我正在使用 Alfresco 5.0.1,我正在 Repository 方面(不是共享)工作。

@Autowired
NodeService nodeService

不能在露天使用

您需要使用正确的 setter 方法注入它。 您的 bean 应该如下所示。

<bean id="somerandombeanname" class="management.FileManager" >
    <property name="moduleId" value="${project.artifactId}" />
    <property name="serviceRegistry" ref="ServiceRegistry" />
    <property name="nodeService" ref="NodeService" />
    <property name="transactionService" ref="TransactionService" />
    <property name="contentService" ref="ContentService" />
</bean>

您的 java class 应包含以下用于注入 nodeService 的内容。

private NodeService nodeService;

public void setNodeService(NodeService nodeService) {
        this.nodeService = nodeService;
}

幸运的是我有通过 JAVA 支持的网络脚本上传文件的代码。希望这可以帮助您 too.To 创建 java 支持的 webscript 请参阅 this

创建一个名为CustomFileUpload.java的class并放入以下内容

package com.upload;

import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.io.IOUtils;
import org.json.JSONException;
import org.json.JSONObject;

public class CustomFileUpload extends DeclarativeWebScript {

    private final String UPLOAD_FILE_PATH = "C:\Users\Test\Desktop\test.txt";
    private int statusCode;

    protected Map<String, Object> executeImpl(WebScriptRequest arg0, Status status, Cache cache) {
        Map<String, Object> model = new HashMap<String, Object>();
        try {
            String URL = "http://localhost:8080/alfresco/service/upload/fileupload?alf_ticket=" +getAlfticket();
            File file = new File(UPLOAD_FILE_PATH);
            String filetype = "text/plain";
            String filename = file.getName();
            HttpClient client = new HttpClient();
            PostMethod post = new PostMethod(URL);

            Part[] parts = {

                    new FilePart("filedata", filename, file, filetype, null),
                    new StringPart("filename", filename),
                    new StringPart("description", "This is test description"),
                    new StringPart("destination", "workspace://SpacesStore/bb424b1d-0418-4954-8591-b8c807264df0")
            };

            post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));
            statusCode = client.executeMethod(post);
            System.out.println(post.getResponseBodyAsString());
            post.releaseConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (statusCode == 200) {
            model.put("result", "File uploaded successfully.");
            return model;
        } else {
            model.put("result", "There was an error while uploading document.");
            return model;
        }
    }

    private static String getAlfticket() throws IOException, JSONException {
        URL url = new URL("http://localhost:8080/alfresco/service/api/login?u=admin&pw=admin&format=json");
        URLConnection con = url.openConnection();
        InputStream in = con.getInputStream();
        String encoding = con.getContentEncoding();
        encoding = encoding == null ? "UTF-8" : encoding;
        String json = IOUtils.toString(in, encoding);
        JSONObject getData = new JSONObject(json);

        return getData.getJSONObject("data").get("ticket").toString();
    }
}

注意: 在目标位置,您可以将要上传的文件夹的 nodeRef 放入其中。

然后在上下文文件中创建 bean,随便你怎么命名 mycustom-context.xml 并将其放入 ALFRESCO_HOME\tomcat\shared\classes\alfresco\extension 和内容

<bean id="webscript.com.upload.customupload.post" class="com.upload.CustomFileUpload" parent="webscript">
</bean>

最终通过创建 customupload.post.desc.xml 在 alfresco 中注册此 Web 脚本。然后放

<webscript>
   <shortname>File Upload</shortname>
   <description>Upload files to user home</description>
   <url>/upload/fileupload?alf_ticket={ticket}</url>
   <format default="json"/>
   <authentication>user</authentication>
</webscript>

我们声明的最后创建视图 JSON 是默认格式,因此我们需要创建 customupload.post.json.ftl

${result}

并将这两个文件放入 ALFRESCO_HOME\tomcat\shared\classes\alfresco\extension\templates\webscripts\com\upload

现在重启服务器并点击http://localhost:8080/alfresco/service/upload/fileupload and you will see file uploaded in folder(Whatever you have given). For Reference

终于!这是将文件添加到存储库的解决方案:

CustomFileUpload.java:

package org.example;

import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.apache.commons.io.FileUtils;

public class CustomFileUpload extends DeclarativeWebScript {
    private final String UPLOAD_FILE_PATH = "{someRandomFile}";
    private final String UPLOAD_DESTINATION = "workspace://SpacesStore/{someRandomNodeRef}";
    protected ServiceRegistry serviceRegistry;

    public ServiceRegistry getServiceRegistry() {
        return serviceRegistry;
    }

    public void setServiceRegistry(ServiceRegistry serviceRegistry) {
        this.serviceRegistry = serviceRegistry;
    }

    protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache) {
        File file = new File(UPLOAD_FILE_PATH);
//      NodeRef parent = getCompanyHome();
        NodeRef parent = new NodeRef(UPLOAD_DESTINATION);
        String name = "name of file in Repository " + System.currentTimeMillis();

        Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
        props.put(ContentModel.PROP_NAME, name);

        // use the node service to create a new node
        NodeRef node = serviceRegistry.getNodeService().createNode(
                        parent,
                        ContentModel.ASSOC_CONTAINS,
                        QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name),
                        ContentModel.TYPE_CONTENT, props).getChildRef();

        // Use the content service to set the content onto the newly created
        // node
        ContentWriter writer = serviceRegistry.getContentService().getWriter(node, ContentModel.PROP_CONTENT, true);
        writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
        writer.setEncoding("UTF-8");
        String text = "";
        try {
            text = FileUtils.readFileToString(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        writer.putContent(text);

        Map<String, Object> model = new HashMap<String, Object>();
        if (status.getCode() == Status.STATUS_OK) {
            model.put("resultRepoWS", "File \"" + file.getName() + "\" uploaded successfully to the repository. Status: " + status.getCode());
            return model;
        } else {
            model.put("resultRepoWS", "There was an error while uploading document \"" + file.getName() + "\" - Status: " + status.getCode());
            return model;
        }
    }

    //If you want to test with CompanyHome first use this method instead of the NodeRef
    @SuppressWarnings("unused")
    private NodeRef getCompanyHome() {
        StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore");
        serviceRegistry.getSearchService();
        ResultSet rs = serviceRegistry.getSearchService().query(storeRef, SearchService.LANGUAGE_XPATH, "/app:company_home");
        NodeRef parent = null;
        try {
            if (rs.length() == 0) {
                throw new AlfrescoRuntimeException("Didn't find Company Home");
            }
            parent = rs.getNodeRef(0);
        } finally {
            rs.close();
        }
        return parent;
    }
}

此 java class 放置在以下文件夹中:

{tomcat}\webapps\alfresco\WEB-INF\classes\org\example

其中 org\example 与包 org.example 相同。现在我们有了 class,现在我们需要配置文件,我这样称呼它们:

  • customfileupload-context.xml

位于此处

  • {tomcat}\shared\classes\alfresco\extension

您还需要这些:

  • customfileupload.post.desc.xml
  • customfileupload.post.json.ftl

位于此处

  • {tomcat}\shared\classes\alfresco\extension\webscripts\org\example

注意到文件夹了吗?和前面说的包一样。

customfileupload 的内容-context.xml:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN 2.0//EN'
  'http://www.springframework.org/dtd/spring-beans-2.0.dtd'>
<beans>
    <bean id="webscript.org.example.customfileupload.post" class="org.example.CustomFileUpload" parent="webscript">
        <property name="ServiceRegistry" ref="ServiceRegistry" />
    </bean>
</beans>

customfileupload.post.desc.xml 的内容:

<webscript>
   <shortname>File Upload</shortname>
   <description>Upload files to user home</description>
   <url>/upload/fileupload.json</url>
   <format default="json"/>
   <authentication runas="admin">guest</authentication>
   <transaction>required</transaction>
</webscript>

customfileupload.post.json.ftl 的内容:

<#escape x as jsonUtils.encodeJSONString(x)>  {  "resultRepoWS": "${resultRepoWS}"  }  </#escape>

就是这样。有了这个,您将能够使用 Alfresco 5 将文件上传到 Alfresco 的存储库。