【问题标题】:Using Jackson annotations to serialise objects to XML使用 Jackson 注释将对象序列化为 XML
【发布时间】:2020-04-11 06:11:52
【问题描述】:

我正在使用 Spring 和 Jackson 序列化对象,然后将它们作为 XML 作为 API 的一部分返回。 Jackson 文档概述了返回的根元素名称应与对象的类名称匹配。

我有以下型号。我已明确将根元素设置为等于“产品”。

package example.models;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.Data;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import javax.persistence.*;
import java.util.Date;

@Data
@Entity
@Table(name = "products")
@JacksonXmlRootElement(localName = "product")
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @CreationTimestamp
    private Date createdAt;

    @UpdateTimestamp
    private Date updatedAt;
}

在我的控制器中,我返回一个包含检索到的产品列表的响应。

package example.controllers;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api/products")
@RequiredArgsConstructor
public class ProductController {
    private final ProductRepository productRepository;

    @GetMapping(path = "/{id}", produces = {"application/json", "application/xml"})
    public ResponseEntity<Optional<Product>> getProduct(@PathVariable Long id) {
        return ResponseEntity.ok(this.productRepository.findById(id));
    }
}

当我到达终点时,/api/products/1 我得到:

<Optional>
    <id>1</id>
    <name>Example</name>
    <createdAt>2019-12-18T12:44:12.536+0000</createdAt>
    <updatedAt>2019-12-18T12:44:12.536+0000</updatedAt>
</Optional>

虽然,我期待:

<product>
    <id>1</id>
    <name>Example</name>
    <createdAt>2019-12-18T12:44:12.536+0000</createdAt>
    <updatedAt>2019-12-18T12:44:12.536+0000</updatedAt>
</product>

我如何使用 Jackson/jackson-dataformat-xml 来实现这一点,因为我的注释看起来没有效果?

【问题讨论】:

    标签: java spring hibernate jackson


    【解决方案1】:

    更改端点以返回 Product 而不是 Optional

    @GetMapping(path = "/{id}", produces = {"application/json", "application/xml"})
    public ResponseEntity<Product> getProduct(@PathVariable Long id) {
        return ResponseEntity.ok(this.productRepository.findById(id).get());
    }
    

    注意:为简单起见,此处使用Optional.get()。没有Product 的情况应该使用Optional 方法如isPresent()orElse() 妥善处理。

    【讨论】:

    • 这似乎是正确的,请注意Optional 的意思正是它所说的。这是可选的。您需要检查它是否存在于Optional.isPresent()。根据您的设计,如果 isPresent 返回 false,您可能会返回 404。
    • 感谢您的回答!在这种情况下,效果很好......但如果我返回 List&lt;Product&gt;,例如,它会返回 &lt;List&gt;&lt;item&gt;...&lt;/item&gt;&lt;/List&gt;
    • @ChristopherSchneider:谢谢,更新了答案。 @spudmonkee:在这种情况下,需要将列表包装在对象 Products 中,并且端点将返回单个 Products 对象。
    猜你喜欢
    • 2018-01-27
    • 2017-09-10
    • 1970-01-01
    • 2016-03-09
    • 2015-01-06
    • 2013-01-20
    • 2021-09-19
    • 1970-01-01
    • 2013-09-10
    相关资源
    最近更新 更多