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的资料请关注脚本之家其它相关文章!

相关文章

  • Java Spring Boot消息服务万字详解分析

    Java Spring Boot消息服务万字详解分析

    在实际项目开发中,有时需要与其他系统进行集成完成相关业务功能,这种情况最原始做法是程序内部相互调用,除此之外,还可以用消息服务中间件进行业务处理,用消息服务中间件处理业务能够提升系统的异步通信和扩展解耦能力。Spring Boot对消息服务管理提供了非常好的支持
    2021-10-10
  • SpringBoot多级缓存实现方案总结

    SpringBoot多级缓存实现方案总结

    所谓多级缓存,是指在整个系统架构的不同系统层面进行数据缓存,以提升访问速度,多级缓存就是为了解决项目服务中单一缓存使用不足的缺点,本文我们将给大家总结了SpringBoot多级缓存实现方案,需要的朋友可以参考下
    2023-08-08
  • Java实现读取html文本内容并按照格式导出到excel中

    Java实现读取html文本内容并按照格式导出到excel中

    这篇文章主要为大家详细介绍了如何使用Java实现读取html文本提取相应内容按照格式导出到excel中,文中的示例代码讲解详细,需要的可以参考下
    2024-02-02
  • Netty学习教程之基础使用篇

    Netty学习教程之基础使用篇

    Netty是由JBOSS提供的一个Java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。下面这篇文章主要给大家介绍了关于Netty基础使用的相关资料,需要的朋友可以参考下。
    2017-05-05
  • Springboot整合Netty实现RPC服务器的示例代码

    Springboot整合Netty实现RPC服务器的示例代码

    这篇文章主要介绍了Springboot整合Netty实现RPC服务器的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • IDEA 错误之找不到或无法加载主类的问题

    IDEA 错误之找不到或无法加载主类的问题

    这篇文章主要介绍了IDEA 错误之找不到或无法加载主类,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • IDEA2020.2.3

    IDEA2020.2.3 "reading maven projects"卡住的问题

    这篇文章主要介绍了IDEA2020.2.3 "reading maven projects"卡住的问题及问题原因探究,通过多种方法给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2020-10-10
  • Java GUI实现多个窗口切换效果

    Java GUI实现多个窗口切换效果

    这篇文章主要为大家详细介绍了Java GUI实现多个窗口的切换效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • SpringBoot项目中使用Netty实现远程调用的示例代码

    SpringBoot项目中使用Netty实现远程调用的示例代码

    众所周知在进行网络连接的时候,建立套接字连接是一个非常消耗性能的事情,特别是在分布式的情况下,那么该通过什么技术去解决上述的问题呢,本文小编给大家介绍了SpringBoot项目中使用Netty实现远程调用的方法,需要的朋友可以参考下
    2025-04-04
  • Java局部打印效果不同问题解决方案

    Java局部打印效果不同问题解决方案

    这篇文章主要介绍了Java局部打印效果不同问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09

最新评论