Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring mvc Spring数据Rest-PersistentEntityResourcesAssembler中的空指针_Spring Mvc_Spring Data_Spring Data Jpa_Spring Data Rest - Fatal编程技术网

Spring mvc Spring数据Rest-PersistentEntityResourcesAssembler中的空指针

Spring mvc Spring数据Rest-PersistentEntityResourcesAssembler中的空指针,spring-mvc,spring-data,spring-data-jpa,spring-data-rest,Spring Mvc,Spring Data,Spring Data Jpa,Spring Data Rest,由于空指针,@RepositoryRestResource返回500错误时出现问题 我有一个名为Resource的抽象类,它使用InheritanceType.JOINED和@JsonSubTypes来提供Resource的大约5个子类,例如ServerResource。特定的资源在与之关联的另一个实体中引用时返回良好。在代码中调用PagingAndSortingRepository时也可以正常工作。问题是@RepositoryRestResource为资源实体公开的端点在直接调用时返回500错

由于空指针,@RepositoryRestResource返回500错误时出现问题

我有一个名为
Resource
的抽象类,它使用
InheritanceType.JOINED
@JsonSubTypes
来提供
Resource
的大约5个子类,例如
ServerResource
。特定的
资源
在与之关联的另一个实体中引用时返回良好。在代码中调用PagingAndSortingRepository时也可以正常工作。问题是@RepositoryRestResource为
资源
实体公开的端点在直接调用时返回500错误(由于NPE)

调试后,我发现问题是由于行
PersistentEntityResourcesEmbler:154
引起的。映射对象为空,因为框架无法将
ServerResource.class
映射到父
Resource.class
。缓存是一个映射,使用
.getClass()


有没有什么方法可以让
资源
实体为这些单独的类型找到一个端点?这几乎像是一个bug。

为了纠正这个问题,我重写了
resourceMappings()
方法,并注入了我需要的映射。这解决了这个问题,现在/resources-uri按预期工作

package com.environment.config;

import java.lang.reflect.Field;
import java.util.Map;

import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.core.mapping.RepositoryResourceMappings;
import org.springframework.data.rest.core.mapping.ResourceMappings;
import org.springframework.data.rest.core.mapping.ResourceMetadata;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;

import com.environment.domain.Resource;
import com.environment.util.Tuple;

@Configuration
public class RepositoryConfig extends RepositoryRestMvcConfiguration {

    @Override
    public ResourceMappings resourceMappings() {
        RepositoryResourceMappings rm = RepositoryResourceMappings)super.resourceMappings();
        try {
            Field cacheField = rm.getClass().getDeclaredField("cache");
            cacheField.setAccessible(true);
            Map<Class<?>, ResourceMetadata> cache = (Map<Class<?>, ResourceMetadata>) cacheField.get(rm);

            //Get metadata for parent object
            ResourceMetadata resourceMetadata = cache.entrySet().stream()
                .map(Tuple<Class<?>,ResourceMetadata>::new)
                .filter(t -> Resource.class.equals(t.t))
                .map(t -> t.u)
                .findFirst()
                .get();

            ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
            provider.addIncludeFilter(new AssignableTypeFilter(Resource.class));

                provider.findCandidateComponents("com/environment")
                .stream()
                .map(beanDef -> {
                    try {
                        return Class.forName(beanDef.getBeanClassName());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return null;
                })
                .filter(c -> !Resource.class.equals(c))
                .filter(c -> Resource.class.isAssignableFrom(c))
                .peek(c -> System.out.println("Mapping: " + c)
                .forEach(c -> cache.put((Class<?>) c, resourceMetadata));

        } catch (Exception e) {
            e.printStackTrace();
        }


        return rm;
    }

}
package com.environment.config;
导入java.lang.reflect.Field;
导入java.util.Map;
导入org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
导入org.springframework.context.annotation.Configuration;
导入org.springframework.core.type.filter.AssignableTypeFilter;
导入org.springframework.data.rest.core.config.RepositoryRestConfiguration;
导入org.springframework.data.rest.core.mapping.RepositoryResourceMappings;
导入org.springframework.data.rest.core.mapping.ResourceMappings;
导入org.springframework.data.rest.core.mapping.ResourceMetadata;
导入org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
导入com.environment.domain.Resource;
导入com.environment.util.Tuple;
@配置
公共类RepositoryConfig扩展了RepositoryRestMvcConfiguration{
@凌驾
公共资源映射ResourceMappings(){
RepositoryResourceMappings rm=RepositoryResourceMappings)super.resourceMappings();
试一试{
字段cacheField=rm.getClass().getDeclaredField(“缓存”);
cacheField.setAccessible(true);

Map要更正此问题,我重写了
resourceMappings()
方法,并注入了所需的映射。这解决了问题,现在/resources uri按预期工作

package com.environment.config;

import java.lang.reflect.Field;
import java.util.Map;

import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.core.mapping.RepositoryResourceMappings;
import org.springframework.data.rest.core.mapping.ResourceMappings;
import org.springframework.data.rest.core.mapping.ResourceMetadata;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;

import com.environment.domain.Resource;
import com.environment.util.Tuple;

@Configuration
public class RepositoryConfig extends RepositoryRestMvcConfiguration {

    @Override
    public ResourceMappings resourceMappings() {
        RepositoryResourceMappings rm = RepositoryResourceMappings)super.resourceMappings();
        try {
            Field cacheField = rm.getClass().getDeclaredField("cache");
            cacheField.setAccessible(true);
            Map<Class<?>, ResourceMetadata> cache = (Map<Class<?>, ResourceMetadata>) cacheField.get(rm);

            //Get metadata for parent object
            ResourceMetadata resourceMetadata = cache.entrySet().stream()
                .map(Tuple<Class<?>,ResourceMetadata>::new)
                .filter(t -> Resource.class.equals(t.t))
                .map(t -> t.u)
                .findFirst()
                .get();

            ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
            provider.addIncludeFilter(new AssignableTypeFilter(Resource.class));

                provider.findCandidateComponents("com/environment")
                .stream()
                .map(beanDef -> {
                    try {
                        return Class.forName(beanDef.getBeanClassName());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return null;
                })
                .filter(c -> !Resource.class.equals(c))
                .filter(c -> Resource.class.isAssignableFrom(c))
                .peek(c -> System.out.println("Mapping: " + c)
                .forEach(c -> cache.put((Class<?>) c, resourceMetadata));

        } catch (Exception e) {
            e.printStackTrace();
        }


        return rm;
    }

}
package com.environment.config;
导入java.lang.reflect.Field;
导入java.util.Map;
导入org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
导入org.springframework.context.annotation.Configuration;
导入org.springframework.core.type.filter.AssignableTypeFilter;
导入org.springframework.data.rest.core.config.RepositoryRestConfiguration;
导入org.springframework.data.rest.core.mapping.RepositoryResourceMappings;
导入org.springframework.data.rest.core.mapping.ResourceMappings;
导入org.springframework.data.rest.core.mapping.ResourceMetadata;
导入org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
导入com.environment.domain.Resource;
导入com.environment.util.Tuple;
@配置
公共类RepositoryConfig扩展了RepositoryRestMvcConfiguration{
@凌驾
公共资源映射ResourceMappings(){
RepositoryResourceMappings rm=RepositoryResourceMappings)super.resourceMappings();
试一试{
字段cacheField=rm.getClass().getDeclaredField(“缓存”);
cacheField.setAccessible(true);

MapI可以发布到URL,但GET不起作用。我可以发布到URL,但GET不起作用。