用于投影异常的Spring Data Rest ResourceProcessor

时间:2017-03-29 07:58:00

标签: java spring spring-data-rest

我创建了以下Projection

@Projection(name = "select", types = {Organisation.class})
public interface OrganisationSelectProjection {

    Long getId();

    String getName();

}

我想在" Select"组件所以我需要尽可能少的数据。所以我也想删除ResourceProcessor的所有链接,所以我创建了这个:

@Bean
public ResourceProcessor<Resource<OrganisationSelectProjection>> organisationProcessor() {
    return resource -> {
        resource.removeLinks();
        return resource;
    };
}

然而,看起来这打破了整个API,因为我点击的任何端点都得到以下异常消息org.springframework.hateoas.PagedResources cannot be cast to org.springframework.hateoas.Resource

知道我做错了吗?

1 个答案:

答案 0 :(得分:2)

如果您希望保留匿名课程,使用ResourceSupport代替Resource可以解决问题。

@Bean
public ResourceProcessor<ResourceSupport> organisationProcessor() {
    return resource -> {
        resource.removeLinks();
        return resource;
    };
}

但是在这种情况下,无论内容的类型如何,处理器都将在每个资源上使用(尽管你可以在方法体内查看)。

您可以将其定义为独立类,而不是ResourceProcessor的匿名后代:

public class OrganizationResourceProcessor implements ResourceProcessor<Resource<OrganisationSelectProjection>> {
    @Override
    public Resource<OrganisationSelectProjection> process(Resource<OrganisationSelectProjection> resource) {
        resource.removeLinks();
        return resource;
    }
}

@Bean
public OrganizationResourceProcessor  organisationProcessor() {
    return new OrganizationResourceProcessor();
}

您遇到的问题与类型擦除有关,因为匿名类实现中没有任何类型参数。您的定义是类型安全的,但它缺少在确定特定ResourceProcessor是否可以处理资源时在运行时使用的类型相关数据。因此spring-data-rest认为匿名organizationProcessor可以处理PagedResources并将其提供给ClassCastException发生的处理器。

并非spring-data-rest通过ResourceProcessor的所有内容都是Resource。可能有org.springframework.hateoas.ResourceSupport类的不同后代(在您的情况下为PagedResources),其中大多数不是从Resource继承的。