JsonView用于过滤Spring MVC中的Json属性不起作用

时间:2016-11-21 10:22:35

标签: spring rest spring-mvc jackson

在我们用于招聘工作的Spring MVC Web应用程序中,我使用RESTful服务来获取有关给定帐户的可用公司的信息,或者针对单个公司的更详细数据。

这是使用Spring MVC以非常简单的方式实现的。 从逻辑上讲,单个公司的API显示的详细信息比公司列表更多。特别是,只有在通过其ID查询单个公司的详细信息时才会显示两个字段(CoverPhoto和Logo)。

为了生成Json输出,我使用Jackson为返回的DTO对象注释特定的字段名称,因为有时它们与成员变量名称不同。

以优雅的方式实现它的一种方法是使用JsonViews,如这些教程中所述:

https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring http://www.baeldung.com/jackson-json-view-annotation

它们之间的唯一区别是第二个使用View类的接口,第一个使用类。但这不应该有任何区别,而且我的代码与其中任何一个都没有按预期工作。

我创建了接口(ObjectList和OblectDetails)并在我的DTO中注释了字段     @JsonView(Views.ObjectList.class) 对于我想在lisdt和details API上看到的字段,以及     @JsonView(Views.ObjectDetails.class) 对于仅在单个公司API中显示的字段。

但不幸的是,无论注释如何,两个API都会显示所有字段。此外,没有@JsonView注释的字段出现在输出JSON中,而根据文档,当使用@JsonView注释Controller方法时,每个字段也应该使用@JsonView注释进行注释以显示。

我的简化代码如下:

DTO:

package nl.xxxxxx.dto.too;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonView;

@JsonAutoDetect
@JsonPropertyOrder({"id", "name", "logo", "coverPhoto", "description", "shortDescription",
        "phone", "address"})

public class XxxCompanyDto {

    @JsonView(Views.ObjectList.class)
    private Long id;

    @JsonView(Views.ObjectList.class)
    private String name;

    @JsonView(Views.ObjectDetails.class)
    private String logo;

    @JsonView(Views.ObjectDetails.class)
    @JsonProperty("cover_photo")
    private String coverPhoto;

    @JsonView(Views.ObjectList.class)
    private String description;

    //more fields

    //setters, no getters are used to prevent ambiguity for Json generation
    //omitted for clarity
}

查看:

package nl.xxx.dto.too;

public class Views {

    public interface ObjectList {}

    public interface ObjectDetails extends ObjectList {}
}

控制器:

package nl.xxx.controller;

import com.fasterxml.jackson.annotation.JsonView;
import org.springframework.web.bind.annotation.*;
//more imports 

/**
 * Created by Klaas van Gelder on 17-Nov-16.
 */

@RestController
public class XxxCompanyController {

    @Autowired
    //services omitted

    @JsonView(Views.ObjectDetails.class)
    @RequestMapping(value = "/public-api/xxx/company/{companyId}", method = RequestMethod.GET)
    public TooCompanyDto getCompanyById(
            @RequestHeader(value = "X-Channel") String publicationChannelToken,
            @PathVariable(value = "companyId") Long companyId) {

        XxxCompany tooCompany = tooCompanyService.getCompanyById(companyId);
        //some verifications omitted
        TooCompanyDto tooCompanyDto = tooCompanyJsonConverter.convertToDto(tooCompany);

        return tooCompanyDto;
    }


    @JsonView(Views.ObjectList.class)
    @RequestMapping(value = "/public-api/xxx/company", method = RequestMethod.GET)
    public List<TooCompanyDto> listCompaniesForChannel(
            @RequestHeader(value = "X-Channel") String publicationChannelToken) {

        XxxPublicationChannel channel = tooVacancyService.findPublicationChannelByToken(publicationChannelToken);
        List<XxxCompany> xxxCompaniesForChannel = xxxCompanyService.findCompaniesByPublicationChannelToken(publicationChannelToken);

        List<XxxCompanyDto> dtoList = new ArrayList<>();
        for (XxxCompany xxxCompany : xxxCompaniesForChannel) {
            XxxCompanyDto xxxCompanyDto = xxxCompanyJsonConverter.convertToDto(xxxCompany);
            dtoList.add(xxxCompanyDto);
        }

        return dtoList;
    }
}

的Maven:                               org.springframework             弹簧核心             4.2.2.BUILD-快照         

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>${jackson-2-version}</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>${jackson-2-version}</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson-2-version}</version>
    </dependency>
    //more depedencies

    with <jackson-2-version>2.2.2</jackson-2-version> in parent POM

似乎完全忽略了JsonView注释。我可以通过使用两个单独的DTO类来使用另一个解决方案,但是让它按原样运行会很好! 任何提示都非常受欢迎!

0 个答案:

没有答案