• spring boot 之使用mapstruct


      最近在阅读swagger源码,当看到 springfox.documentation.swagger2.mappers.ModelMapper 类时,无意中看到该类上面使用的 org.mapstruct.Mapper 注解时,对这个注解一时竟想不出个所意然来。便打开百度搜索了一番,有关这个注解的文章不是很多,从这些文章中了解到,这个注解跟JSR 269 有关,下面列出这个注解相关的文章链接。


     相关的文章链接:

    1.  mapstruct官网 http://mapstruct.org/
    2.  mapstruct github网址:https://github.com/mapstruct/mapstruct
    3. JSR 269: Pluggable Annotation Processing API  https://jcp.org/en/jsr/detail?id=269
    4. 插入式注解处理API(Pluggable Annotation Processing API)  https://blog.csdn.net/yczz/article/details/34116189
    5. MapStruct实体间转换快速入门  https://blog.csdn.net/lx_yoyo/article/details/75061614

      当看完上面的几篇的文章之后,对这个注解到底起何作用,仍然是一知半解。于是参照上面列表中的 MapStruct实体间转换快速入门 ,当我把工程建好,copy完相关的代码之后,根据文章的提示,执行mvn install(mvn compile)命令之后,没有出现文章中提到的在 targetgenerated-sourcesannotations 会自动生成PeopleMapperImpl.Java 源文件,反到是控制台打印出的日志信息提示编译失败,错误信息如下所示:

     

    [INFO] -------------------------------------------------------------
    [ERROR] COMPILATION ERROR : 
    [INFO] -------------------------------------------------------------
    [ERROR] /F:/java.ws.01/springboot-example/example4/src/main/java/com/github/torlight/sbex/PeopleMapper.java:[21,15] No property named "age" exists in source parameter(s). Did you mean "null"?
    [ERROR] /F:/java.ws.01/springboot-example/example4/src/main/java/com/github/torlight/sbex/PeopleMapper.java:[32,10] No property named "user.name" exists in source parameter(s). Did you mean "null"?
    [INFO] 2 errors 
    [INFO] -------------------------------------------------------------
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD FAILURE
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 5.951 s
    [INFO] Finished at: 2018-08-19T10:52:59+08:00
    [INFO] Final Memory: 26M/282M
    [INFO] ------------------------------------------------------------------------
    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile (default-compile) on project example4: Compilation failure: Compilation failure:
    [ERROR] /F:/java.ws.01/springboot-example/example4/src/main/java/com/github/torlight/sbex/PeopleMapper.java:[21,15] No property named "age" exists in source parameter(s). Did you mean "null"?
    [ERROR] /F:/java.ws.01/springboot-example/example4/src/main/java/com/github/torlight/sbex/PeopleMapper.java:[32,10] No property named "user.name" exists in source parameter(s). Did you mean "null"?
    [ERROR] -> [Help 1]
    org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile (default-compile) on project example4: Compilation failure
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:212)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:862)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:286)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:197)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
    Caused by: org.apache.maven.plugin.compiler.CompilationFailureException: Compilation failure
        at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:972)
        at org.apache.maven.plugin.compiler.CompilerMojo.execute(CompilerMojo.java:129)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
        ... 20 more
    [ERROR] 
    [ERROR] 
    [ERROR] For more information about the errors and possible solutions, please read the following articles:
    [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

     

      当出现上面的错误之后,先是在网上找了一下,但没有找到相关的资料,没办法只能靠自己解决了。查看工程的pom.xml文件,有用到maven-compiler-plugin 插件,看到该插件的配置项中mapstruct-processor ,心里也清楚当maven执行maven-compiler-plugin 插件中相关类的方法时,肯定会执行mapstruct-processor 中相关类的方法。可是不清楚具体会先从那个类的方法开始执行。

      没办法,只能根据上面的异常提示信息,在maven源码工程中一路跟踪下来,发现错误源是当执行SourceReference类的getSourceEntries方法时触发的。No property named "age" exists in source parameter(s). Did you mean "null"?  在被转换的实体中找不到age属性,可是在PeopleEntity 实体中本来就存在age属性。原来报错是因为getSourceEntries方法是通过反射读取实体的get方法来获取属性,然后再进行属性比较,怪不得会报错。当找到报错的原因之后,我把目光停留在源码中的注释 //constructor, getters, setters etc.  来实体中的getter,setter 方法都被省略了。

     1 package com.github.torlight.sbex;
     2 
     3 public class PeopleEntity {
     4     private Integer age;
     5     private String name;
     6     private String callNumber;
     7     private String address;
     8     private String email;
     9     
    10     public PeopleEntity() {
    11         
    12     }
    13 
    14     public PeopleEntity(Integer age, String name, String callNumber, String address, String email) {
    15         this.age = age;
    16         this.name = name;
    17         this.callNumber = callNumber;
    18         this.address = address;
    19         this.email = email;
    20     }
    21     
    22   //constructor, getters, setters etc.
    23 
    24 }

     


     修改之后的代码:

     1 package com.github.torlight.sbex;
     2 
     3 public class PeopleDTO {
     4     
     5     private String phoneNumber;
     6     private String address;
     7     private String email;
     8     private User  user;
     9     
    10     public PeopleDTO() {
    11     
    12     }
    13 
    14     public PeopleDTO(String phoneNumber, String address, String email, User user) {
    15         this.phoneNumber = phoneNumber;
    16         this.address = address;
    17         this.email = email;
    18         this.user = user;
    19     }
    20 
    21     public String getPhoneNumber() {
    22         return phoneNumber;
    23     }
    24 
    25     public void setPhoneNumber(String phoneNumber) {
    26         this.phoneNumber = phoneNumber;
    27     }
    28 
    29     public String getAddress() {
    30         return address;
    31     }
    32 
    33     public void setAddress(String address) {
    34         this.address = address;
    35     }
    36 
    37     public String getEmail() {
    38         return email;
    39     }
    40 
    41     public void setEmail(String email) {
    42         this.email = email;
    43     }
    44 
    45     public User getUser() {
    46         return user;
    47     }
    48 
    49     public void setUser(User user) {
    50         this.user = user;
    51     }
    52     
    53 }
     1 package com.github.torlight.sbex;
     2 
     3 public class PeopleEntity {
     4     private Integer age;
     5     private String name;
     6     private String callNumber;
     7     private String address;
     8     private String email;
     9     
    10     public PeopleEntity() {
    11         
    12     }
    13 
    14     public PeopleEntity(Integer age, String name, String callNumber, String address, String email) {
    15         this.age = age;
    16         this.name = name;
    17         this.callNumber = callNumber;
    18         this.address = address;
    19         this.email = email;
    20     }
    21 
    22     public Integer getAge() {
    23         return age;
    24     }
    25 
    26     public void setAge(Integer age) {
    27         this.age = age;
    28     }
    29 
    30     public String getName() {
    31         return name;
    32     }
    33 
    34     public void setName(String name) {
    35         this.name = name;
    36     }
    37 
    38     public String getCallNumber() {
    39         return callNumber;
    40     }
    41 
    42     public void setCallNumber(String callNumber) {
    43         this.callNumber = callNumber;
    44     }
    45 
    46     public String getAddress() {
    47         return address;
    48     }
    49 
    50     public void setAddress(String address) {
    51         this.address = address;
    52     }
    53 
    54     public String getEmail() {
    55         return email;
    56     }
    57 
    58     public void setEmail(String email) {
    59         this.email = email;
    60     }
    61 
    62 }   
    package com.github.torlight.sbex;
    
    public class User {
        private Integer age;
        private String name;
        
        public User() {
    
        }
    
        public User(Integer age, String name) {
            this.age = age;
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }

      


      执行mvn install(mvn compile)命令之后,控制台没有提示报错,但在 argetgenerated-sourcesannotations 文件夹下面还是空的,奇怪了? 先执行mvn clean 然后再执行 mvn install(mvn compile)之后,终于出现了PeopleMapperImpl.java 源文件。要确保 targetclass 文件夹下面为空时,执行mvn install(mvn compile)命令才能生成java源文件。


    示例代码: https://github.com/gittorlight/springboot-example/tree/master/example4

  • 相关阅读:
    django学习笔记
    linux安装tree命令
    SecureCRT卡死的问题
    vim常用快捷键记录
    项目经理应具备的9种能力
    regsvr32命令
    通知栏构建和取消的基本认识
    AlertDialog 对话框 5种
    异步任务——AsyncTask的初步认识
    BaseAdapter的使用与优化
  • 原文地址:https://www.cnblogs.com/yql1986/p/9500851.html
Copyright © 2020-2023  润新知