SpringBoot讀寫(xiě)xml上傳到AWS存儲(chǔ)服務(wù)S3的示例
最近的工作涉及到了生成xml文件并上傳到AWS存儲(chǔ)服務(wù)S3這樣的處理。期間遇到了兩個(gè)問(wèn)題,簡(jiǎn)單記錄下:
- springboot讀取xml模板異常
- 將生成的xml上傳到S3的問(wèn)題
springboot的版本是0,讀寫(xiě)xml文件使用的是Dom4J,版本是1。逐個(gè)說(shuō)明下遇到的這幾個(gè)問(wèn)題。
1.springboot讀取xml模板異常
現(xiàn)階段是將xml模板文件存儲(chǔ)在springboot項(xiàng)目的resource目錄下的。具體路徑為
template/xxx.xml
最初是通過(guò)類加載器獲取文件路徑后再嘗試讀取模板文件的:
String fullPath = TemplateParser.class.getClassLoader().getResource(pathXml).getFile(); File file = new File(fullPath); SAXReader reader = new SAXReader(); Document document = reader.read(file);
通過(guò)類加器獲取到的文件路徑是:
file:/path/of/jar/springboot-xml.jar!/BOOT-INF/classes!/template/xxx.xml
不過(guò)我們都知道,springboot是將整個(gè)工程包括配置文件打成一個(gè)jar包后再直接運(yùn)行。這樣想在linux的服務(wù)器上通過(guò)文件路徑找文件是注定找不到的。
后來(lái)改成直接通過(guò)SpringBoot提供的 ClassResource
類來(lái)獲取resource路徑下的配置文件:
ClassPathResource resource = new ClassPathResource(pathXml); Document doc = reader.read(resource.getInputStream());
這里直接使用 InputStream
讀取的模板文件。注意不要再嘗試通過(guò)調(diào)用 ClassResource實(shí)例的 getFile()方法來(lái)獲取文件,不然會(huì)遇到和之前同樣的問(wèn)題。
額,期間還發(fā)生了無(wú)法將模板文件打進(jìn)springboot項(xiàng)目運(yùn)行時(shí)的jar文件這樣的問(wèn)題。因?yàn)槭菍⒛0逦募鎯?chǔ)在了resources的子目錄下,需要調(diào)整下maven打包的配置:
<resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <includes> <include>**/*</include> </includes> </resource> </resources>
下面這幾行如果沒(méi)有的話需要加上,不然會(huì)讀取不到子目錄中的配置文件:
<includes> <include>**/*</include> </includes>
2.將生成的xml上傳到S3
AWS提供的最便捷的上傳文件接口是這個(gè):
public PutObjectResult putObject(String bucketName, String key, File file) throws SdkClientException, AmazonServiceException;
這個(gè)接口通過(guò) File實(shí)例來(lái)執(zhí)行上傳。所以我一開(kāi)始的想法是先生成一個(gè)臨時(shí)文件保存在服務(wù)器本地,讀取本地臨時(shí)文件為 File執(zhí)行上傳,最后再刪掉本地的臨時(shí)文件。這個(gè)思路是沒(méi)問(wèn)題的,在本地執(zhí)行也OK。但是在生產(chǎn)環(huán)境,由于權(quán)限相關(guān)的問(wèn)題,生成臨時(shí)文件失敗了。
不想再去折騰權(quán)限相關(guān)的事情,所以將出路寄托在了AWS提供的另一個(gè)接口上:
public PutObjectResult putObject( String bucketName, String key, InputStream input, ObjectMetadata metadata) throws SdkClientException, AmazonServiceException;
也就是說(shuō)考慮將xml文件內(nèi)容輸出到 InputStream
,然后再將InputStream上傳到S3。一切都在內(nèi)存里執(zhí)行,不依賴外部文件系統(tǒng)也就不會(huì)有文件權(quán)限的問(wèn)題。
這個(gè)方案的問(wèn)題在于 ObjectMetaData
這個(gè)類有點(diǎn)兒黑箱的意思。該怎么設(shè)置需要進(jìn)行一些摸索??戳艘槐檫@個(gè)類的接口文檔,需要調(diào)用的也就這兩個(gè)set方法:
/** * Set the date when the object is no longer cacheable. */ public void setHttpExpiresDate(Date httpExpiresDate) { this.httpExpiresDate = httpExpiresDate; } /** * <p> * Sets the Content-Length HTTP header indicating the size of the * associated object in bytes. * </p> * <p> * This field is required when uploading objects to S3, but the AWS S3 Java * client will automatically set it when working directly with files. When * uploading directly from a stream, set this field if * possible. Otherwise the client must buffer the entire stream in * order to calculate the content length before sending the data to * Amazon S3. * </p> */ public void setContentLength(long contentLength) { metadata.put(Headers.CONTENT_LENGTH, contentLength); }
其中后者(文件長(zhǎng)度)是AWS建議設(shè)置的,不設(shè)置會(huì)在處理的時(shí)候給出WARN。根據(jù)方法文檔也可以看到,如果不設(shè)置,在上傳的時(shí)候就會(huì)在內(nèi)存中緩存整個(gè)信息流來(lái)計(jì)算文件長(zhǎng)度。
至于前者是上傳到S3文件的緩存過(guò)期時(shí)間,酌情設(shè)置即可。
另一個(gè)需要解決的問(wèn)題就是怎么將Dom4j生成的 Document
輸出再讀取到 InputStream
中。這里用到了 XmlWritter
類,具體實(shí)現(xiàn)如下:
XMLWriter xmlWriter = new XMLWriter(outputStream, OutputFormat.createCompactFormat()); xmlWriter.write(doc); xmlWriter.close(); return new ByteArrayInputStream(outputStream.toByteArray());
驗(yàn)證了一下,這個(gè)方法是可行的。修改后生產(chǎn)環(huán)境沒(méi)有再報(bào)錯(cuò)。
向AWS S3存儲(chǔ)服務(wù)上傳文件的實(shí)現(xiàn)代碼在這篇文章里:Java實(shí)現(xiàn)上傳文件到AWS S3
End!
以上就是SpringBoot讀寫(xiě)xml上傳到S3的示例的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot讀寫(xiě)xml的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
分布式服務(wù)Dubbo+Zookeeper安全認(rèn)證實(shí)例
下面小編就為大家分享一篇分布式服務(wù)Dubbo+Zookeeper安全認(rèn)證實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12SPRINGMVC JSON數(shù)據(jù)交互如何實(shí)現(xiàn)
這篇文章主要介紹了SPRINGMVC JSON數(shù)據(jù)交互如何實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06Spring解決循環(huán)依賴問(wèn)題及三級(jí)緩存的作用
這篇文章主要介紹了Spring解決循環(huán)依賴問(wèn)題及三級(jí)緩存的作用,所謂的三級(jí)緩存只是三個(gè)可以當(dāng)作是全局變量的Map,Spring的源碼中大量使用了這種先將數(shù)據(jù)放入容器中等使用結(jié)束再銷毀的代碼風(fēng)格2022-07-07jasypt對(duì)配置文件的數(shù)據(jù)加密與解密方式
這篇文章主要介紹了jasypt對(duì)配置文件的數(shù)據(jù)加密與解密方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01elasticsearch數(shù)據(jù)信息索引操作action?support示例分析
這篇文章主要為大家介紹了elasticsearch數(shù)據(jù)信息索引操作action?support示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04SpringBoot實(shí)現(xiàn)redis延遲隊(duì)列的示例代碼
延時(shí)隊(duì)列場(chǎng)景在我們?nèi)粘I(yè)務(wù)開(kāi)發(fā)中經(jīng)常遇到,它是一種特殊類型的消息隊(duì)列,本文就來(lái)介紹一下SpringBoot實(shí)現(xiàn)redis延遲隊(duì)列的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下2024-02-02完美解決request請(qǐng)求流只能讀取一次的問(wèn)題
這篇文章主要介紹了完美解決request請(qǐng)求流只能讀取一次的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08