使用 MapStruct 将 2 个字符串字段映射到 OffsetDateTime
Mapping 2 String fields to OffsetDateTime with MapStruct
我有以下 DTO,其中有 2 个字段必须转换为 OffsetDateTime:
@Data
public class AppointmentDTO {
private String id;
@NotNull
private String startTime;
@NotNull
private String endTime;
@NotNull
private String timeZoneStart;
@NotNull
private String timeZoneEnd;
// other fields
}
至
@Data
@Document
@NoArgsConstructor
@AllArgsConstructor
public class Appointment {
@Id
private String id;
private String timeZoneStart;
private String timeZoneEnd;
private OffsetDateTime startTime;
private OffsetDateTime endTime;
private OffsetDateTime createdTime;
// other fields
}
为了转换,我需要 DTO 的 timeZone
字段加上一个 DateTimeFormatter
。所以,我的尝试是这样的:
@Component
@Mapper(componentModel = "spring")
public interface IAppointmentMapper {
@Mapping(target = "createdTime", ignore = true)
Appointment convertAppointmentDTOToAppointment(AppointmentDTO dto, @Context OffsetDateTimeMapper offsetDateTimeMapper);
}
public class OffsetDateTimeMapper {
private String startTime;
private String endTime;
private String timeZoneStart;
private String timeZoneEnd;
private final DateTimeFormatter dateTimeFormatter;
public OffsetDateTimeMapper(DateTimeFormatter dateTimeFormatter) {
this.dateTimeFormatter = dateTimeFormatter;
}
@BeforeMapping
public void beforeStartTimeMapping(AppointmentDTO dto) {
this.startTime = dto.getStartTime();
this.timeZoneStart = dto.getTimeZoneStart();
}
@BeforeMapping
public void beforeEndTimeMapping(AppointmentDTO dto) {
this.endTime = dto.getEndTime();
this.timeZoneEnd = dto.getTimeZoneEnd();
}
@AfterMapping
public void startTimeMap(@MappingTarget Appointment appointment) {
LocalDateTime localDateTime = LocalDateTime.parse(startTime, dateTimeFormatter);
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of(timeZoneStart));
appointment.setStartTime(zonedDateTime.toOffsetDateTime());
}
@AfterMapping
public void endTimeMap(@MappingTarget Appointment appointment) {
LocalDateTime localDateTime = LocalDateTime.parse(endTime, dateTimeFormatter);
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of(timeZoneEnd));
appointment.setEndTime(zonedDateTime.toOffsetDateTime());
}
}
但是,当我构建时,出现以下错误:Error:(22,17) java: Can't map property "java.lang.String startTime" to "java.time.OffsetDateTime startTime". Consider to declare/implement a mapping method: "java.time.OffsetDateTime map(java.lang.String value)".
如果我在界面上放置一个 default map()
方法,我不会收到错误,但我没有需要正确的 @Context
。
/*default OffsetDateTime map(String value) {
LocalDateTime localDateTime = LocalDateTime.parse(value);
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneOffset.UTC);
return zonedDateTime.toOffsetDateTime();
}*/
你的方法很有趣。为了正常工作,您必须明确忽略不希望 MapStruct 自动映射的属性。
在这种情况下添加:
@Mapping(target = "startTime", ignore = true)
@Mapping(target = "endTime", ignore = true)
但是,在您的情况下,我会尝试使用 Mapping method selection based on qualifiers 并将源参数用作源。
所以像这样:
@Component
@Mapper(componentModel = "spring")
public interface IAppointmentMapper {
@Mapping(target = "createdTime", ignore = true)
@Mapping(target = "startTime", source = "dto", qualifiedByName = "startTime")
@Mapping(target = "endTime", source = "dto", qualifiedByName = "endTime")
Appointment convertAppointmentDTOToAppointment(AppointmentDTO dto, @Context DateTimeFormatter dateTimeFormatter);
@Named("startTime")
default OffsetDateTime mapStartTime(AppointmentDTO dto, @Context DateTimeFormatter dateTimeFormatter) {
LocalDateTime localDateTime = LocalDateTime.parse(dto.getStartTime(), dateTimeFormatter);
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of(dto. getTimeZoneStart()));
return zonedDateTime.toOffsetDateTime()
}
@Named("endTime")
default OffsetDateTime mapEndTime(AppointmentDTO dto, @Context DateTimeFormatter dateTimeFormatter) {
LocalDateTime localDateTime = LocalDateTime.parse(dto.getEndTime(), dateTimeFormatter);
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of(dto. getTimeZoneEnd()));
return zonedDateTime.toOffsetDateTime()
}
}
注意:@Named
是 org.mapstruct.Named
。
我有以下 DTO,其中有 2 个字段必须转换为 OffsetDateTime:
@Data
public class AppointmentDTO {
private String id;
@NotNull
private String startTime;
@NotNull
private String endTime;
@NotNull
private String timeZoneStart;
@NotNull
private String timeZoneEnd;
// other fields
}
至
@Data
@Document
@NoArgsConstructor
@AllArgsConstructor
public class Appointment {
@Id
private String id;
private String timeZoneStart;
private String timeZoneEnd;
private OffsetDateTime startTime;
private OffsetDateTime endTime;
private OffsetDateTime createdTime;
// other fields
}
为了转换,我需要 DTO 的 timeZone
字段加上一个 DateTimeFormatter
。所以,我的尝试是这样的:
@Component
@Mapper(componentModel = "spring")
public interface IAppointmentMapper {
@Mapping(target = "createdTime", ignore = true)
Appointment convertAppointmentDTOToAppointment(AppointmentDTO dto, @Context OffsetDateTimeMapper offsetDateTimeMapper);
}
public class OffsetDateTimeMapper {
private String startTime;
private String endTime;
private String timeZoneStart;
private String timeZoneEnd;
private final DateTimeFormatter dateTimeFormatter;
public OffsetDateTimeMapper(DateTimeFormatter dateTimeFormatter) {
this.dateTimeFormatter = dateTimeFormatter;
}
@BeforeMapping
public void beforeStartTimeMapping(AppointmentDTO dto) {
this.startTime = dto.getStartTime();
this.timeZoneStart = dto.getTimeZoneStart();
}
@BeforeMapping
public void beforeEndTimeMapping(AppointmentDTO dto) {
this.endTime = dto.getEndTime();
this.timeZoneEnd = dto.getTimeZoneEnd();
}
@AfterMapping
public void startTimeMap(@MappingTarget Appointment appointment) {
LocalDateTime localDateTime = LocalDateTime.parse(startTime, dateTimeFormatter);
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of(timeZoneStart));
appointment.setStartTime(zonedDateTime.toOffsetDateTime());
}
@AfterMapping
public void endTimeMap(@MappingTarget Appointment appointment) {
LocalDateTime localDateTime = LocalDateTime.parse(endTime, dateTimeFormatter);
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of(timeZoneEnd));
appointment.setEndTime(zonedDateTime.toOffsetDateTime());
}
}
但是,当我构建时,出现以下错误:Error:(22,17) java: Can't map property "java.lang.String startTime" to "java.time.OffsetDateTime startTime". Consider to declare/implement a mapping method: "java.time.OffsetDateTime map(java.lang.String value)".
如果我在界面上放置一个 default map()
方法,我不会收到错误,但我没有需要正确的 @Context
。
/*default OffsetDateTime map(String value) {
LocalDateTime localDateTime = LocalDateTime.parse(value);
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneOffset.UTC);
return zonedDateTime.toOffsetDateTime();
}*/
你的方法很有趣。为了正常工作,您必须明确忽略不希望 MapStruct 自动映射的属性。
在这种情况下添加:
@Mapping(target = "startTime", ignore = true)
@Mapping(target = "endTime", ignore = true)
但是,在您的情况下,我会尝试使用 Mapping method selection based on qualifiers 并将源参数用作源。
所以像这样:
@Component
@Mapper(componentModel = "spring")
public interface IAppointmentMapper {
@Mapping(target = "createdTime", ignore = true)
@Mapping(target = "startTime", source = "dto", qualifiedByName = "startTime")
@Mapping(target = "endTime", source = "dto", qualifiedByName = "endTime")
Appointment convertAppointmentDTOToAppointment(AppointmentDTO dto, @Context DateTimeFormatter dateTimeFormatter);
@Named("startTime")
default OffsetDateTime mapStartTime(AppointmentDTO dto, @Context DateTimeFormatter dateTimeFormatter) {
LocalDateTime localDateTime = LocalDateTime.parse(dto.getStartTime(), dateTimeFormatter);
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of(dto. getTimeZoneStart()));
return zonedDateTime.toOffsetDateTime()
}
@Named("endTime")
default OffsetDateTime mapEndTime(AppointmentDTO dto, @Context DateTimeFormatter dateTimeFormatter) {
LocalDateTime localDateTime = LocalDateTime.parse(dto.getEndTime(), dateTimeFormatter);
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of(dto. getTimeZoneEnd()));
return zonedDateTime.toOffsetDateTime()
}
}
注意:@Named
是 org.mapstruct.Named
。