Spring Data Rest投影不适用于单个资源

时间:2017-04-29 14:28:54

标签: spring spring-boot spring-data spring-data-rest

我为实体类编写了以下投影。

@Projection(name = "instituteProjection", types = { Institute.class })
public interface InstituteProjection {

    String getOrganizationName();

    Address getRegisteredAddress();
}

现在,每当我调用返回单个学院资源的网址http://localhost:8080/institutes/1?projection=instituteProjection时,我都会尝试应用此投影。控制器GET方法实现如下:

@RequestMapping(value = "institutes/{instituteId}", method = RequestMethod.GET,
        produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> getInstitute(@PathVariable Long instituteId) {
    Institute institute = service.getInstitute(instituteId);
    return new ResponseEntity<>(institute, HttpStatus.OK);
}

问题是这不会返回研究所预测。它返回默认存储库json。

只有使用SDR生成的控制器而不是我实现的自定义静止控制器时,投影才有效。

那么如何在自定义控制器中应用投影?

更新1 学院班级

@Data
@Entity
public class Institute{

 private String organizationName;

    @OneToOne
    private Address registeredAddress;

    @OneToOne
    private Address mailingAddress;

}

更新2

地址类

    public class Address {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private long addressID;   

    @ManyToOne
    private Street street;

    @ManyToOne
    private Country country;

    private double latitude;

    private double longitude;

    @ManyToOne
    private City city;


}

1 个答案:

答案 0 :(得分:1)

这非常简单。您可以使用现有投影,甚至可以删除@Projection注释,这不是必须使用自定义控制器。

所以最小的预测是:

public interface InstituteProjection {

    String getOrganizationName();

    Address getRegisteredAddress();

}

现在,要转换您的Institute实体,您需要ProjectionFactory interface的实现,现有的实体是SpelAwareProxyProjectionFactory

要使该类型的bean可访问,请添加一个小配置:

@Configuration
public class ProjectionFactoryConfig {

    @Bean
    public ProjectionFactory projectionFactory() {
        return new SpelAwareProxyProjectionFactory();
    }

}

现在您可以在控制器中使用它将您的学院转换为您的InstituteProjection:

@Autowired
private ProjectionFactory projectionFactory;

...

@RequestMapping(value = "institutes/{instituteId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> getInstitute(@PathVariable Long instituteId) {
    final Institute institute = service.getInstitute(instituteId);
    final InstituteProjection instituteProjection = projectionFactory.createProjection(InstituteProjection.class, institute);
    return new ResponseEntity<>(instituteProjection, HttpStatus.OK);
}