英文:
Consider defining a bean of type 'UserConverter' in your configuration
问题
以下是翻译好的内容:
我不知道我的 Spring Boot 应用程序发生了什么事,但现在由于一个错误,我无法启动它:
***************************
应用程序启动失败
***************************
描述:
webapp.controllers.UserResourceController 中的 userConverter 字段需要找到一个名为 'webapp.converter.UserConverter' 的类型的 bean,但找不到该 bean。
注入点具有以下注解:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
操作:
请考虑在您的配置中定义一个类型为 'webapp.converter.UserConverter' 的 bean。
进程以退出代码 1 完成
控制器代码:
@RestController
@RequestMapping("/api/user")
public class UserResourceController {
@Autowired
private UserServiceImpl userService;
@Autowired
private UserConverter userConverter;
@PostMapping
public ResponseEntity<UserDto> addUser(@RequestBody UserDto userDto) {
userService.persist(userConverter.toUser(userDto));
return ResponseEntity.ok().body(userDto);
}
@GetMapping
public ResponseEntity<List<UserDto>> findAllUsers() {
return ResponseEntity.ok(userConverter.toUserDtos(userService.getAll()));
}
@PutMapping("/api/user/{id}")
public ResponseEntity<UserDto> updateUser(@PathVariable Long id, @RequestBody UserDto userDto) {
User user = userConverter.toUser(userDto);
user.setId(id);
userService.persist(user);
return ResponseEntity.ok().body(userDto);
}
@GetMapping("/api/user/{id}")
public ResponseEntity<UserDto> findUser (@PathVariable Long id) {
Optional<User> user = Optional.ofNullable(userService.getByKey(id));
return ResponseEntity.ok(userConverter.toUserDto(user.get()));
}
}
映射器类:
@Mapper(componentModel = "spring")
@Service
public abstract class UserConverter {
public abstract User toUser(UserDto userDto);
public abstract UserDto toUserDto(User user);
public abstract List<UserDto> toUserDtos(List<User> users);
}
起初我尝试在没有 @Service
注解的情况下运行它,然后使用了该注解,但我始终看到相同的错误。
英文:
I don't know what happend with my spring boot application but now I can't to start it because of an error:
***************************
APPLICATION FAILED TO START
***************************
Description:
Field userConverter in webapp.controllers.UserResourceController required a bean of type 'webapp.converter.UserConverter' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'webapp.converter.UserConverter' in your configuration.
Process finished with exit code 1
Controller code:
@RestController
@RequestMapping("/api/user")
public class UserResourceController {
@Autowired
private UserServiceImpl userService;
@Autowired
private UserConverter userConverter;
@PostMapping
public ResponseEntity<UserDto> addUser(@RequestBody UserDto userDto) {
userService.persist(userConverter.toUser(userDto));
return ResponseEntity.ok().body(userDto);
}
@GetMapping
public ResponseEntity<List<UserDto>> findAllUsers() {
return ResponseEntity.ok(userConverter.toUserDtos(userService.getAll()));
}
@PutMapping("/api/user/{id}")
public ResponseEntity<UserDto> updateUser(@PathVariable Long id, @RequestBody UserDto userDto) {
User user = userConverter.toUser(userDto);
user.setId(id);
userService.persist(user);
return ResponseEntity.ok().body(userDto);
}
@GetMapping("/api/user/{id}")
public ResponseEntity<UserDto> findUser (@PathVariable Long id) {
Optional<User> user = Optional.ofNullable(userService.getByKey(id));
return ResponseEntity.ok(userConverter.toUserDto(user.get()));
}
}
The mapper class:
@Mapper(componentModel = "spring")
@Service
public abstract class UserConverter {
public abstract User toUser(UserDto userDto);
public abstract UserDto toUserDto(User user);
public abstract List<UserDto> toUserDtos(List<User> users);
}
The first I tried to run it without @Service
annotation, and then with it annotation but I always see the same error.
答案1
得分: 0
无法将没有任何实际实现的抽象类注入。即使没有使用Spring,在Java中也无法实现。那你希望如何进行注入呢?
我不明白为什么你需要注入那个类。最佳解决方案是创建一个带有适当转换器的实用类,例如:
public final class UserConverter {
private UserConverter() {}
public static UserDTO toUserDTO(User employee) {
Department empDp = employee.getDepartment();
return UserDTO.builder()
.id(employee.getId())
.name(employee.getName())
.active(employee.getActive())
.departmentId(empDp.getId())
.departmentName(empDp.getName())
.build();
}
public static User toUser(UserDTO dto) {
Department dp = Department.builder()
.id(dto.getDepartmentId())
.name(dto.getDepartmentName())
.build();
return User.builder()
.id(dto.getId())
.name(dto.getName())
.active(dto.getActive())
.department(dp)
.build();
}
}
然后在你的代码中将其作为静态方法调用:
@GetMapping("/{id}")
public ResponseEntity<UserDto> findUser (@PathVariable Long id) {
return userService.getByKey(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
另外,你的代码在API方面存在一些错误:
- 映射到资源的注解应该是复数形式,如
@RequestMapping("/api/users")
-> 当且仅当你需要根据ID执行操作时,才添加@GetMapping("/{id}")
- 创建方法应该返回
201 - Created
状态码,而不是 200 - 如果
/api
应该对所有API通用,你可以在配置文件中为所有资源定义它。从application.yml
中截取的代码如下:
server:
servlet:
context-path: /api
使用 MapStruct 的有用参考资料:
英文:
You couldn't inject an abstract class which doesn't have any real implementation. It isn't possible in Java even without Spring. So have do you expect it could be injected?
I don't understand why do you need to inject that class. The best solution will create a utility class with the appropriate converter, like:
public final class UserConverter {
private UserConverter() {}
public static UserDTO toUserDTO(User employee) {
Department empDp = employee.getDepartment();
return UserDTO.builder()
.id(employee.getId())
.name(employee.getName())
.active(employee.getActive())
.departmentId(empDp.getId())
.departmentName(empDp.getName())
.build();
}
public static User toUser(UserDTO dto) {
Department dp = Department.builder()
.id(dto.getDepartmentId())
.name(dto.getDepartmentName())
.build();
return User.builder()
.id(dto.getId())
.name(dto.getName())
.active(dto.getActive())
.department(dp)
.build();
}
}
And call it as a static method from your code:
@GetMapping("/{id}")
public ResponseEntity<UserDto> findUser (@PathVariable Long id) {
return userService.getByKey(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
Also, your code has some mistakes for your API:
-
mapping to resource should be plural like
@RequestMapping("/api/users")
-> and only when you need operation by id add@GetMapping("/{id}")
-
create method should return
201 - Create
status code instead of 200 -
if
/api
should be common for all your API you could define it at the configuration file for all your resources.
Snippet fromapplicatoin.yml
:server:
servlet:
context-path: /api
Useful references for solutions with MapStruct:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论