2016-06-09 79 views
1

我知道Mule對使用元素的gzip壓縮數據有很大的支持。然而,客戶現在想zip壓縮,因爲該文件已被放置在一個FTP作爲一個zip壓縮文件:(Mule Zip文件並向FTP服務器發送壓縮文件

我遇到騾子困難以下情形:

我創建了一個Spring bean,其中一個文件來在我想用ZipOutputStream類壓縮這個文件,並通過它向我們的FTP

這是我的流程配置:

<flow name="testFlow" initialState="stopped"> 
    <file:inbound-endpoint path="${home.dir}/out" moveToDirectory="${hip.dir}/out/hist" fileAge="10000" responseTimeout="10000" connector-ref="input"/> 
    <component> 
     <spring-object bean="zipCompressor"/> 
    </component> 
    <set-variable value="#[message.inboundProperties.originalFilename]" variableName="originalFilename" /> 
    <ftp:outbound-endpoint host="${ftp.host}" port="${ftp.port}" user="${ftp.username}" password="${ftp.password}" path="${ftp.root.out}" outputPattern="#[flowVars['originalFilename']].zip" /> 
</flow> 

這是我zipCompressor的代碼:

@Component 
public class ZipCompressor implements Callable { 

    private static final Logger LOG = LogManager.getLogger(ZipCompressor.class.getName()); 

    @Override 
    @Transactional 
    public Object onCall(MuleEventContext eventContext) throws Exception { 

     if (eventContext.getMessage().getPayload() instanceof File) { 
      final File srcFile = (File) eventContext.getMessage().getPayload(); 
      final String fileName = srcFile.getName(); 
      final File zipFile = new File(fileName + ".zip"); 

      try { 

       // create byte buffer 
       byte[] buffer = new byte[1024]; 
       FileOutputStream fos = new FileOutputStream(zipFile); 
       ZipOutputStream zos = new ZipOutputStream(fos); 
       FileInputStream fis = new FileInputStream(srcFile); 
       // begin writing a new ZIP entry, positions the stream to the start of the entry data 
       zos.putNextEntry(new ZipEntry(srcFile.getName())); 
       int length; 
       while ((length = fis.read(buffer)) > 0) { 
        zos.write(buffer, 0, length); 
       } 
       zos.closeEntry(); 
       // close the InputStream 
       fis.close(); 
       // close the ZipOutputStream 
       zos.close(); 
      } 
      catch (IOException ioe) { 
       LOG.error("Error creating zip file" + ioe); 
      } 
      eventContext.getMessage().setPayload(zipFile); 
     } 
     return eventContext.getMessage(); 
    } 
} 

我寫了一個單元測試,壓縮效果很好。使用正確的名稱確實將文件傳輸到FTP,但zip文件無效,並且通過在NotePad ++中打開它,它只包含原始文件名。

我想我做錯了將zip文件傳遞迴騾流,但我現在卡住了,所以任何幫助將不勝感激!

+1

我跑你的流量和zipCompressor的副本。我也收到一個文件,但文件從不壓縮。它處於原始狀態。 – tbriscoe

回答

2

我已經實現了變壓器這個

package com.test.transformer; 

import java.io.IOException; 
import java.io.InputStream; 
import java.util.zip.ZipEntry; 
import java.util.zip.ZipOutputStream; 

import org.apache.commons.io.IOUtils; 
import org.apache.commons.io.output.ByteArrayOutputStream; 
import org.mule.api.MuleMessage; 
import org.mule.api.transformer.TransformerException; 
import org.mule.transformer.AbstractMessageTransformer; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

public class ZipTransformer 
    extends AbstractMessageTransformer 
{ 
    private static final Logger log = LoggerFactory.getLogger(ZipTransformer.class); 
    public static final int DEFAULT_BUFFER_SIZE = 32768; 
    public static byte[] MAGIC = { 'P', 'K', 0x3, 0x4 }; 

    public ZipTransformer() 
    { 
    registerSourceType(InputStream.class); 
    registerSourceType(byte[].class); 
    } 

    public Object transformMessage(MuleMessage message, String outputEncoding) 
    throws TransformerException 
    { 
    Object payload = message.getPayload(); 
    try{ 
     byte[] data; 
     if (payload instanceof byte[]) 
     { 
      data = (byte[]) payload; 
     } 
     else if (payload instanceof InputStream) { 
      data = IOUtils.toByteArray((InputStream)payload); 
     } 
     else if (payload instanceof String) 
     { 
      data = ((String) payload).getBytes(outputEncoding); 
     } 
     else 
     { 
      data = muleContext.getObjectSerializer().serialize(payload); 
     } 
     return compressByteArray(data); 
    }catch (Exception ioex) 
    { 
     throw new TransformerException(this, ioex); 
    } 
    } 

    public Object compressByteArray(byte[] bytes) throws IOException 
    { 
     if (bytes == null || isCompressed(bytes)) 
     { 
      if (logger.isDebugEnabled()) 
      { 
       logger.debug("Data already compressed; doing nothing"); 
      } 
      return bytes; 
     } 

     if (logger.isDebugEnabled()) 
     { 
      logger.debug("Compressing message of size: " + bytes.length); 
     } 

     ByteArrayOutputStream baos = null; 
     ZipOutputStream zos = null; 

     try 
     { 
      baos = new ByteArrayOutputStream(DEFAULT_BUFFER_SIZE); 
      zos = new ZipOutputStream(baos); 
      zos.putNextEntry(new ZipEntry("test.txt")); 
      zos.write(bytes, 0, bytes.length); 
      zos.finish(); 
      zos.close(); 

      byte[] compressedByteArray = baos.toByteArray(); 

      baos.close(); 
      if (logger.isDebugEnabled()) 
      { 
       logger.debug("Compressed message to size: " + compressedByteArray.length); 
      } 

      return compressedByteArray; 
     } 
     catch (IOException ioex) 
     { 
      throw ioex; 
     } 
     finally 
     { 
      IOUtils.closeQuietly(zos); 
      IOUtils.closeQuietly(baos); 
     } 
    } 

    public boolean isCompressed(byte[] bytes) throws IOException 
    { 
     if ((bytes == null) || (bytes.length < 4)) 
     { 
      return false; 
     } 
     else 
     { 
      for (int i = 0; i < MAGIC.length; i++) { 
       if (bytes[i] != MAGIC[i]) { 
       return false; 
       } 
      } 
      return true; 
     } 
    } 


} 

用它作爲

<custom-transformer class="com.test.transformer.ZipTransformer" doc:name="file zip transformer"/> 

截至目前設置文件名的test.txt。你可以改變使用任何屬性或變量。

希望這會有所幫助。

+0

正是我需要的。我會嘗試將其轉換爲使用@Transform註釋。謝謝! –

1

更簡單的方法是使用mule中的gzip轉換器壓縮文件。請注意,你必須通過xml來完成。

<gzip-compress-transformer/> 
+0

我知道,我起初使用gzip壓縮,但要求是zip壓縮,如我的文章的第一行所述。 –

0

在ZipTransformer構造函數中,不推薦使用以下內容。

registerSourceType(InputStream.class); 
registerSourceType(byte[].class); 

使用這個代替:

registerSourceType(DataTypeFactory.create(InputStream.class)); 
registerSourceType(DataTypeFactory.create(byte[].class)); 
相關問題