在执行spring security+jwt身份验证后,我的应用程序没有生成。有关控制器和服务的测试出现故障。当我尝试构建应用程序时,我通过控制器和服务的测试收到这样的信息:
java.lang.IllegalStateException
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException
Caused by: org.springframework.beans.factory.BeanCreationException
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException
在实现springsecurity+jwt身份验证之前,一切正常。
我寻找解决方案并试图:
在涉及spring security+jwt身份验证的类中用@bean和方法替换@autowired和field
在有关spring security+jwt身份验证的类中实现@componentscan
添加@lazy with@autowired in clases关于spring security+jwt身份验证
因为有一个关于以下注射的问题:
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Lazy
@Autowired(required = true)
private ReaderPrincipalDetailsService readerPrincipalDetailsService;
@Lazy
@Autowired(required = true)
private JwtRequestFilter jwtRequestFilter;
现在,在这些更正之后,当我尝试运行一个失败的测试时,重要的日志如下所示(如果需要的话,我可以将整个日志括起来):
2021-02-05 10:11:09.530 WARN 6980 --- [ main] o.s.w.c.s.GenericWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException:**Error creating bean with name 'volumeAdapter': Unsatisfied dependency expressed through field 'volumeService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'volumeService'**: Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManagerFactory' available
Description:
Field volumeService in com.kodilla.librarybackend.adapter.VolumeAdapter required a bean of type 'javax.persistence.EntityManagerFactory' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Consider defining a bean of type 'javax.persistence.EntityManagerFactory' in your configuration.
2021-02-05 10:11:09.787 ERROR 6980 --- [ main] o.s.test.context.TestContextManager : Caught exception while allowing TestExecutionListener [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@1fa268de] to prepare test instance [com.kodilla.librarybackend.controller.GenreControllerTest@57c47a9e]
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'volumeAdapter': Unsatisfied dependency expressed through field 'volumeService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'volumeService': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManagerFactory' available
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'volumeService': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManagerFactory' available
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManagerFactory' available
以下是我的认证课程:
@EnableWebSecurity
@Component
@ComponentScan(basePackages = {"com.kodilla.librarybackend"})
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Lazy
@Autowired(required = true)
private ReaderPrincipalDetailsService readerPrincipalDetailsService;
@Lazy
@Autowired(required = true)
private JwtRequestFilter jwtRequestFilter;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(readerPrincipalDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().antMatchers("/authenticate").permitAll()
.anyRequest().authenticated()
.and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception{
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
}
@Service
@ComponentScan(basePackages = {"com.kodilla.librarybackend"})
public class ReaderPrincipalDetailsService implements UserDetailsService {
@Lazy
@Autowired
private ReaderRepository readerRepository;
@Override
public UserDetails loadUserByUsername(String emailAddress) throws UsernameNotFoundException {
return readerRepository.findFirstByEmailAddress(emailAddress);
}
}
@Service
public class JwtUtil {
public JwtUtil() {
}
private String SECRET_KEY = "secret";
public String extractUserName(String token){
return extractClaim(token, Claims::getSubject);
}
public Date extractExpiration(String token){
return extractClaim(token, Claims::getExpiration);
}
public <T> T extractClaim(String token, Function<Claims, T> claimsResolver){
final Claims claims = extractAllClaims(token);
return claimsResolver.apply(claims);
}
private Claims extractAllClaims (String token){
return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
}
private Boolean isTokenExpired (String token){
return extractExpiration(token).before(new Date());
}
public String generateToken(UserDetails userDetails){
Map <String, Object> claims = new HashMap<>();
return createToken(claims, userDetails.getUsername());
}
private String createToken (Map<String,Object>claims,String subject){
return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10))
.signWith(SignatureAlgorithm.HS256,SECRET_KEY).compact();
}
public Boolean validateToken(String token, UserDetails userDetails){
final String readerName = extractUserName(token);
return (readerName.equals(userDetails.getUsername()) && isTokenExpired(token));
}
}
@Component
@ComponentScan(basePackages = {"com.kodilla.librarybackend"})
public class JwtRequestFilter extends OncePerRequestFilter {
@Lazy
@Autowired
private ReaderPrincipalDetailsService readerPrincipalDetailsService;
@Lazy
@Autowired
private JwtUtil jwtUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
final String authorizationHeader = request.getHeader("Authorization");
String emailAddress = null;
String jwt = null;
if(authorizationHeader != null && authorizationHeader.startsWith("Bearer ")){
jwt = authorizationHeader.substring(7);
emailAddress = jwtUtil.extractUserName(jwt);
}
if(emailAddress != null && SecurityContextHolder.getContext().getAuthentication() == null){
UserDetails userDetails = this.readerPrincipalDetailsService.loadUserByUsername(emailAddress);
if(jwtUtil.validateToken(jwt,userDetails)){
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
filterChain.doFilter(request,response);
}
}
public class AuthenticationRequest {
private String emailAddress;
private String password;
public AuthenticationRequest(String emailAddress, String password) {
this.emailAddress = emailAddress;
this.password = password;
}
public AuthenticationRequest() {
}
public String getemailAddress() {
return emailAddress;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
public class AuthenticationResponse {
private final String jwt;
public AuthenticationResponse(String jwt) {
this.jwt = jwt;
}
public String getJwt() {
return jwt;
}
}
关于电流误差:
@Component
public class VolumeAdapter {
@Autowired
private VolumeService volumeService;
private static final Logger LOGGER = LoggerFactory.getLogger(VolumeAdapter.class);
public List<Volume> createAllGoogleVolumeList(List<VolumeDto> volumeDtoList){
LOGGER.info("Google books adapter starts...");
return volumeDtoList.stream().map(v -> {
return new Volume(v.getTitle(),v.getAuthors(),v.getPublishedDate(),v.getDescription());
}).collect(Collectors.toList());
}
public List <Volume> createSpecificVolume(List <VolumeDto> volumeDtoList){
LOGGER.info("Specific google book adapter is looking for requested book");
return volumeDtoList.stream().map(v -> {
return new Volume(v.getTitle(),v.getAuthors(),v.getPublishedDate(),v.getDescription());
}).collect(Collectors.toList());
}
}
@Service
public class VolumeService {
@Autowired
private GoogleBooksClient googleBooksClient;
@Autowired
private VolumeRepository volumeRepository;
@Autowired
private CartRepository cartRepository;
@Autowired
private VolumeMapper volumeMapper;
@PersistenceContext
private EntityManager entityManager;
@Autowired
private VolumeAdapter volumeAdapter;
private static final Logger LOGGER = LoggerFactory.getLogger(VolumeService.class);
private Set<Volume> volumes;
private static VolumeService volumeService;
public static VolumeService getInstance() {
if (volumeService == null) {
volumeService = new VolumeService();
}
return volumeService;
}
public Set<Volume> getBooks() {
return new HashSet<>(volumes);
}
public List <Volume> fetchSpecifiedGoogleBook(String book){
LOGGER.info("Fetching Google Book with requested typo:"+ book);
return volumeAdapter.createSpecificVolume(googleBooksClient.getSpecifiedGoogleBooks(book));
}
public void addBook(Volume volume) {
this.volumes.add(volume);
}
public CartBookAdderDto putFoundVolumeInCart (Volume foundVolume, Long cartId){
LOGGER.info("Putting found volume in cart started");
Cart cart = cartRepository.findCartById(cartId);
LOGGER.info("Cart: " + cart.toString() + " selected.");
LOGGER.info("Volume: " + foundVolume.getTitle() + " adding to cart started");
Volume volumePutInCart = new Volume(foundVolume.getTitle(),foundVolume.getAuthors(),foundVolume.getPublishedDate(),foundVolume.getDescription());
List <Volume> volumeList = new ArrayList<>();
volumeList.add(volumePutInCart);
cart.setBooks(volumeList);
LOGGER.info("Volume added to cart");
return new CartBookAdderDto(cartId, volumeMapper.mapToBookDtoList((volumeList)));
}
/*public VolumeDto getBookPutInCart(CartBookAdderDto cartBookAdderDto){
LOGGER.info("Getting books put in cart started");
if(putFoundVolumeInCart(volumeMapper.mapToBook(cartBookAdderDto.getBookDto()), volumeMapper.mapToBook(cartBookAdderDto.getBookDto()).toString() , cartBookAdderDto.getCartId()) != null){
VolumeDto bookPutInCart = putFoundVolumeInCart(volumeMapper.mapToBook(cartBookAdderDto.getBookDto()),volumeMapper.mapToBook(cartBookAdderDto.getBookDto()).toString(), cartBookAdderDto.getCartId()).getBookDto();
LOGGER.info(bookPutInCart + " will be put in cart");
return bookPutInCart;
}
else{
LOGGER.info("Putting book in Cart failed");
}
return new VolumeDto();
}*/
/*public List<Volume> getAvaiableToRentBooks(boolean rented) {
LOGGER.info("Getting books avaiable to rent");
List<Volume> volumeList = volumeRepository.findAll();
return volumeList.stream()
.filter(book -> book.isRented() == false)
.collect(Collectors.toList());
}*/
/*public List<Volume> getAlreadyRentedBooks(boolean rented) {
LOGGER.info("Getting books already rented");
List<Volume> volumeList = volumeRepository.findAll();
return volumeList.stream()
.filter(book -> book.isRented() == true)
.collect(Collectors.toList());
}*/
public List<Volume> getBooksOfDefiniedTitleAndAuthor(String title, String authors) {
LOGGER.info("Getting books of:"+authors);
List<Volume> volumeList = volumeRepository.findAll();
return volumeList.stream()
.filter(book -> book.getTitle() == title)
.filter(book -> book.getAuthors() == authors)
.collect(Collectors.toList());
}
public Volume getBook(final Long id){
LOGGER.info("Getting book with id:"+id.toString());
return volumeRepository.getOne(id);
}
@Transactional
public Volume createBook(final Volume volume){
LOGGER.info("Creating new book");
return volumeRepository.save(volume);
}
/*public void updateBook(final Long id){
LOGGER.info("Start of updating book with id:"+id.toString());
volumeRepository.updateBookSetRentedForId(true,id);
Book book = getBook(id);
entityManager.refresh(book);
LOGGER.info("Updating book with id:"+id.toString()+" finished");
}*/
@Transactional
public void deleteBook(final Long id){
LOGGER.info("Deleting book with id:"+id.toString());
volumeRepository.deleteById(id);
}
}
很抱歉发了这么长的帖子:),我想附上所有可能有用的信息
有人知道那里发生了什么吗?:)
暂无答案!
目前还没有任何答案,快来回答吧!