时间:2021-05-20
最近的工作涉及到了生成xml文件并上传到AWS存储服务S3这样的处理。期间遇到了两个问题,简单记录下:
springboot的版本是0,读写xml文件使用的是Dom4J,版本是1。逐个说明下遇到的这几个问题。
1.springboot读取xml模板异常
现阶段是将xml模板文件存储在springboot项目的resource目录下的。具体路径为
template/xxx.xml
最初是通过类加载器获取文件路径后再尝试读取模板文件的:
String fullPath = TemplateParser.class.getClassLoader().getResource(pathXml).getFile();File file = new File(fullPath);SAXReader reader = new SAXReader();Document document = reader.read(file);通过类加器获取到的文件路径是:
file:/path/of/jar/springboot-xml.jar!/BOOT-INF/classes!/template/xxx.xml
不过我们都知道,springboot是将整个工程包括配置文件打成一个jar包后再直接运行。这样想在linux的服务器上通过文件路径找文件是注定找不到的。
后来改成直接通过SpringBoot提供的 ClassResource类来获取resource路径下的配置文件:
ClassPathResource resource = new ClassPathResource(pathXml);Document doc = reader.read(resource.getInputStream());这里直接使用 InputStream读取的模板文件。注意不要再尝试通过调用 ClassResource实例的 getFile()方法来获取文件,不然会遇到和之前同样的问题。
额,期间还发生了无法将模板文件打进springboot项目运行时的jar文件这样的问题。因为是将模板文件存储在了resources的子目录下,需要调整下maven打包的配置:
<resources><resource><directory>src/main/resources</directory><filtering>true</filtering><includes><include>**/*</include></includes></resource></resources>下面这几行如果没有的话需要加上,不然会读取不到子目录中的配置文件:
<includes><include>**/*</include></includes>2.将生成的xml上传到S3
AWS提供的最便捷的上传文件接口是这个:
public PutObjectResult putObject(String bucketName, String key, File file)throws SdkClientException, AmazonServiceException;这个接口通过 File实例来执行上传。所以我一开始的想法是先生成一个临时文件保存在服务器本地,读取本地临时文件为 File执行上传,最后再删掉本地的临时文件。这个思路是没问题的,在本地执行也OK。但是在生产环境,由于权限相关的问题,生成临时文件失败了。
不想再去折腾权限相关的事情,所以将出路寄托在了AWS提供的另一个接口上:
public PutObjectResult putObject(String bucketName, String key, InputStream input, ObjectMetadata metadata)throws SdkClientException, AmazonServiceException;也就是说考虑将xml文件内容输出到 InputStream,然后再将InputStream上传到S3。一切都在内存里执行,不依赖外部文件系统也就不会有文件权限的问题。
这个方案的问题在于 ObjectMetaData这个类有点儿黑箱的意思。该怎么设置需要进行一些摸索。看了一遍这个类的接口文档,需要调用的也就这两个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);}其中后者(文件长度)是AWS建议设置的,不设置会在处理的时候给出WARN。根据方法文档也可以看到,如果不设置,在上传的时候就会在内存中缓存整个信息流来计算文件长度。
至于前者是上传到S3文件的缓存过期时间,酌情设置即可。
另一个需要解决的问题就是怎么将Dom4j生成的 Document输出再读取到 InputStream中。这里用到了 XmlWritter类,具体实现如下:
XMLWriter xmlWriter = new XMLWriter(outputStream, OutputFormat.createCompactFormat());xmlWriter.write(doc);xmlWriter.close();return new ByteArrayInputStream(outputStream.toByteArray());验证了一下,这个方法是可行的。修改后生产环境没有再报错。
向AWS S3存储服务上传文件的实现代码在这篇文章里:Java实现上传文件到AWS S3
End!
以上就是SpringBoot读写xml上传到S3的示例的详细内容,更多关于SpringBoot读写xml的资料请关注其它相关文章!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
IntellijIDEA开发工具,基于Maven框架的SpringBoot简单示例演示启动。Maven工程pom.xml配置,主要引入spring-boot-s
据安全研究机构KromtechSecurityResearchers披露,一家医疗服务机构存储在亚马逊S3上的大约47GB医疗数据意外对公众开放,其中包含315
微信收款音箱s3和s2的区别如下: 1、微信收款音箱S2是一款四角梯形形状的音箱,而微信收款音箱S3是一款圆角正方体形状的音箱。 2、S3可以连接WiFi,
简单点说就是Glacier更便宜。但是Glacier所保障的标准比S3要低。如果是想要多存多取的话,内S3是更好的选择,因为S3的延迟等等比容glacier要低
之前一直在用qiniu的存储服务,生成图片的缩略图,模糊图,视频的webp,现在需要把存储移到s3上,那么这些图片,视频处理就要自己动手写了,本文梳理一下大致的