我正在使用 Mapstruct 并且需要使用 更新现有 bean @MappingTarget,但需要应用一些复杂的逻辑来在目标中设置正确的字段。
假设我有一个如下所示的目标 bean。用户有一个帐户列表,其中一个帐户被标记为最喜欢的。
UserDetails {
String name;
List<Account> accounts;
}
Account {
String id;
boolean favourite;
}
Run Code Online (Sandbox Code Playgroud)
DTO 类包含他们最喜欢的帐户的帐户 ID。
UserDetialsDTO {
String name;
String favouriteAccountId;
List<String> accountIds;
}
Run Code Online (Sandbox Code Playgroud)
我需要使用一些复杂的逻辑来更新Account帐户列表中的正确内容。
UserDetails fromDto(UserDetialsDTO dto, @MappingTarget UserDetails userDetails);
Run Code Online (Sandbox Code Playgroud)
查找并更新正确的内容Account以使其成为最爱的逻辑如下:
userDetails.accounts
.stream()
.forEach(acct -> acct.setFavourite(dto.favouriteAccountId.equals(acct.id))) ;
Run Code Online (Sandbox Code Playgroud)
我如何告诉 Mapstruct 在更新 a 时使用此自定义逻辑@MapingTarget?
defaultValue使用 MapStruct 映射 DTO 时如何指定 a ?以下构造不起作用
@Mapping(target = "used", defaultValue = "0")
MyDTO toDto(MyEntity entity);
@Mapping(target = "used", defaultValue = "false")
MyDTO toDto(MyEntity entity);
Run Code Online (Sandbox Code Playgroud)
该文档显示了除布尔值以外的所有类型的示例
我正在使用 MapStruct 将值从源映射到目标类。源类有一个 String 属性,目标类有一个 java.util.Date 属性。源属性是这样的:“yyyy-mm-dd”。我想将此 String 属性转换为 Date 属性。我如何使用 MapStruct 做到这一点?谢谢!
我试图弄清楚如何实现以下映射:
class SuperComplexClass {
Long value;
String description;
}
class MapIntoMe {
// Many other fields that is also mapped
SuperComplexClass superComplexObject;
}
class MapFromMe {
ComplexClassPart1 complexClassPart;
}
class AdditionalData {
ComplexClassPart2 complexClassPart;
}
@Mapper
public interface SomeFancyMapper {
@Mapping(target = "superComplexObject", source = "{mfm.complexPart, ad.complexPart}",
qualifiedByName = "mapSuperComplexObject")
MapIntoMe mapFromMeIntoMe(MapFromMe mfm, AdditionalData ad);
@Named("mapSuperComplexObject")
default SuperComplexClass mapSuperComplexObject(ComplexPart1 p1, ComplexPart2 p2) {
SuperComplexClass superObject = new SuperComplexClass();
//some logic that calculates and fills superObject]
return superObject;
}
}
Run Code Online (Sandbox Code Playgroud)
现在显然这样的表达 …
我在更新实体的服务中有一个方法。它接受具有更新实体的数据的对象。Dto 对象的字段比实体少,但字段具有相同的名称。
通过传递现有的目标对象,是否可以将 mapstruct 用于该例行工作?
class Entity {
id
name
date
country
by
... //hell of the fields
}
class UpdateEntity {
name
country
... //less but still a lot
}
class EntityService {
update(UpdateEntity u) {
Entity e = // get from storage
mapstructMapper.mapFromTo(u, e)
}
}
Run Code Online (Sandbox Code Playgroud) 我一起使用 mapstruct 和 lombok 并遇到了一些问题:
EntityMapper.java:10: error: Unknown property "id" in result type Entity. Did you mean "null"?
@Mapping(target = "id", ignore = true)
^
Run Code Online (Sandbox Code Playgroud)
我的 Entity 和 EntityDto 类:
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Entity {
private int id;
private String property;
}
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class EntityDto {
private String property;
}
Run Code Online (Sandbox Code Playgroud)
实体映射器:
@Mapper(implementationName = "MapStruct<CLASS_NAME>")
public interface EntityMapper {
// neither of them work
@Mapping(target = "id", ignore = true)
//@Mapping(target = "id", defaultValue …Run Code Online (Sandbox Code Playgroud) 我正在使用高于 2.2.5 和 Java 15、lombok、Mapstruct 的最新版本的 Spring boot 来映射一些 pojo。
使用spring boot 2.2.5 版时,我得到了预期的结果:
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2021-01-02T21:59:24+0100",
comments = "version: 1.4.1.Final, compiler: javac, environment: Java 15.0.1 (Oracle Corporation)"
)
@Component
public class ProduitMapperImpl implements ProduitMapper {
@Override
public ProduitDtoResponse produitToProduitDtoResponse(Produit produit) {
if ( produit == null ) {
return null;
}
ProduitDtoResponseBuilder produitDtoResponse = ProduitDtoResponse.builder();
produitDtoResponse.id( produit.getId() );
produitDtoResponse.nom( produit.getNom() );
produitDtoResponse.prix( produit.getPrix() );
return produitDtoResponse.build();
}
@Override
public Produit produitToProduitDtoResponse(ProduitDtoResponse produitDto) { …Run Code Online (Sandbox Code Playgroud) 我有这些豆子:
public class Company {
private String name;
private List<Address> addresses;
...some other fields...
}
public class Address {
private String street;
private String city;
private boolean deleted;
...some other fields...
}
Run Code Online (Sandbox Code Playgroud)
我还有一些用于这些豆子的 DTO
public class CompanyDto {
private String name;
private List<AddressDto> addresses;
...some other fields...
}
public class AddressDto {
private String street;
private String city;
...some other fields...
}
Run Code Online (Sandbox Code Playgroud)
(请注意,AddressDto 类缺少该deleted字段)
我正在使用 Mapstruct 将这些 bean 映射到它们的 DTO。映射器是这样的:
@Mapper
public interface CompanyMapper {
CompanyDto companyToCompanyDto(Company company); …Run Code Online (Sandbox Code Playgroud) 我对Java了解不多,但我认为它应该足以管理这个小任务......
我正在构建一个微服务,它通过多个休息端点提供歌曲和歌曲列表。但它不仅仅在调用时返回歌曲,它还必须联系另一个服务并使用附加信息增强歌曲对象。为此,我实现了一个 Dto-Class,并使用 mapstruct 来处理后面的逻辑。我在其他项目中也这样做过,没有任何问题。但现在我很挣扎,因为这个错误,我不知道如何解决 - 它说:
mk.microservices.songsservice.services.SongServiceImpl 中的构造函数的参数 1 需要类型为“mk.microservices.songsservice.web.mapper.SongMapper”的 bean,但无法找到。
行动:
考虑在配置中定义“mk.microservices.songsservice.web.mapper.SongMapper”类型的 bean。
以下是我的代码的摘录:
歌曲服务实现
import lombok.RequiredArgsConstructor;
import mk.microservices.songsservice.domain.Song;
import mk.microservices.songsservice.repositories.SongRepository;
import mk.microservices.songsservice.web.mapper.SongMapper;
import mk.microservices.songsservice.web.model.SongDto;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@RequiredArgsConstructor
@Service
public class SongServiceImpl implements SongService {
private final SongRepository songRepository;
private final SongMapper songMapper;
@Override
public SongDto getSongById(Integer id) {
return songMapper.songToSongDto(songRepository.findById(id));
}
@Override
public List<Song> getAllSongs() {
return songRepository.findAll();
}
....
}
Run Code Online (Sandbox Code Playgroud)
歌曲映射器
import org.mapstruct.DecoratedWith;
import java.util.Optional;
@MapStruct
@DecoratedWith(SongMapperDecorator.class)
public interface SongMapper {
SongDto …Run Code Online (Sandbox Code Playgroud) 使用 Idea 进行 mvn 编译工作正常。
在 App.main 启动期间失败。
在 Ubuntu 上的其他 PC 上的旧 Idea 上运行良好。
环境:
Intellij 2020.3.2 作为管理员;
Java 15.02;
视窗 10 x64;
最新的地图结构。
如何解决这个问题?
D:\back\src\main\java\io\x\mapper\Mapper.java:15:8 java: Internal error in the mapping processor: java.lang.NullPointerException: Cannot invoke "java.net.URL.toExternalForm()" because "resource" is null
at org.mapstruct.ap.internal.processor.DefaultVersionInformation.createManifestUrl(DefaultVersionInformation.java:182)
at org.mapstruct.ap.internal.processor.DefaultVersionInformation.openManifest(DefaultVersionInformation.java:153)
at org.mapstruct.ap.internal.processor.DefaultVersionInformation.getLibraryName(DefaultVersionInformation.java:129)
at org.mapstruct.ap.internal.processor.DefaultVersionInformation.getCompiler(DefaultVersionInformation.java:122)
at org.mapstruct.ap.internal.processor.DefaultVersionInformation.fromProcessingEnvironment(DefaultVersionInformation.java:95)
at org.mapstruct.ap.internal.processor.DefaultModelElementProcessorContext.<init>(DefaultModelElementProcessorContext.java:50)
at org.mapstruct.ap.MappingProcessor.processMapperElements(MappingProcessor.java:218)
at org.mapstruct.ap.MappingProcessor.process(MappingProcessor.java:156)
at jdk.internal.reflect.GeneratedMethodAccessor207.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.jetbrains.jps.javac.APIWrappers$1.invoke(APIWrappers.java:248)
at lombok.launch.AnnotationProcessorHider$AnnotationProcessor.process(Unknown Source)
at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:1025)
at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:940)
at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1269)
at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1383)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1261) …Run Code Online (Sandbox Code Playgroud)