Java show/hide object fields depending on REST call



Is it possible to config the Item class that depending on the REST call to show and hide specific fields? For example I want to hide colorId (and show categoryId) from User class when calling XmlController and vice versa when calling JsonController.

Item class

@Getter
@Setter
@NoArgsConstructor
public class Item
{
   private Long id;
   private Long categoryId;    // <-- Show field in XML REST call and hide in JSON REST call
   private Long colorId;       // <-- Show field in JSON REST call and hide in XML REST call
   private Long groupId;
   @JacksonXmlProperty(localName = "item")
   @JacksonXmlElementWrapper(localName = "groupItems")
   private List<GroupedItem> item;
}

JSON Controller

@RestController
@RequestMapping(
    path = "/json/",
    produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class JsonController
{
    @Autowired
    private Service service;

    @RequestMapping(path = "{colorId}")
    public Item getArticles(@PathVariable("colorId") Long colorId)
    {
        return service.getByColor(colorId); // returns JSON without "categoryId"
    }
}

XML Controller

@RestController
@RequestMapping(
    path = "/xml/",
    produces = MediaType.APPLICATION_XML_VALUE)
public class XmlController
{
    @Autowired
    private Service service;

    @RequestMapping(path = "{categoryId}")
    public Item getArticles(@PathVariable("categoryId") Long categoryId)
    {
        return service.getByCategory(categoryId); // returns XML without "colorId"
    }
}

Answer

I’ve solved it by creating following View:

public class View
{
    public static class Parent
    {
    }

    public static class Json extends Parent
    {
    }

    public static class Xml extends Parent
    {
    }
}

With this config it is possible to set up the Class as:

@Getter
@Setter
@NoArgsConstructor
@JsonView(View.Parent.class)
public class Item
{
   private Long id;
   @JsonView(View.Xml.class)  // <-- Show field in XML REST call and hide in JSON REST call
   private Long categoryId;    
   @JsonView(View.Json.class) // <-- Show field in JSON REST call and hide in XML REST call
   private Long colorId;    
   private Long groupId;
   @JacksonXmlProperty(localName = "item")
   @JacksonXmlElementWrapper(localName = "groupItems")
   private List<GroupedItem> item;
}

(Note: if you want to list List<GroupedItem> item in your response you need to define @JsonView(View.Parent.class) in GroupedItem as well)

Finally, if you are using Spring, the REST requests (See question) can be defined as:

@JsonView(View.Json.class) // or @JsonView(View.Xml.class) in other case
@RequestMapping(path = "{colorId}")
public Item getArticles(@PathVariable("colorId") Long colorId)
{
    return service.getByColor(colorId); // returns JSON without "categoryId"
}


Source: stackoverflow