【发布时间】:2021-08-11 21:01:24
【问题描述】:
嗨,我的简单 Spring Boot 安全项目
我的用户控制器
@RestController
@RequestMapping(path= "/api")
@RequiredArgcContructor
public class UserController {
private final UserService userService;
@PostMapping
public String create(@RequestBody UserDTO userDto){
return userService.save(userDto);
}
}
我的用户服务
@Service
@RequiredArgsConstructor
public class UserService {
private UserManager userManager;
private Mapper<UserDTO, UserEntity> userDTOUserMapper;
public String save(UserDTO userDto) {
return userManager.signUp(userDTOUserMapper.map(userDto));
}
}
我的用户管理器
package com.userlogintask.userlogintask.business;
import com.userlogintask.userlogintask.model.TokenEntity;
import com.userlogintask.userlogintask.model.UserEntity;
import com.userlogintask.userlogintask.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.UUID;
@Component
@RequiredArgsConstructor
public class UserManager implements UserDetailsService {
private final static String USER_NOT_FOUND_msg="user with email %s not found";
private final UserRepository userRepository;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
private final TokenManager tokenManager;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
return userRepository.findByEmail(email)
.orElseThrow(()-> new UsernameNotFoundException(String.format(USER_NOT_FOUND_msg,email)));
}
public String signUp(UserEntity userEntity){
boolean isExist = userRepository.findByEmail(userEntity.getEmail()).isPresent();
if(isExist){
throw new IllegalStateException("email is already exists");
}
String encodePassword = bCryptPasswordEncoder.encode(userEntity.getPassword());
userEntity.setPassword(encodePassword);
userRepository.save(userEntity);
//TODO:Send confirmation token;
String token = UUID.randomUUID().toString();
TokenEntity confirmationTokenEntity = new TokenEntity(
token,
LocalDateTime.now(),
LocalDateTime.now().plusMinutes(15),
userEntity
);
tokenManager.saveConfirmationToken(confirmationTokenEntity);
//TODO:Send email
return token;
}
public int enableAppUser(String email) {
return userRepository.enableUser(email);
}
}
我的映射配置
@Configuration
public class ApiMappingConfig {
//userDTO mapping user
@Bean
public Mapper<UserDTO, UserEntity> userDTOUserMapper(){
return Mapping.from(UserDTO.class)
.to(UserEntity.class)
.omitInDestination(UserEntity::getLocked)
.omitInDestination(UserEntity::getUser_id)
.omitInDestination(UserEntity::getEnabled)
.mapper();
}
}
我的用户实体
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class UserEntity implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "user_id",unique = true)
private Long user_id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
private String email;
private String password;
@Enumerated(EnumType.STRING)
private UserRole userRole;
private Boolean locked = false;
private Boolean enabled = false;
public UserEntity(String firstName,
String lastName, String email,
String password, UserRole userRole) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.password = password;
this.userRole = userRole;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.singleton(new SimpleGrantedAuthority(userRole.name()));
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return email;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return !locked;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return enabled;
}
}
我的用户DTO
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserDTO {
private String firstName;
private String lastName;
private String email;
private String password;
private UserRole userRole;
}
我的主要课程
@SpringBootApplication
public class UserlogintaskApplication {
public static void main(String[] args) {
SpringApplication.run(UserlogintaskApplication.class, args);
}
}
我的错误
创建文件中定义的名称为“userController”的 bean 时出错 [C:\Users\user\Desktop\Java\userlogintask\target\classes\com\userlogintask\userlogintask\controller\UserController.class]: 通过构造函数参数 0 表示的不满足的依赖关系; 嵌套异常是 org.springframework.beans.factory.UnsatisfiedDependencyException: 创建文件中定义的名称为“userService”的 bean 时出错 [C:\Users\user\Desktop\Java\userlogintask\target\classes\com\userlogintask\userlogintask\service\UserService.class]: 通过构造函数参数1表示的不满足的依赖关系; 嵌套异常是 org.springframework.beans.factory.BeanCreationException:错误 创建在类路径中定义的名称为“userDTOUserMapper”的 bean 资源 [com/userlogintask/userlogintask/mapping/ApiMappingConfig.class]:豆 通过工厂方法实例化失败;嵌套异常是 org.springframework.beans.BeanInstantiationException:失败 实例化 [com.remondis.remap.Mapper]:工厂方法 'userDTOUserMapper' 抛出异常;嵌套异常是 com.remondis.remap.MappingException:属性的获取方法 com.userlogintask.userlogintask.model.UserEntity 类型中的“启用”是 不是有效的 Java Bean 属性。在 org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1354) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.5.jar:5.3.5] 在 org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.5.jar:5.3.5] 在 org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.4.jar:2.4.4] 在 org.springframework.boot.SpringApplication.refresh(SpringApplication.java:769) ~[spring-boot-2.4.4.jar:2.4.4] 在 org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761) ~[spring-boot-2.4.4.jar:2.4.4] 在 org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) ~[spring-boot-2.4.4.jar:2.4.4] 在 org.springframework.boot.SpringApplication.run(SpringApplication.java:326) ~[spring-boot-2.4.4.jar:2.4.4] 在 org.springframework.boot.SpringApplication.run(SpringApplication.java:1313) ~[spring-boot-2.4.4.jar:2.4.4] 在 org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[spring-boot-2.4.4.jar:2.4.4] 在 com.userlogintask.userlogintask.UserlogintaskApplication.main(UserlogintaskApplication.java:14) 〜[类/:na]在 java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native 方法)~[na:na] 在 java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na] 在 java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] 在 java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na] 在 org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.4.4.jar:2.4.4] 原因: org.springframework.beans.factory.UnsatisfiedDependencyException: 创建文件中定义的名称为“userService”的 bean 时出错 [C:\Users\user\Desktop\Java\userlogintask\target\classes\com\userlogintask\userlogintask\service\UserService.class]: 通过构造函数参数1表示的不满足的依赖关系; 嵌套异常是 org.springframework.beans.factory.BeanCreationException:错误 创建在类路径中定义的名称为“userDTOUserMapper”的 bean 资源 [com/userlogintask/userlogintask/mapping/ApiMappingConfig.class]:豆 通过工厂方法实例化失败;嵌套异常是 org.springframework.beans.BeanInstantiationException:失败 实例化 [com.remondis.remap.Mapper]:工厂方法 'userDTOUserMapper' 抛出异常;嵌套异常是 com.remondis.remap.MappingException:属性的获取方法 com.userlogintask.userlogintask.model.UserEntity 类型中的“启用”是 不是有效的 Java Bean 属性。在 org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1354) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.5.jar:5.3.5] ...省略了25个常用框架导致 作者:org.springframework.beans.factory.BeanCreationException:错误 创建在类路径中定义的名称为“userDTOUserMapper”的 bean 资源 [com/userlogintask/userlogintask/mapping/ApiMappingConfig.class]:豆 通过工厂方法实例化失败;嵌套异常是 org.springframework.beans.BeanInstantiationException:失败 实例化 [com.remondis.remap.Mapper]:工厂方法 'userDTOUserMapper' 抛出异常;嵌套异常是 com.remondis.remap.MappingException:属性的获取方法 com.userlogintask.userlogintask.model.UserEntity 类型中的“启用”是 不是有效的 Java Bean 属性。在 org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:486) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.5.jar:5.3.5] ...省略了39个常用框架造成的 作者:org.springframework.beans.BeanInstantiationException:失败 实例化 [com.remondis.remap.Mapper]:工厂方法 'userDTOUserMapper' 抛出异常;嵌套异常是 com.remondis.remap.MappingException:属性的获取方法 com.userlogintask.userlogintask.model.UserEntity 类型中的“启用”是 不是有效的 Java Bean 属性。在 org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.3.5.jar:5.3.5] 在 org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.5.jar:5.3.5] ... 53个常用框架省略造成 作者:com.remondis.remap.MappingException:属性的获取方法 com.userlogintask.userlogintask.model.UserEntity 类型中的“启用”是 不是有效的 Java Bean 属性。在 com.remondis.remap.MappingException.notAProperty(MappingException.java:55) ~[remap-4.2.5.jar:4.2.5] 在 com.remondis.remap.MappingConfiguration.getPropertyDescriptorOrFail(MappingConfiguration.java:574) ~[remap-4.2.5.jar:4.2.5] 在 com.remondis.remap.MappingConfiguration.getPropertyFromFieldSelector(MappingConfiguration.java:550) ~[remap-4.2.5.jar:4.2.5] 在 com.remondis.remap.MappingConfiguration.omitInDestination(MappingConfiguration.java:117) ~[remap-4.2.5.jar:4.2.5] 在 com.userlogintask.userlogintask.mapping.ApiMappingConfig.userDTOUserMapper(ApiMappingConfig.java:23) 〜[类/:na]在 com.userlogintask.userlogintask.mapping.ApiMappingConfig$$EnhancerBySpringCGLIB$$952967e9.CGLIB$userDTOUserMapper$0() 〜[类/:na]在 com.userlogintask.userlogintask.mapping.ApiMappingConfig$$EnhancerBySpringCGLIB$$952967e9$$FastClassBySpringCGLIB$$7199a018.invoke() 〜[类/:na]在 org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.3.5.jar:5.3.5] 在 org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-5.3.5.jar:5.3.5] 在 com.userlogintask.userlogintask.mapping.ApiMappingConfig$$EnhancerBySpringCGLIB$$952967e9.userDTOUserMapper() 〜[类/:na]在 java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native 方法)~[na:na] 在 java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na] 在 java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] 在 java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na] 在 org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.5.jar:5.3.5] ...省略54个常用框架 进程以退出代码 0 结束
我的 Pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.userlogintask</groupId>
<artifactId>userlogintask</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>userlogintask</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>15</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.20</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.remondis</groupId>
<artifactId>remap</artifactId>
<version>4.2.5</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>4.3.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.4.4</version>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
有什么问题?我不明白
【问题讨论】:
-
请贴出项目结构:
@SpringBootApplication(主要方法)在哪个包中,服务、映射器、管理器和这个控制器在哪里。什么是映射器?您使用的是第三方还是您的自定义映射代码?也请在问题中发布整个异常,因为目前无法理解究竟发生了什么。当然不能创建userServicebean,但为什么呢?为了回答我们需要这些信息 -
好的,没问题
-
@Zaur 创建映射失败 - 隔离。
标签: java spring spring-boot