在带有 Rest Controller 的 Spring Boot 应用程序中使用 Mapstruct 和 lombok 将域 class 映射到 DTO class

Map domain class to DTO class using Mapstruct and lombok in SpringBoot application with RestController

下面是我的主要应用class。

@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan("com.example.demo")
public class Demo1Application {

    public static void main(String[] args) {
        SpringApplication.run(Demo1Application.class, args);
    }

}

控制器Class.

@RestController
public class JobAppController {
    
    @Autowired
    JobApplicationRepository jobApplicationRepository;
    
    //@Autowired
    //private JobApplicationMapper mapper;
    
    JobApplicationMapper mapper = Mappers.getMapper(JobApplicationMapper.class);
    
    @GetMapping("/hello")
    public String greeting()
    {
        return "hello Mr";
    }
    
    @PostMapping("/save")
    public JobApplicationDto save(@RequestBody JobApplicationDto jobApplicationDto)
    {
        JobApplication jobApplication = mapper.toEntity(jobApplicationDto);
        jobApplication = jobApplicationRepository.save(jobApplication);
        return mapper.ToDTO(jobApplication);
        
    }

}

映射器接口。

@Mapper
@Component
public interface JobApplicationMapper {

    //JobApplicationMapper mapper = Mappers.getMapper(JobApplicationMapper.class);
    //({ @Mapping(target="employeeId", source="entity.id"),@Mapping(target="employeeName", source="entity.name")})
    
    JobApplicationDto  ToDTO(JobApplication jobApplication);
    JobApplication toEntity(JobApplicationDto jobApplicationDto);
}

我的 pom 文件。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.jobSearch</groupId>
    <artifactId>demo-1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo-1</name>
    <description>Demo project for Spring Boot/JobSearch</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
    <!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct -->
        <dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-jdk8</artifactId>
    <version>1.3.0.Final</version>
       </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
     <groupId>org.apache.commons</groupId>
     <artifactId>commons-lang3</artifactId>
     <version>3.3.2</version>
     <type>jar</type>
</dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.5.1</version>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <annotationProcessorPaths>
            <path>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>1.3.0.Beta2</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>
        </plugins>
    </build>

</project>

域名class.

    @Entity
    @Table(name = "Job_Application")
    //@Data
    //@AllArgsConstructor
    //@NoArgsConstructor
    public class JobApplication {
        
        
        
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Id()
        private Integer id;
    
        @Column(name = "requisition_id")
        private String requisition_id;
    
        @Column(name = "job_posting_source")
        private String job_posting_source;
    
        @Column(name = "applied_date")
        private Date applied_date;
    
        @Column(name = "company")
        private String company;
    
        @Column(name = "current_status")
        private String current_status;
    
        @Column(name = "position")
        private String position;
    
        @Column(name = "location")
        private String location;
//getters and setters follows...

dto class.

    /*@Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder*/
    public class JobApplicationDto {
        
        private Integer id;
        private String requisition_id;
        private String job_posting_source;
        private Date applied_date;
        private String company;
        private String current_status;
        private String position;
        private String location;
//getters and setters follows

当尝试通过 postman post data/dto(如 JSON)到我的数据库 table 时,数据被插入为空值

{
  "requisition_id" : "1234",
  "job_posting_source" : "indeed",
  "applied_date" : "2020-08-15",
  "company" : "softInc",
  "current_status" : "under review",
  "position" : "SE3",
  "location" : "Himalayas"
}

插入后的响应是这样

{
    "id": null,
    "requisition_id": null,
    "job_posting_source": null,
    "applied_date": null,
    "company": null,
    "current_status": null,
    "position": null,
    "location": null
}

没有错误信息。不知道我错过了什么。 彻底调试后,我意识到映射器实现没有问题。但是,由于我对域和 dto classes 使用“lombok”,因此没有生成 getter 和 setter。所以我现在在代码中手动添加它们并按预期工作。

PS:我认为自己是初学者,所以欢迎任何类型的discussion/suggestions。

我现在要编辑这个问题,因为问题出在 lombok 上,为什么没有生成 getters/setters。

我想 Lombok 缺少注释处理器..

尝试:

<annotationProcessorPaths>
    <path>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>${org.mapstruct.version}</version>
    </path>
    <path>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${org.projectlombok.version}</version>
    </path>
</annotationProcessorPaths>

查看 this 以获取工作示例。

请注意:Lombok/MapStruct 存在多个问题。两者都是注解处理器。 Lombok 生成 getters / setters,MapStruct 使用它们。时机是必不可少的。因此,MapStruct 引入了一个 SPI 来表示生成准备就绪。