基于Groovy+Gradle的SpringBoot应用运行报错,求解决方案
我之前在做Groovy结合SpringBoot的项目时,也碰到过一模一样的Dozer映射报错,核心原因就是Dozer试图处理Groovy对象自带的metaClass特殊属性,但这个属性并不是我们需要映射的业务字段,而且Dozer识别不了它的访问方法。咱们一步步来解决:
首先先明确报错的核心信息:
16:18:37.215 [http-nio-9092-exec-5] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'org.dozer.MappingE...
嵌套异常:org.dozer.MappingException: No read or write method found for field (metaClass) in class
解决方法:
排除
metaClass字段的映射
这是最直接的解决方案,告诉Dozer不要处理这个字段。- 如果用XML配置映射:在对应的
<mapping>标签里添加排除规则:<mapping> <class-a>com.yourpackage.YourGroovyClass</class-a> <class-b>com.yourpackage.TargetClass</class-b> <exclude field="metaClass"/> </mapping> - 如果用注解方式(比如
@Mapper):在Groovy类或者对应的字段上添加排除注解,如果是Dozer的注解,可以用@Mapping(exclude = true)标记metaClass,或者在类级别配置全局排除该字段。
- 如果用XML配置映射:在对应的
全局配置忽略Groovy特殊字段
要是你的项目里有很多Groovy类需要映射,一个个加排除太麻烦,可以在Dozer的全局配置里设置忽略这些Groovy自带的特殊字段:<configuration> <exclude-null>true</exclude-null> <global-exclude field="metaClass"/> <global-exclude field="class"/> </configuration>这样所有映射都会自动跳过
metaClass和class这类不需要的字段。升级Dozer版本
有些旧版本的Dozer对Groovy的支持不够完善,可能会错误地尝试映射这些特殊属性。你可以在Gradle的build.gradle里升级Dozer的依赖到较新的稳定版本(比如6.5.0及以上,注意和你的SpringBoot版本兼容):dependencies { implementation 'net.sf.dozer:dozer:6.5.0' // 或者如果用Spring整合的版本: // implementation 'org.springframework.boot:spring-boot-starter-dozer' }确认Groovy类的属性访问权限
虽然这个问题主要是metaClass的锅,但也可以顺便检查下你的Groovy业务字段是否都有正确的getter/setter——不过Groovy默认会给非final字段生成这些方法,所以大概率不是这个问题,但排查的时候可以确认下。
总结
最快速的解决方式就是在Dozer配置里排除metaClass字段,全局配置一劳永逸,升级版本则能避免更多类似的Groovy兼容问题。
内容的提问来源于stack exchange,提问作者SpaceNet

