SpringBoot读写xml上传到AWS存储服务S3的示例

 更新时间:2020年10月27日 09:15:07   作者:白42  
这篇文章主要介绍了SpringBoot读写xml上传到S3的示例,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下

最近的工作涉及到了生成xml文件并上传到AWS存储服务S3这样的处理。期间遇到了两个问题,简单记录下:

  • springboot读取xml模板异常
  • 将生成的xml上传到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的资料请关注脚本之家其它相关文章!

相关文章

  • Mybatis中like搭配concat的写法详解

    Mybatis中like搭配concat的写法详解

    这篇文章主要介绍了Mybatis中like搭配concat的写法详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • Java中的stream流的概念解析及实际运用总结

    Java中的stream流的概念解析及实际运用总结

    流是指传输时的数据,Java为流准备了很多内置类,尤其是IO输入输出流非常常用,这里我们来看一下Java中的stream流的概念解析及实际运用总结
    2016-06-06
  • 解决@ResponseBody作用在返回类型为String的方法时的坑

    解决@ResponseBody作用在返回类型为String的方法时的坑

    这篇文章主要介绍了解决@ResponseBody作用在返回类型为String的方法时的坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • java单例模式使用及注意事项

    java单例模式使用及注意事项

    这篇文章主要介绍了java单例模式使用及注意事项,需要的朋友可以参考下
    2014-04-04
  • 深入分析Comparable与Comparator及Clonable三个Java接口

    深入分析Comparable与Comparator及Clonable三个Java接口

    接口不是类,而是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义,这篇文章主要为大家详细介绍了Java的Comparable,Comparator和Cloneable的接口,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-05-05
  • java远程连接调用Rabbitmq的实例代码

    java远程连接调用Rabbitmq的实例代码

    本篇文章主要介绍了java远程连接调用Rabbitmq的实例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • Java Ehcache缓存框架入门级使用实例

    Java Ehcache缓存框架入门级使用实例

    这篇文章主要介绍了Java Ehcache缓存框架入门级使用实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-08-08
  • 详解java封装继承多态

    详解java封装继承多态

    这篇文章主要介绍了java封装继承多态,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • java正则表达式使用示例

    java正则表达式使用示例

    这篇文章主要介绍了java正则表达式使用示例,实现拆分字符串、替换字符串、判断字符串是否与制定模式匹配等功能,需要的朋友可以参考下
    2014-03-03
  • Java中使用MyBatis-Plus操作数据库的实例

    Java中使用MyBatis-Plus操作数据库的实例

    本文主要介绍了Java中使用MyBatis-Plus操作数据库的实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-02-02

最新评论