首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用MapStruct将2个字符串字段映射到OffsetDateTime

使用MapStruct将2个字符串字段映射到OffsetDateTime
EN

Stack Overflow用户
提问于 2020-01-07 01:44:47
回答 1查看 3.4K关注 0票数 1

我有下面的DTO,其中有2个字段,必须转换为OffsetDateTime:

代码语言:javascript
运行
复制
@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
} 

代码语言:javascript
运行
复制
@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。所以,我的尝试是:

代码语言:javascript
运行
复制
@Component
@Mapper(componentModel = "spring")
public interface IAppointmentMapper {

    @Mapping(target = "createdTime", ignore = true)
    Appointment convertAppointmentDTOToAppointment(AppointmentDTO dto, @Context OffsetDateTimeMapper offsetDateTimeMapper);
}
代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
/*default OffsetDateTime map(String value) {
     LocalDateTime localDateTime = LocalDateTime.parse(value);
     ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneOffset.UTC);
     return zonedDateTime.toOffsetDateTime();
}*/
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-15 03:03:30

你的方法很有趣。为了正常工作,您必须显式地忽略您不希望MapStruct自动映射的属性。

在这种情况下,添加:

代码语言:javascript
运行
复制
@Mapping(target = "startTime", ignore = true)
@Mapping(target = "endTime", ignore = true)

但是,在您的示例中,我会尝试使用Mapping method selection based on qualifiers,并使用源参数作为源。

所以就像这样:

代码语言:javascript
运行
复制
@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()
    }
}

注:@Namedorg.mapstruct.Named

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59616631

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档