Spring Boot+MongoDB项目出现ObjectMapper转UserService类型转换异常求助
问题分析:Spring Boot中ObjectMapper转UserService的类型转换异常
错误日志
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userController' Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.pypek.testtaskapi.controller.UserController]: Constructor threw exception Caused by: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'com.fasterxml.jackson.databind.ObjectMapper@5f4d427e' with class 'com.fasterxml.jackson.databind.ObjectMapper' to class 'com.pypek.testtaskapi.service.UserService' ...(错误栈省略)
相关代码
UserController(Groovy)
package com.pypek.testtaskapi.controller import com.pypek.testtaskapi.model.User import com.pypek.testtaskapi.service.UserService import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.DeleteMapping import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PatchMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController @RestController @RequestMapping("/user") class UserController { @Autowired UserService service UserController(UserService service) { this.service = service } @GetMapping("/{id}") def getUser(@PathVariable String id) { return service.getUser(id) } @PatchMapping def updateUser(@RequestBody User user){ service.updateUser(user) } @PostMapping def addUser(@RequestBody User user){ service.addUser(user) } @DeleteMapping("/{id}") def deleteUser(@PathVariable String id){ service.deleteUser(id) } }
UserService(Groovy)
package com.pypek.testtaskapi.service import com.pypek.testtaskapi.exceptions.UserNotFoundExceptions import com.pypek.testtaskapi.model.User import com.pypek.testtaskapi.repository.UserRepository import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service @Service class UserService { UserRepository repository @Autowired UserService(UserRepository repository) { this.repository = repository } def getUser(String id) { return repository.findById(id).orElseThrow(() -> new UserNotFoundExceptions(id)) } String addUser(User user) { return repository.save(user).getId() } def updateUser(User user) { def id = user.getId() if (checkIfUserExist(id)){ return repository.save(user) } else throw new UserNotFoundExceptions(id) } def deleteUser(String id) { if (checkIfUserExist(id)) { repository.deleteById(id) } else throw new UserNotFoundExceptions(id) } def checkIfUserExist(String id) { return repository.existsById(id) } }
问题原因
你在UserController中同时使用了字段注入(@Autowired标注在service字段上)和构造函数注入(手动编写接收UserService参数的构造函数),在Groovy环境下,Spring的依赖注入解析逻辑出现混淆:
- 当类存在自定义构造函数时,Spring会优先尝试构造函数注入;
- 但字段上的
@Autowired注解干扰了Spring的依赖匹配逻辑,导致Spring错误地将上下文存在的ObjectMapperBean尝试注入到构造函数中,最终引发类型转换异常。
解决方法
只需保留一种注入方式即可,推荐使用构造函数注入(更符合依赖注入最佳实践,便于测试和依赖明确):
方案一:保留构造函数注入,移除字段上的@Autowired
修改后的UserController代码:
package com.pypek.testtaskapi.controller import com.pypek.testtaskapi.model.User import com.pypek.testtaskapi.service.UserService import org.springframework.web.bind.annotation.DeleteMapping import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PatchMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController @RestController @RequestMapping("/user") class UserController { final UserService service UserController(UserService service) { this.service = service } @GetMapping("/{id}") def getUser(@PathVariable String id) { return service.getUser(id) } @PatchMapping def updateUser(@RequestBody User user){ service.updateUser(user) } @PostMapping def addUser(@RequestBody User user){ service.addUser(user) } @DeleteMapping("/{id}") def deleteUser(@PathVariable String id){ service.deleteUser(id) } }
方案二:保留字段注入,移除自定义构造函数
修改后的UserController代码:
package com.pypek.testtaskapi.controller import com.pypek.testtaskapi.model.User import com.pypek.testtaskapi.service.UserService import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.DeleteMapping import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PatchMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController @RestController @RequestMapping("/user") class UserController { @Autowired UserService service @GetMapping("/{id}") def getUser(@PathVariable String id) { return service.getUser(id) } @PatchMapping def updateUser(@RequestBody User user){ service.updateUser(user) } @PostMapping def addUser(@RequestBody User user){ service.addUser(user) } @DeleteMapping("/{id}") def deleteUser(@PathVariable String id){ service.deleteUser(id) } }
内容的提问来源于stack exchange,提问作者Olexie Polishchyk
相关产品推荐
相关产品推荐

