Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.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
Java 尝试定义自定义属性映射时出现NullPointerException_Java_Spring_Nullpointerexception_Modelmapper - Fatal编程技术网

Java 尝试定义自定义属性映射时出现NullPointerException

Java 尝试定义自定义属性映射时出现NullPointerException,java,spring,nullpointerexception,modelmapper,Java,Spring,Nullpointerexception,Modelmapper,我使用ModelMapper的方式如下: 我有几个转换器类是Spring组件,它们注册自定义ModelMapper映射 @Component public class FooConverter { @Autowired private ModelMapper modelMapper; public static final PropertyMap<Foo, FooModel> FOO_TO_FOO_MODEL_MAP = new PropertyMap&l

我使用ModelMapper的方式如下:

我有几个转换器类是Spring组件,它们注册自定义ModelMapper映射

@Component
public class FooConverter {

    @Autowired
    private ModelMapper modelMapper;

    public static final PropertyMap<Foo, FooModel> FOO_TO_FOO_MODEL_MAP = new PropertyMap<Foo, FooModel>() {
        @Override
        protected void configure() {
            map().setTimeZone(source.getTimeZone().getID());
        }
    };

    @PostConstruct
    public void init() {
        modelMapper.addMappings(FOO_TO_FOO_MODEL_MAP);
    }
}
重要编辑

实际上,即使在主类内的函数中显式创建映射,也会得到相同的NullPointerException

public class main {
public static void main(String[] args) {
    ModelMapper mapper = new ModelMapper();
    final PropertyMap<Foo, FooModel> FOO_TO_FOO_MODEL_MAP = new PropertyMap<Foo, FooModel>() {
       @Override
       protected void configure() {
           map().setTimeZone(source.getTimeZone().getID());
       }
    };

    mapper.addMappings(FOO_TO_FOO_MODEL_MAP );
}
问题只在于时区对象,所以我必须使用转换器,这并不理想

map().setTimeZone(source.getTimeZone().getID());


public class Foo {
    private TimeZone timeZone;
    //Setters//Getters

}

public class FooModel {
    private String timeZoneId;
    //Setters//Getters
}
使用构造函数自动连线 像

还要确保ModelMapper bean已在spring配置类中定义,如下所示:

@Bean
public ModelMapper modelMapper() {
    return new ModelMapper();
}

我认为这最终是因为ModelMapper在配置映射器时不能实例化
TimeZone
对象(也不能实例化
LocalDateTime
等)

实际上你不需要配置任何东西

ModelMapper mapper = new ModelMapper();

Foo foo = new Foo();
foo.setTimeZone(TimeZone.getDefault());

FooModel model = mapper.map(foo, FooModel.class);
System.out.println(model.getTimeZoneId()); // "Europe/Berlin" here
这对我有用。ModelMapper发现您想要将
时区的属性
ID
映射到
FooModel
的属性
timeZoneId

不过,如果您想手动执行此操作: 我很快就看完了文档,发现了。 使用将
时区
转换为
字符串
转换器
,可以执行以下操作:

ModelMapper mapper = new ModelMapper();
TypeMap<Foo, FooModel> typeMap = mapper.createTypeMap(Foo.class, FooModel.class);
Converter<TimeZone, String> tzConverter = ctx -> ctx.getSource().getID() + "!!!";
typeMap.addMappings(map -> {
    map.using(tzConverter).map(Foo::getTimeZone, FooModel::setTimeZoneId);
});

Foo foo = new Foo();
foo.setTimeZone(TimeZone.getDefault());

FooModel model = mapper.map(foo, FooModel.class);
System.out.println(model.getTimeZoneId()); // "Europe/Berlin!!!" here
ModelMapper-mapper=newmodelmapper();
TypeMap TypeMap=mapper.createTypeMap(Foo.class,FooModel.class);
转换器tzConverter=ctx->ctx.getSource().getID()+“!!!”;
typeMap.addMappings(映射->{
map.using(tzConverter.map)(Foo::getTimeZone,FooModel::setTimeZoneId);
});
Foo-Foo=新的Foo();
setTimeZone(TimeZone.getDefault());
FooModel model=mapper.map(foo,FooModel.class);
System.out.println(model.getTimeZoneId());//“欧洲/柏林!!!”在这里

对于遇到相同问题的人:我的问题是我使用了带有匿名实现的PropertyMap,就像spring配置中建议的文档一样。这在ExplicitMappingBuilder中搞砸了。我现在有以下资料:

@Configuration
public class ApplicationConfig {

    @Bean
    public ModelMapper modelMapper() {
        ModelMapper modelMapper = new ModelMapper();
        modelMapper.addMappings(new UserPropertyMap());
        return modelMapper;
    }
}
我的UserPropertyMap如下所示:

public class UserPropertyMap extends PropertyMap<UserRepresentation, UserDTO> {
    @Override
    protected void configure() {
        map().setUserName(source.getUsername());
    }
}
公共类UserPropertyMap扩展了PropertyMap{
@凌驾
受保护的void configure(){
map().setUserName(source.getUsername());
}
}

这就像Spring Boot 2中的魅力一样。

基于构造函数的连接只会使bean的缺乏更加明显,但是如果bean被正确定义和连接,你就无法区分基于字段的连接和基于构造函数的连接。这是在修复一个症状。它总是倾向于使用基于Construtor的接线。它确保在为类创建Bean之前初始化注入Beannull@SayantanMandal在现实世界中,基于构造函数的布线变得非常困难!您的
modelMapper
bean在哪里定义?@Makoto问题已更新。bean的定义是正确的,它不是nullIs
Foo
FooModel
声明为
final
?@JanRieke不,它们不是。您说过映射可以用于那些示例类
InnerFoo,Foo l,FooModel
。您能为
FooModel
添加一个无法映射的示例吗?谢谢。我最终使用了一个转换器。
ModelMapper mapper = new ModelMapper();

Foo foo = new Foo();
foo.setTimeZone(TimeZone.getDefault());

FooModel model = mapper.map(foo, FooModel.class);
System.out.println(model.getTimeZoneId()); // "Europe/Berlin" here
ModelMapper mapper = new ModelMapper();
TypeMap<Foo, FooModel> typeMap = mapper.createTypeMap(Foo.class, FooModel.class);
Converter<TimeZone, String> tzConverter = ctx -> ctx.getSource().getID() + "!!!";
typeMap.addMappings(map -> {
    map.using(tzConverter).map(Foo::getTimeZone, FooModel::setTimeZoneId);
});

Foo foo = new Foo();
foo.setTimeZone(TimeZone.getDefault());

FooModel model = mapper.map(foo, FooModel.class);
System.out.println(model.getTimeZoneId()); // "Europe/Berlin!!!" here
@Configuration
public class ApplicationConfig {

    @Bean
    public ModelMapper modelMapper() {
        ModelMapper modelMapper = new ModelMapper();
        modelMapper.addMappings(new UserPropertyMap());
        return modelMapper;
    }
}
public class UserPropertyMap extends PropertyMap<UserRepresentation, UserDTO> {
    @Override
    protected void configure() {
        map().setUserName(source.getUsername());
    }
}