Reputation: 399
I'm using Spring and Jackson to serialise objects before returning them as XML as part of an API. The Jackson documentation outlines that the root element name returned should match that of the object's class name.
I have the following model. I've explicitly set the root element to equal 'product'.
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;
}
In my controller, I'm returning a response containing the list of products retrieved.
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));
}
}
When I hit the endpoint, /api/products/1
I get:
<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>
Although, I'm expecting:
<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>
How can I use Jackson/jackson-dataformat-xml
to achieve this as it looks like my annotations have no effect?
Upvotes: 0
Views: 228
Reputation: 2215
Change the endpoint to return a Product
instead of Optional
.
@GetMapping(path = "/{id}", produces = {"application/json", "application/xml"})
public ResponseEntity<Product> getProduct(@PathVariable Long id) {
return ResponseEntity.ok(this.productRepository.findById(id).get());
}
Note: Optional.get()
is used here for simplicity. The case of having no Product
should be properly handled with Optional
methods like isPresent()
or orElse()
.
Upvotes: 1