복붙노트

[SPRING] Mule Zip 파일을 압축하여 FTP 서버로 압축 파일 보내기

SPRING

Mule Zip 파일을 압축하여 FTP 서버로 압축 파일 보내기

나는 Mule이 엘리먼트를 사용하는 gzip 압축 데이터를 아주 잘 지원한다는 것을 알고있다. 그러나 클라이언트는 zip 압축 파일을 FTP에 저장해야하므로 zip 압축을 원합니다.

다음과 같은 상황에서 나는 노새에 어려움을 겪는다.

나는 파일이 들어오는 Spring 빈을 만들었다. 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. ==============================

    1.나는 이것을 위해 변압기를 구현했다.

    나는 이것을 위해 변압기를 구현했다.

        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로 설정합니다. 속성이나 변수를 사용하여 변경할 수 있습니다.

    희망이 도움이됩니다.

  2. ==============================

    2.더 간단한 방법은 파일을 압축하기 위해 mule의 gzip 변환기를 사용하는 것입니다. 당신이 XML을 통해 그것을해야한다는 것에주의해라.

    더 간단한 방법은 파일을 압축하기 위해 mule의 gzip 변환기를 사용하는 것입니다. 당신이 XML을 통해 그것을해야한다는 것에주의해라.

    <gzip-compress-transformer/>
    
  3. ==============================

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

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

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

    이것을 대신 사용하십시오 :

    registerSourceType(DataTypeFactory.create(InputStream.class));
    registerSourceType(DataTypeFactory.create(byte[].class));
    
  4. from https://stackoverflow.com/questions/37731108/mule-zip-file-and-send-zipped-file-towards-ftp-server by cc-by-sa and MIT license