2016-06-09 1 views
1

Mule은 요소를 사용하여 gzip 압축을 지원합니다. 클라이언트가 현재 ZIP 압축을 원하지만 파일은 압축 압축 파일 :(Mule Zip 파일을 FTP 서버쪽으로 압축 파일을 보냅니다.

나는 다음과 같은 시나리오를 노새에 어려움이 같은 FTP에 배치해야하기 때문에 : 파일이 오는 곳 나는 스프링 빈을 생성

.에 나는 ZipOutputStream이 클래스를 사용하여이 파일을 압축하고 우리의 ftp를 향해을 전달하려는

이 내 흐름의 구성이다. 이것은 내 zipCompressor의 코드가

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

입니다 :

@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 파일을 노새 흐름으로 되돌려 보내는데 문제가 있다고 생각하지만, 지금 당장 붙어서 어떤 도움을 주시면 감사하겠습니다! 지금있는 test.txt로 파일 이름을 설정하는 기준으로

+1

나는 당신의 흐름과 zipCompressor의 사본을 달렸다. 나는 파일을 또한 얻고있다, 그러나 파일은 결코 압축되지 않는다. 그것은 원래 상태입니다. – tbriscoe

답변

2

나는

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

로 사용이

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


} 

의 변압기를 구현했습니다. 속성이나 변수를 사용하여 변경할 수 있습니다.

희망이 도움이됩니다.

+0

정확히 내가 필요한 것. @Transform 어노테이션을 사용하도록 변환하려고 시도 할 것이다. 감사! –

1

더 간단한 방법은 mule의 gzip 변환기를 사용하여 파일을 압축하는 것입니다. XML을 통해해야한다는 것에주의하십시오.

<gzip-compress-transformer/> 
+0

처음에는 gzip 압축이 있었지만 요구 사항은 내 게시물의 첫 줄에 명시된 압축 압축입니다. –

0

ZipTransformer 생성자에서 다음은 사용되지 않습니다.

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

사용이 대신은 :

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