使用 jax-rs 从 REST 服务下载 xml,无需本地存储文件

2024-03-24

在一项服务中,我正在创建一个名为 doc 的 XML 文档,并且希望用户收到下载该文档的提示,而不必将其保存在本地(如显示打开或保存文件的提示)。

但是,我无法找到应该如何构建将返回的响应,甚至无法找到@ Produce 的类型。

到目前为止我有这个:

@GET
@Path("/getXML")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public StreamingOutput getXML(
        @FormParam("id") int id) {
    UserDB userDao = new UserDB();
    entities.User userd = userDao.getById(id);

    DocumentBuilderFactory icFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder icBuilder;

    try {
        icBuilder = icFactory.newDocumentBuilder();
        Document doc = icBuilder.newDocument();

        Element rootElement = doc.createElement("Users");
        doc.appendChild(rootElement);

        rootElement.appendChild(getUser(doc, "1", "asd", "adas"));
        rootElement.appendChild(getUser(doc, "2", "bbb", "ccc"));

        //Here I should return the doc that is going to be downloaded
    }
    catch (Exception e) {
        e.printStackTrace();
    }

}

EDIT1:我的主要问题是我无法找到如何构建将返回的响应。我找到的答案下载了本地存储的现有文件。

最接近回答的线程是:如何使 XML 文档无需中间文件存储即可下载? https://stackoverflow.com/questions/17350323/how-to-make-an-xml-document-downloadable-without-intermediate-file-storage

但我无法理解如何将其应用于与 HttpServletResponse 不同的 REST 服务响应。


如果您查看链接到的答案,您会发现StreamResult https://docs.oracle.com/javase/7/docs/api/javax/xml/transform/stream/StreamResult.html用来。答案中,有一个StringWriter被传递给构造函数,但是如果你查看 Javadoc,它有一个重载的构造函数,它也需要一个OutputStream。所以如果你要返回一个StreamingOutput,只需通过OutputStream来自StreamingOutput#write(OutputStream)方法到StreamResult构造函数。答案中的其他内容应该是相同的。

return new StreamingOutput() {
    @Override
    public void write(OutputStream out)
            throws IOException, WebApplicationException {
        try {
            Transformer transformer = TransformerFactory.newInstance().newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            StreamResult result = new StreamResult(out);
            DOMSource source = new DOMSource(doc);
            transformer.transform(source, result);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
};

Here's the complete resource class I used to test. Notice that I use @Produces(MediaType.APPLICATION_XML). There's no point in setting to application/octet-stream if the data is XML1.

@Path("dom")
public class DomXmlResource {

    @GET
    @Produces(MediaType.APPLICATION_XML)
    public StreamingOutput getXml() throws Exception {

        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

        Document doc = docBuilder.newDocument();
        Element rootElement = doc.createElement("company");
        doc.appendChild(rootElement);

        Element staff = doc.createElement("Staff");
        rootElement.appendChild(staff);

        staff.setAttribute("id", "1");

        Element firstname = doc.createElement("firstname");
        firstname.appendChild(doc.createTextNode("yong"));
        staff.appendChild(firstname);

        return new StreamingOutput() {
            @Override
            public void write(OutputStream out)
                    throws IOException, WebApplicationException {
                try {
                    Transformer transformer = TransformerFactory.newInstance()
                            .newTransformer();
                    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
                    StreamResult result = new StreamResult(out);
                    DOMSource source = new DOMSource(doc);
                    transformer.transform(source, result);
                    out.flush();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
    }
}

Update

要自动下载文件(而不是显示 XML 结果),我们实际上需要添加Content-Disposition标头与attachment价值。要做到这一点,而不是返回StreamingOutput从该方法中,我们应该返回Response,其中实体将是StreamingOutput

@Path("dom")
public class DomXmlResource {

    @GET
    @Produces(MediaType.APPLICATION_XML)
    public Response getXml() throws Exception {
        ...
        StreamingOutput entity = new StreamingOutput() {
            @Override
            public void write(OutputStream out)
                    throws IOException, WebApplicationException {
                ...
            }
        };
        return Response.ok(entity)
                .header(HttpHeaders.CONTENT_DISPOSITION, 
                        "attachment;filename=file.xml")
                .build();
    }
}

Update 2

如果您还不知道,您可以简单地返回 POJO(或它们的列表),它们将自动序列化为 XML。您不需要手动使用 DOM 类来创建 XML 结构。已经有实体提供商 https://jersey.github.io/documentation/latest/message-body-workers.html它将为我们处理从 POJO 到 XML 的转换。例如,如果我们有以下POJO(需要用注释@XmlRootElement)

@XmlRootElement
public class User {
    private String name;

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

然后我们可以返回它,它会自动序列化为

<user><name>footer</name></user>

这是一个例子

@Path("pojo")
public class PojoXmlResource {

    @GET
    @Produces("application/xml")
    public Response getXml() {
        User user = new User();
        user.setName("Jane Doe");

        return Response.ok(user)
                .header(HttpHeaders.CONTENT_DISPOSITION,
                        "attachment;filename=user.xml")
                .build();
    }
}

这样就不会那么混乱了,不是吗?如果您想返回用户列表,那么您需要将其包装在GenericEntity

List<User> users = Arrays.asList(user1, user2, user3);
GenericEntity<List<User>> entity = new GenericEntity<List<User>>(users){};
return Response.ok(entity)
        ...
        .build();

1. See: Do I need Content-Type: application/octet-stream for file download? https://stackoverflow.com/q/20508788/2587435

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 jax-rs 从 REST 服务下载 xml,无需本地存储文件 的相关文章

  • XPath - 测试是否至少有一个节点具有给定值

    给定以下 XML
  • Java 弱哈希映射 - 需要根据值的弱点而不是键来删除条目

    所以JavaWeakHashMap让我们创建一个映射 如果其键变弱 则删除该映射的条目 但是我怎样才能创建一个Map 当它的条目被删除时values地图上变弱了 我想使用映射的原因是作为全局哈希表 它根据对象的 ID 跟踪对象 ID gt
  • java.sql.SQLException: ORA-01005: 给定的密码为空;登录被拒绝

    我在尝试连接到数据库时遇到以下异常 java sql SQLException ORA 01005 null password given logon denied at oracle jdbc driver T4CTTIoer proce
  • 无法从 TemporalAccessor 获取 OffsetDateTime

    当我这样做时 String datum 20130419233512 DateTimeFormatter formatter DateTimeFormatter ofPattern yyyyMMddHHmmss withZone ZoneI
  • 包含小时、分钟和秒的周期[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我需要一个代表年 月 周 日 小时 分钟 秒的间隔数据类型 前三年 年 月 日 可以用Period最后
  • 如何在 Java 中安装附加包?

    我对 Java 很陌生 我想使用名为的包中的一些功能daj 教程代码有以下几行 import daj import java util import java lang Math import Msg 但第一行和第四行会产生红色下划线 导致
  • Java 中的本机方法

    我花了一些时间学习什么是 Java Native 方法以及它们是在平台相关代码 主要是 C 中实现的 但是我在哪里可以找到这些 Java 的本机实现呢 例如 Thread 类的 sleep long millis 方法是本机的 但它的实现代
  • 文件保存在文件系统中 VS 保存在数据库中

    我正在设计一个 servlet 或 Struts2 中的操作 用于文件 图像 文档等 下载 但我想知道哪种更好的方法可以将文件保留在文件系统和数据库中 只需保留文件的路径或将文件保留在数据库中 如 BLOB 我知道当我查询数据库时 哪里的
  • 在 JSP 中对表单操作使用相对路径

    如何在表单操作中使用相对路径
  • 将 emoji 替换为适当的 java 代码

    我正在开发一个简单的java程序 它可以接受这样的字符串 停止 你违反了 法律 但是现在 你 并将每个表情符号替换为适当的 java 字符 我不知道该怎么称呼他们 这是一个例子 汽车表情符号 将替换为 uD83D uDE97 这允许我有一个
  • 可以混合使用 JVM 语言吗?即:Groovy 和 Clojure

    我知道你可以轻松地混合groovy java clojure java 无论什么JvmLang java 这是否也意味着我也可以让 clojure 和 groovy 代码进行交互 如果我使用 Grails 或 jRoR 我也可以在该环境中使
  • 如何使用 UUID 生成唯一的正 Long

    我需要为我的数据库主键列生成唯一的长 ID 我以为我可以用UUID randomUUID getMostSignificantBits 但有时它也会产生一些负多头 这对我来说是个问题 是否可以从 UUID 中仅生成正长 将会有数十亿个条目
  • 在 Java 中打开现有文件并关闭它。

    是否可以在java中打开一个文件附加数据并关闭多次 例如 psuedocode class variable declaration FileWriter writer1 new FileWriter filename fn1 writer
  • 如何在 Spring Boot 中创建 Apache POI Excel 视图配置

    当我想使用 Spring Boot Web 将数据导出到 Excel 时遇到问题 我使用 Thymeleaf 作为模板引擎 由 Spring Boot 自动配置 但是当我在附加配置中添加 XmlViewResolver 时 由 XmlVie
  • 日志记录在 Android 设备上实际上有什么作用?

    我一直在 Android 示例中看到这样的代码 try catch Exception e Log e Error e getMessage 什么是Log e实际上在物理设备上做什么 它进入系统日志 开发人员可以通过 SDK 工具访问该日志
  • 获取证书链

    我正在 Java 中使用 X509 证书 给定一个证书 是否可以在签名层次结构中找到所有其他证书 直到找到根证书 我有一个证书文件 带有 cer扩展名 我想提取父签名证书 我想继续查找该证书的父证书 直到获得最终的自签名根证书 我已经检查了
  • 有时 Properties.load() 会跳过行

    在以下情况下 Properties load 会跳过 InputStream 的第二行 这是 Java 的错误还是正常行为 public class PropTest public static void main String args
  • 如何正确使用Google Calendar API Events.Insert命令?

    所以我一直使用REST方法来调用Google的API 我需要将事件插入到我拥有 ID 的特定日历中 这是我发送的 POST 请求 地址 https www googleapis com calendar v3 calendars https
  • 对 Java 协议缓冲区对象进行一些小更改

    我想在 Java 协议缓冲区对象树的深处进行一个小更改 我可以使用 getBuilder 方法来创建一个新对象 该新对象是旧对象的克隆并进行一些更改 当深入完成此操作时 代码会变得丑陋 Quux Builder quuxBuilder fo
  • 在Java的System.out中以表格格式输出

    我正在从数据库获取结果 并希望将数据作为 Java 标准输出中的表输出 我尝试过使用 t 但我想要的第一列的长度变化很大 有没有办法将其显示在类似输出的漂亮表格中 Use System out format http java sun co

随机推荐

  • Rust 中结构的生命周期界限如何工作?

    昨天IRC里对此有一些讨论 让我感到隐隐约约的不满 问题是 如何在结构上定义生命周期以将其内容限制为 只有与 自身 一样长寿的事物 i e a self那类的东西 我最初的反应是 你不能 如果你创建一个结构体Foo lt a gt 与其关联
  • Laragon 和 Laravel - sendmail 不工作

    我使用 Windows 10 Laragon 和 Laravel 框架 我通过调用设置默认身份验证php artisan make auth 问题是当我尝试使用 忘记密码 组件时 sendmail 不起作用 我点击后Send Passwor
  • 在首次反应应用程序初始化之前显示加载图标

    在浏览器下载所有 js 文件并加载 React 应用程序之前显示加载程序图标的标准方式是什么 我可以在不破坏任何东西的情况下做这样的事情吗 div class app Loading div Yes 一旦你的 JavaScript 加载完毕
  • 在 Visual Studio 中使用不同的编译器

    这可能是一个初学者问题 但在互联网上找不到正确的答案 我很好奇我可以使用吗其他Visual Studio 10 中的编译器 我喜欢 从 Visual Studio 2010 开始 概念上可以集成另一个编译器 在书里 在 Microsoft
  • 是否可以使用flyway管理oracle数据库?

    我真的很难理解如何使用 Flyway 来管理 Oracle 数据库 相关数据库有 3 个模式 如果我在我的 gradle 文件中的 Flyway 插件定义中规定了 3 个模式 我如何管理用户本身的创建以及他们使用的表空间 任何提示或建议将非
  • Jquery Mobile 面板随内容滚动

    使用 Jquery Mobile 我有一个面板 div 来创建导航系统并将其高度设置为浏览器的 100 如果内容超出面板的高度 则 css Overflow y 属性可让用户滚动查看隐藏的内容 很简单吧 现在我遇到了一些麻烦 虽然 css
  • 如何向节点的所有特定子节点添加属性

    我有以下节点 我想在其中向所有节点添加属性add nodes
  • Flutter Firestore - 查找“文档快照”id

    我有一个带有产品列表的简单应用程序 产品存储在 Firebase Firestore 上 我想下载产品列表并让用户可以更新一些数据 所以我准备了产品清单 Widget buildProductsList return new StreamB
  • JcaPEMWriter 可以生成 PKCS#8 输出吗?

    以下代码使用JcaPEMWriterBouncyCastle 中的类 以 PKCS 1 格式输出随机生成的 RSA 私钥 BEGIN RSA PRIVATE KEY public static void main String args t
  • Kotlin for 具有不同的增量

    Kotlin 有以下内容 for i in 0 10 它与Java类似 for int i 0 i lt 10 i 但是如何改变 kotlin 中的增量以获得与 java 中类似的东西 for int i 0 i lt 10 i i 2 f
  • TYPO3-Slug 无法使用 f:link.action 中的多个参数

    我尝试在 TYPO3 9 5 中从操作链接创建语音 URL 以便让下一页知道用户来自哪里 当我使用此代码作为操作链接时
  • 更改 android 字体不起作用

    我正在使用以下代码行来更改字体类型android应用 L Typeface font Typeface createFromAsset this getAssets fonts Abumohammed ttf textView setTyp
  • 为什么泛型类中重复嵌套类型的字段声明会导致源代码大幅增加?

    场景非常罕见 但非常简单 定义一个泛型类 然后创建一个继承自外部类的嵌套类 并在嵌套内定义一个关联字段 自类型 代码片段比描述更简单 class Outer
  • WCF 中是否可以有可选的 DataMember?

    如果我有以下课程 DataContract public class GetColorsRS DataMember Name Colors Order 0 IsRequired true public List
  • 我是否仍然需要对 CSS box-shadow 属性使用所有五个供应商前缀?

    声明时说box shadow or text shadow或者梯度 你还需要所有的前缀吗 webkit box shadow inset 0 0 1px 1px e3e3e3 moz box shadow inset 0 0 1px 1px
  • Jetpack Compose Constraint 布局约束不链接

    我将 constrainAs 与 Jetpack Compose 结合使用 将 wifi 选项列表限制到父级的顶部 然后限制到文本视图的底部 从照片中可以看出 我的列表并没有被限制在父级的顶部或其下面的文本视图上 它甚至被向上推离屏幕 作为
  • Actions on Google 上的帐户取消关联

    我正在 Google 上开发一项操作 要求用户使用我的服务登录 我以前可以实施帐户关联 https developers google com actions develop identity account linking 效果很好 我能
  • UDAF 与 Spark 中聚合器的性能比较

    我正在尝试在 Spark 中编写一些注重性能的代码 并想知道是否应该编写一个聚合器 https spark apache org docs latest api java org apache spark Aggregator html o
  • Haskell:代数数据与元组

    data Ray Ray Vector Vector or type Ray Vector Vector 在惯用的 Haskell 中哪个是首选 为什么我应该使用其中一种而不是另一种 我不关心表现 它似乎与功能没有什么区别 例如 trace
  • 使用 jax-rs 从 REST 服务下载 xml,无需本地存储文件

    在一项服务中 我正在创建一个名为 doc 的 XML 文档 并且希望用户收到下载该文档的提示 而不必将其保存在本地 如显示打开或保存文件的提示 但是 我无法找到应该如何构建将返回的响应 甚至无法找到 Produce 的类型 到目前为止我有这