java - 某些 Zip 文件无法通过 java 代码在露天正确提取

标签 java alfresco alfresco-share alfresco-webscripts

我编写了java代码来在露天提取zip文件。 但通过该代码,一些 zip 文件无法正确提取。

我还有一个观察结果,如果我手动解压缩该文件并再次手动创建 zip 文件,那么它工作正常并且成功地在露天站点中提取。

所以我不明白到底是什么问题。

是文件有问题还是我的代码有问题还是 zip 文件有问题

谁能帮我解决这个问题...

请参阅下面的日志以供引用...

2017-01-25 12:10:12,069  ERROR [tandf.ingestion.TransformExceptionService] [org.springframework.jms.listener.DefaultMessageListenerContainer#22-1] Unhandled Exception occured in ingestion pipeline:  org.alfresco.error.AlfrescoRuntimeException: 00250134 Exception in Transaction.
    at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:542)
    at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:326)
    at com.ixxus.tandf.service.XmlZipExtractService.lambda$extract$4(XmlZipExtractService.java:235)
    at org.alfresco.repo.security.authentication.AuthenticationUtil.runAs(AuthenticationUtil.java:548)
    at 

我正在使用下面的代码来提取 zip 文件..

 private void unzipToNode(final String zipFilePath, final NodeRef destinationFolder, final String isbn, final String zipFileNoderef, final String assetType, final NodeRef ingestedNodeRef) throws IOException {

    LOG.debug("Inside : Start :-> unzipToNode, zipFileNoderef : {}", zipFileNoderef);

    String rootDisplayPath = nodeUtils.getDisplayPath(destinationFolder);
    List<NodeRef> folderNodes = new ArrayList<>();

    try (ZipFile zipFile = new ZipFile(zipFilePath); FileInputStream fis = new FileInputStream(zipFilePath); ZipInputStream zipInput = new ZipInputStream(fis);) {

        ZipEntry entry = zipInput.getNextEntry();
        int zipFileSize = zipFile.size();
        LOG.info("{} : zipFileSize from zip api for zipFileNoderef : {}", zipFileSize, zipFileNoderef);
        int zipManualFileCount = 0;

        while (entry != null) {

            zipManualFileCount++;

            LOG.debug("Processing the zip entry : {}, zipFileNoderef : {}", entry.getName(), zipFileNoderef);
            InputStream inputStream = zipFile.getInputStream(entry);

            /** create or get final folder path for current entry */
            NodeRef nodeRef = createOrGetFolderStructure(destinationFolder, entry);
            folderNodes.add(nodeRef);

            String name;

            if (!entry.isDirectory()) {

                name = getFileNameFromEntry(entry);

                /** if zip entry is file, then create and write the new node in validation site */
                createNodeOnValidationSite(nodeRef, name, inputStream, assetType, ingestedNodeRef, rootDisplayPath);
            }

            /** close current entry and fetch next one */
            zipInput.closeEntry();
            entry = zipInput.getNextEntry();
        }

        LOG.info("{} : zipManualFileCount from zip api for zipFileNoderef : {}", zipManualFileCount, zipFileNoderef);

        /** Close the last entry */
        zipInput.closeEntry();
    }

    for(NodeRef folderNode : folderNodes){
        if(nodeUtils.isNodeEmpty(folderNode)){
            LOG.debug("Found empty folder [{}] within .zip [{}]", folderNode, ingestedNodeRef);
            /** if the folder is empty we need to copy all properties to it as well to archive it */
            copyAllProperties(ingestedNodeRef, folderNode, rootDisplayPath, assetType);
        }
    }

    LOG.debug("Inside : End :-> unzipToNode : zipFileNoderef : {}", zipFileNoderef);
}

最佳答案

要提取 zip 文件,请尝试使用此代码。

package org.alfresco.repo.action.executer;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipException;

import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ParameterDefinitionImpl;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.InvalidAspectException;
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
import org.alfresco.service.cmr.model.FileExistsException;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.InvalidQNameException;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.TempFileProvider;
import org.alfresco.web.bean.repository.Repository;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;

/**
 * Zip action executor
 * 
 * @author Davide Taibi
 */
public class ZipActionExecuter extends ActionExecuterAbstractBase
{
   public static final String NAME = "importzip";
   public static final String PARAM_ENCODING = "encoding";
   public static final String PARAM_DESTINATION_FOLDER = "destination";

   private static final String TEMP_FILE_PREFIX = "alf";
   private static final String TEMP_FILE_SUFFIX = ".zip";

   /**
    * The node service
    */
   private NodeService nodeService;

   /**
    * The content service
    */
   private ContentService contentService;

   private MimetypeService mimetypeService;
   private FileFolderService fileFolderService;

   /**
    * Sets the NodeService to use
    * 
    * @param nodeService The NodeService
    */
   public void setNodeService(NodeService nodeService)
   {
      this.nodeService = nodeService;
   }

   /**
    * Sets the ContentService to use
    * 
    * @param contentService The ContentService
    */
   public void setContentService(ContentService contentService)
   {
      this.contentService = contentService;
   }

   public void setFileFolderService(FileFolderService fileFolderService) {
      this.fileFolderService = fileFolderService;
   }

   public void setMimetypeService(MimetypeService mimetypeService) {
      this.mimetypeService = mimetypeService;
   }

   private void extractFile(ZipFile archive,String mExtractToDir){
      String fileName;
      String destFileName;
      byte[] buffer = new byte[16384];
      mExtractToDir=mExtractToDir+File.separator;
      try {
         for ( Enumeration e = archive.getEntries(); e.hasMoreElements(); )
         {
            ZipEntry entry = (ZipEntry)e.nextElement();
            if ( ! entry.isDirectory() )
            {
               fileName = entry.getName();
               fileName = fileName.replace('/', File.separatorChar);
               destFileName = mExtractToDir + fileName;
               File destFile = new File(destFileName);
               String parent = destFile.getParent();
               if ( parent != null )
               {
                  File parentFile = new File(parent);
                  if ( ! parentFile.exists() )
                     parentFile.mkdirs();
               }
               InputStream in = archive.getInputStream(entry);
               OutputStream out = new FileOutputStream(destFileName);
               int count;
               while ( (count = in.read(buffer)) != -1 )
                  out.write(buffer, 0, count );
               in.close();
               out.close();
            }else{
               File newdir = new File( mExtractToDir + entry.getName() );
               newdir.mkdir();
            }
         }
      } catch (ZipException e) {
         e.printStackTrace();
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }    

   private void deleteDir(File dir){
         File elenco=new File(dir.getPath());
         for (File file:elenco.listFiles()){
            if (file.isFile())
               file.delete();
            else
               deleteDir(file);
         }
         dir.delete();
   }

   public void executeImpl(Action ruleAction, NodeRef actionedUponNodeRef) {
      String spaceType;
      NodeRef parentNodeRef;
      FileInfo fileInfo;
      NodeRef nodeRef;

      if (this.nodeService.exists(actionedUponNodeRef) == true) {
         ContentReader reader = this.contentService.getReader(
               actionedUponNodeRef, ContentModel.PROP_CONTENT);
         if (reader != null) {
            if (MimetypeMap.MIMETYPE_ZIP.equals(reader.getMimetype())) {
               File zFile = null;
               ZipFile zipFile = null;
               try {
                  spaceType = ContentModel.TYPE_FOLDER.toString();
                  String dirName = ""+this.nodeService.getProperty(actionedUponNodeRef, ContentModel.PROP_NAME);
                  dirName=dirName.substring(0,dirName.indexOf(".zip"));
                  parentNodeRef = (NodeRef)ruleAction.getParameterValue(PARAM_DESTINATION_FOLDER);// this.nodeService.getRootNode(Repository.getStoreRef());
                  fileInfo = fileFolderService.create(
                        parentNodeRef,
                        dirName,
                        Repository.resolveToQName(spaceType));
                  nodeRef = fileInfo.getNodeRef();

                  zFile = TempFileProvider.createTempFile(
                        TEMP_FILE_PREFIX, TEMP_FILE_SUFFIX);
                  reader.getContent(zFile);
                  zipFile = new ZipFile(zFile, "Cp437");
                  File tempDir=new File(TempFileProvider.getTempDir().getPath()+File.separator+dirName);
                  if (tempDir.exists()) deleteDir(tempDir);
                  extractFile(zipFile,tempDir.getPath());
                  importFile(tempDir.getPath(),nodeRef);
                  deleteDir(tempDir);
               } catch (ContentIOException e) {
                  e.printStackTrace();
               } catch (InvalidNodeRefException e) {
                  e.printStackTrace();
               } catch (FileExistsException e) {
                  e.printStackTrace();
               } catch (IOException e) {
                  e.printStackTrace();
               }
            }
         }
      }
   }

   private void importFile(String dir,NodeRef root){
      File elenco=new File(dir);
      for (File file:elenco.listFiles()){
         try {
            if (file.isFile()){
               InputStream contentStream = new FileInputStream(file);
               // assign name
               String fileName=file.getName();
               Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
               contentProps.put(ContentModel.PROP_NAME, fileName);
               // create content node
               ChildAssociationRef association = nodeService
               .createNode(
                     root,
                     ContentModel.ASSOC_CONTAINS,
                     QName.createQName(
                           NamespaceService.CONTENT_MODEL_PREFIX,
                           fileName),
                           ContentModel.TYPE_CONTENT,
                           contentProps);
               NodeRef content = association.getChildRef();
               // add titled aspect (for Web Client display)
               Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>();
               titledProps.put(ContentModel.PROP_TITLE, fileName);
               titledProps.put(ContentModel.PROP_DESCRIPTION,fileName);
               nodeService.addAspect(content,
                     ContentModel.ASPECT_TITLED,
                     titledProps);
               ContentWriter writer = contentService.getWriter(content,
                     ContentModel.PROP_CONTENT, true);
               writer.setMimetype(mimetypeService.guessMimetype(file.getAbsolutePath()));
               writer.setEncoding("Cp437");
               writer.putContent(contentStream);          
            }else{
               String spaceType = ContentModel.TYPE_FOLDER.toString();
               FileInfo fileInfo = fileFolderService.create(
                     root,
                     file.getName(),
                     Repository.resolveToQName(spaceType));

               importFile(file.getPath(),fileInfo.getNodeRef());
            }
         } catch (InvalidTypeException e) {
            e.printStackTrace();
         } catch (InvalidAspectException e) {
            e.printStackTrace();
         } catch (InvalidQNameException e) {
            e.printStackTrace();
         } catch (ContentIOException e) {
            e.printStackTrace();
         } catch (FileNotFoundException e) {
            e.printStackTrace();
         } catch (InvalidNodeRefException e) {
            e.printStackTrace();
         } catch (FileExistsException e) {
            e.printStackTrace();
         }
      }
   }

   protected void addParameterDefinitions(List<ParameterDefinition> paramList) 
   {
      paramList.add(new ParameterDefinitionImpl(PARAM_DESTINATION_FOLDER, DataTypeDefinition.NODE_REF, 
            true, getParamDisplayLabel(PARAM_DESTINATION_FOLDER)));
      paramList.add(new ParameterDefinitionImpl(PARAM_ENCODING, DataTypeDefinition.TEXT, 
            true, getParamDisplayLabel(PARAM_ENCODING)));
   }
}

此外文件 importzip-action-messages.properties :

importzip.title=Import Zip File
importzip.description=This Action import zip file into alfresco
importzip.aspect-name.display-label=The name of the aspect to apply to the node.

并将以下行添加到…-context.xml,(您可以使用action-services-context.xml)

<bean id="importzip" class="org.alfresco.repo.action.executer.ZipActionExecuter" parent="action-executer">
        <property name="nodeService">
            <ref bean="NodeService"></ref>
        </property>
        <property name="contentService">
            <ref bean="ContentService" />
        </property>
        <property name="mimetypeService">
            <ref bean="MimetypeService"></ref>
        </property>
                <property name="fileFolderService">
            <ref bean="FileFolderService"></ref>
        </property>
  </bean>
   <bean id="importzip-messages" class="org.alfresco.i18n.ResourceBundleBootstrapComponent">
       <property name="resourceBundles">
          <list>
             <value>org.alfresco.repo.action.importzip-action-messages</value>
          </list>
       </property>
      </bean>

最后将此行添加到我的 web-client-config-custom.xml

<config evaluator="string-compare" condition="Action Wizards">
      <action-handlers>
         <handler name="importzip" class="org.alfresco.web.bean.actions.handlers.ImportHandler" />
      </action-handlers>         
</config>

关于java - 某些 Zip 文件无法通过 java 代码在露天正确提取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41887945/

相关文章:

java - Alfresco 工作流程起始表单选项不可用

java - 从jsp获取List对象值到action类

java - Alfresco 如何安装附加 jar 文件?例如。我必须在 :fme-datalist-extension-share. jar 上安装 add

javascript - Alfresco 范围的 webscript 配置,它可以加载到 E4X 对象中吗?

java - 如何在 Windows 的露天共享中部署自定义主题?

alfresco - 如何从露天存储库下载多个文件

java - 哈希表插入

java - 我第一次使用 launch4j 并收到以下错误

java - 如何检查 PDF 阅读器是否安装了 Java

javascript - Alfresco:数据字典中尚未定义类