在我们用于招聘工作的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类来使用另一个解决方案,但是让它按原样运行会很好! 任何提示都非常受欢迎!