【问题标题】:How to add a document to the Alfresco Repository with Java code?如何使用 Java 代码将文档添加到 Alfresco 存储库?
【发布时间】:2015-05-18 13:45:57
【问题描述】:

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

原始问题:

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

方式#1:
类中的注入:

@Autowired
NodeService nodeService

方式#2:
在 service-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>

在课程中,我为所有服务和 serviceRegistry 添加了一个 getter 和 setter:

private NodeService nodeService;

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

方式#3:

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$1.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$2.run(URLClassLoader.java:551)
    at java.net.URLClassLoader$2.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 方面工作(不是 Share)。

【问题讨论】:

  • 为什么不使用 Java 支持的 webscript 来执行您需要的操作?
  • 因为我在 Repository 方面工作,而不是 Share。
  • WebScripts 可以部署到 Repo 或 Share,实际上 Alfresco 应用程序的大部分依赖于 repo 端 java 支持的 webscripts!
  • 那么请告诉我为什么我应该使用 webscripts 而我什至不接触 HTML...
  • 你能告诉我们你把service-context.xml放在哪个位置吗?

标签: java alfresco


【解决方案1】:
@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 类应包含以下用于注入 nodeService。

private NodeService nodeService;

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

【讨论】:

  • 这正是我在提出问题时所拥有的。我也会在我的问题中明确包含它,因为我确实提到了它。无论如何它仍然不起作用。
  • 你在使用 webscript 、policy 还是其他东西。你能把你的 javacode 也放上去吗?
  • 注释被提及为方式#1。 bean 和 setter 被称为方式 #2。在我使用 bean 和 setter 方式之前,注释已被删除。
  • 不,没有 webscript(这是存储库,不是共享)。
  • 您是否为要注入的所有其他服务添加了 setter?如果您明确注入所需的服务,则不需要注入“serviceRegistry”。
【解决方案2】:

幸运的是,我有通过 JAVA 支持的 webscript 上传文件的代码。希望这对您也有帮助。要创建 java 支持的 webscript,请参阅this

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

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 在露天注册这个网络脚本。并放

<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,您将看到文件上传到文件夹中(无论您提供什么)。对于Reference

【讨论】:

  • 在 ExecuteImpl 中您提到 URL 是“/upload?alf_ticket=”,但在 desc.xml 中您提到“/upload/fileupload?alf_ticket=”。这些不应该是一样的吗?
  • 哦...抱歉我的错误应该是/upload/fileupload in executeImpl.java :) 我已经相应地修改了代码。
  • bean id 重要吗?或者我可以添加任何我喜欢的东西吗?还是应该是 webscript.&lt;package&gt;.&lt;class&gt;.&lt;HTTP method&gt; 之类的?
  • 是的,重要的是它必须像webscript.&lt;package&gt;.&lt;class&gt;.&lt;HTTP method&gt;。为简单起见webscript.&lt;package&gt;.&lt;filename of desc&gt;.&lt;HTTP method&gt;
  • 您能添加一个 JSON 示例吗?
【解决方案3】:

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

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类放在以下文件夹中:

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

其中 org\example 与包 org.example 相同。现在我们有了一个类,现在我们需要我所说的配置文件:

  • 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 的存储库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 2012-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多