首页 > 解决方案 > 使用 Jackson 注释将对象序列化为 XML

问题描述

我正在使用 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来实现这一点,因为我的注释看起来没有效果?

标签: javaspringhibernatejackson

解决方案


将端点更改为返回 aProduct而不是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()为简单起见,此处使用。没有的情况应该用or之类的方法Product来妥善处理。OptionalisPresent()orElse()


推荐阅读