Java 8 @lombok和mapstruct的访问器(fluent=true)
我有一个下游服务,我想将其bean映射到我的bean。但是使用mapstruct似乎有问题 来自下游服务的Pojo(其定义我无法更改) 我想把它转换成PojoBJava 8 @lombok和mapstruct的访问器(fluent=true),java-8,lombok,mapstruct,Java 8,Lombok,Mapstruct,我有一个下游服务,我想将其bean映射到我的bean。但是使用mapstruct似乎有问题 来自下游服务的Pojo(其定义我无法更改) 我想把它转换成PojoB @Setter @Getter @ToString public class PojoB { private String stringB; private int integer; } 映射器接口 @Mapper public interface PojoMapper { PojoMapper INSTAN
@Setter
@Getter
@ToString
public class PojoB {
private String stringB;
private int integer;
}
映射器接口
@Mapper
public interface PojoMapper {
PojoMapper INSTANCE = Mappers.getMapper(PojoMapper.class);
@Mapping(source = "stringA", target = "stringB")
PojoB pojoAToPojoB(PojoA pojoA);
}
这会失败,因为它找不到getter,因为从getter中删除前缀,然后,
我知道mapstruct生成映射器接口的实现,并使用bean规范(即get和set前缀)
有没有办法克服这个问题?如注释中所述,这可以通过编写一个自定义的
accessornamigstrategy
来实现,该策略将以流畅的访问器形式返回方法的名称
我已经编写了一个自定义生成器访问器(也可以应用于您的案例),您可以找到它
除此之外,还有一个针对MapStruct的开放PR,它增加了对构建器的支持,同时还增加了对流畅链接访问器的支持
您的定制策略(如PR中建议的)可以如下所示:
public class FluentAccessorNamingStrategy extends DefaultAccessorNamingStrategy {
@Override
public boolean isSetterMethod(ExecutableElement method) {
String methodName = method.getSimpleName().toString();
return methodName.startsWith( "set" ) && methodName.length() > 3 || isBuilderSetter( method );
}
protected boolean isBuilderSetter(ExecutableElement method) {
return method.getParameters().size() == 1 &&
!JAVA_JAVAX_PACKAGE.matcher( method.getEnclosingElement().asType().toString() ).matches() &&
method.getReturnType().toString().equals( method.getEnclosingElement().asType().toString() );
}
@Override
public String getPropertyName(ExecutableElement getterOrSetterMethod) {
String methodName = getterOrSetterMethod.getSimpleName().toString();
if ( methodName.startsWith( "is" ) || methodName.startsWith( "get" ) || methodName.startsWith( "set" ) ) {
return Introspector.decapitalize( methodName.substring( methodName.startsWith( "is" ) ? 2 : 3 ) );
}
else if ( isBuilderSetter( getterOrSetterMethod ) ) {
return methodName;
}
return Introspector.decapitalize( methodName.substring( methodName.startsWith( "is" ) ? 2 : 3 ) );
}
}
注:这对流利的接受者有效,你需要做一些额外的事情来让它对流利的接受者有效。基于返回类型的meethod.getEnclosuringElement()
,您需要获取属性的访问器
注释检查并返回方法的名称,否则需要使用默认值
免责声明:我是MapStruct团队的成员之一您需要手动指定mappings@DarrenForsythe请详细说明一下。手动,你的意思是,我必须写一个方法来来回转换对象吗?事实上,刚刚发现Mapstruct可以处理你的确切示例,文档说它可以,但它不能。我也有同样的问题,但我一直无法解决。我也需要帮助。我没有时间实现这一点,因为我陷入了另一个问题(),现在我正在重新考虑是否应该使用mapstruct,因为它给我带来了Lombok方面的困难,我肯定会检查这一点,并标记为正确,如果这一点有效。mapstruct与Lombok一起工作,您需要检查您的设置是否正确。如果使用的是
annotationProcessorPaths
,则需要在其中同时指定MapStruct和Lombok。确保您使用的是两个框架的最新版本和maven编译器插件的最新版本
public class FluentAccessorNamingStrategy extends DefaultAccessorNamingStrategy {
@Override
public boolean isSetterMethod(ExecutableElement method) {
String methodName = method.getSimpleName().toString();
return methodName.startsWith( "set" ) && methodName.length() > 3 || isBuilderSetter( method );
}
protected boolean isBuilderSetter(ExecutableElement method) {
return method.getParameters().size() == 1 &&
!JAVA_JAVAX_PACKAGE.matcher( method.getEnclosingElement().asType().toString() ).matches() &&
method.getReturnType().toString().equals( method.getEnclosingElement().asType().toString() );
}
@Override
public String getPropertyName(ExecutableElement getterOrSetterMethod) {
String methodName = getterOrSetterMethod.getSimpleName().toString();
if ( methodName.startsWith( "is" ) || methodName.startsWith( "get" ) || methodName.startsWith( "set" ) ) {
return Introspector.decapitalize( methodName.substring( methodName.startsWith( "is" ) ? 2 : 3 ) );
}
else if ( isBuilderSetter( getterOrSetterMethod ) ) {
return methodName;
}
return Introspector.decapitalize( methodName.substring( methodName.startsWith( "is" ) ? 2 : 3 ) );
}
}