考虑在您的配置中定义一个类型为 ‘UserConverter’ 的 bean。

huangapple go评论79阅读模式
英文:

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 &#39;webapp.converter.UserConverter&#39; 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 &#39;webapp.converter.UserConverter&#39; in your configuration.
Process finished with exit code 1

Controller code:

@RestController
@RequestMapping(&quot;/api/user&quot;)
public class UserResourceController {

@Autowired
private UserServiceImpl userService;

@Autowired
private UserConverter userConverter;

@PostMapping
public ResponseEntity&lt;UserDto&gt; addUser(@RequestBody UserDto userDto) {
    userService.persist(userConverter.toUser(userDto));
    return ResponseEntity.ok().body(userDto);
}

@GetMapping
public ResponseEntity&lt;List&lt;UserDto&gt;&gt; findAllUsers() {
    return ResponseEntity.ok(userConverter.toUserDtos(userService.getAll()));
}

@PutMapping(&quot;/api/user/{id}&quot;)
public ResponseEntity&lt;UserDto&gt; updateUser(@PathVariable Long id, @RequestBody UserDto userDto) {
    User user = userConverter.toUser(userDto);
    user.setId(id);
    userService.persist(user);
    return ResponseEntity.ok().body(userDto);
}

@GetMapping(&quot;/api/user/{id}&quot;)
public ResponseEntity&lt;UserDto&gt; findUser (@PathVariable Long id) {
    Optional&lt;User&gt; user = Optional.ofNullable(userService.getByKey(id));
    return ResponseEntity.ok(userConverter.toUserDto(user.get()));
}
}

The mapper class:

@Mapper(componentModel = &quot;spring&quot;)
@Service
public abstract class UserConverter {
    public abstract User toUser(UserDto userDto);
    public abstract UserDto toUserDto(User user);
    public abstract List&lt;UserDto&gt; toUserDtos(List&lt;User&gt; 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(&quot;/{id}&quot;)
public ResponseEntity&lt;UserDto&gt; 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(&quot;/api/users&quot;) -> and only when you need operation by id add @GetMapping(&quot;/{id}&quot;)

  • 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 from applicatoin.yml:

    server:
    servlet:
    context-path: /api

Useful references for solutions with MapStruct:

huangapple
  • 本文由 发表于 2020年5月5日 17:51:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/61610293.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定