-->

How to add a document to the Alfresco Repository w

2019-04-15 22:33发布

问题:

EDIT: Apparently I had to make an AMP and map it to Alfresco.war. But now I can't access the code I wrote, so I guess I'll have to use Webscripts and the like. Can someone provide an example of how to add a document to the Alfresco Repository with a Java backed webscript?

ORIGINAL QUESTION:

I've searched google-wide for a way to add a document to the Alfresco Repository with Java code. But I was not able to find a way that would work. I know how I can add a document to the Repository: use the NodeService. But the problem is that I cannot get an instance of the NodeService. I've tried to inject it with @Autowired, I've tried using a bean and I've tried using an ApplicationContext. None of the ways worked...

Way #1:
Injection in a class:

@Autowired
NodeService nodeService

Way #2:
In 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>

In the class I added a getter and setter for all the services and the serviceRegistry:

private NodeService nodeService;

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

Way #3:

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

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

nodeService = serviceRegistry.getNodeService();

Ways #1 and #2 gave me a NullPointerException simply stating the NodeService is null. Way #3 gave a mile long StackTrace because of an AlfrescoRuntimeException because it failed to initialize a keystore:

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

Yes, the keystore exists and yes I have regenerated a new keystore.

I'm using Alfresco 5.0.1 and I'm working on the Repository side (not Share).

回答1:

@Autowired
NodeService nodeService

Will not work in alfresco

You need to inject it with proper setter method. Your bean should be like below.

<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>

Your java class should contain following for injecting nodeService.

private NodeService nodeService;

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


回答2:

Luckily I have code for file upload thorugh JAVA backed webscript. Hope this help you too.To create java backed webscript see this

Create one class named CustomFileUpload.java and put following content

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

NOTE: In destination you can put nodeRef of folder in which you want to upload.

Than create bean in context file name it whatever you want say mycustom-context.xml and put it in ALFRESCO_HOME\tomcat\shared\classes\alfresco\extension and content

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

Finally register this web script in alfresco by creating customupload.post.desc.xml. and put

<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>

And last create view as we have declared JSON is default format so we need to create customupload.post.json.ftl

${result}

And put these both files in ALFRESCO_HOME\tomcat\shared\classes\alfresco\extension\templates\webscripts\com\upload

Now restart server and hit http://localhost:8080/alfresco/service/upload/fileupload and you will see file uploaded in folder(Whatever you have given). For Reference



回答3:

Finally! This is the solution for adding a file to the Repository:

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

This java class is placed in the following folder:

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

Where org\example is the same as the package org.example. Now we have a class, now we need the configuration files as I call them:

  • customfileupload-context.xml

Which is located here

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

You will also need these:

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

Which are located here

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

Noticed the folder? It's the same like the package mentioned earlier.

Contents of 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>

Contents of 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>

Contents of customfileupload.post.json.ftl:

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

This is it. With this you'll be able to upload a file to the Repository of Alfresco with Alfresco 5.



标签: java alfresco