亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

sprintboot使用spring-security包,緩存內(nèi)存與redis共存方式

 更新時(shí)間:2021年10月12日 16:45:21   作者:miheal_near  
這篇文章主要介紹了sprintboot使用spring-security包,緩存內(nèi)存與redis共存方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

項(xiàng)目修改需求描述

項(xiàng)目需要使用分布式緩存機(jī)制,但是使用@Cacheable原始僅配置了內(nèi)存版的,故此次需要改成redis用以支持多應(yīng)用模式的。

項(xiàng)目中如果直接改成redis的,存在一個(gè)問題。如果內(nèi)存對(duì)象同一類,比如都是String的list對(duì)象,存的key值又都是"code",會(huì)把緩存給沖掉,所以需要對(duì)redis的做后綴處理。又因?yàn)橹挥幸粋€(gè)redis服務(wù)器,所以需要對(duì)緩存做項(xiàng)目的前綴處理。

還希望能支持歷史項(xiàng)目,做到內(nèi)存與redis共存,所以順便就做了CacheManager處理。

代碼

使用到的依賴包

		<!-- 緩存、權(quán)限 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-test</artifactId>
			<scope>test</scope>
		</dependency>
		<!-- json -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.47</version>
		</dependency>
		<!-- redis -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-redis</artifactId>
		</dependency>
		<dependency>
			<groupId>io.lettuce</groupId>
			<artifactId>lettuce-core</artifactId>
			<version>5.1.0.M1</version>
		</dependency>

代碼處理

首先如果希望程序支持緩存需要注解

@EnableCaching

然后在application.yml里增加redis的配置

spring:
  application:
    name:app
  redis:
    database: 0
    host: XX.XX.XX.XX
    port: 6379
    password:
    pool:
      max-total: 100
      block-when-exhausted: false
    timeout: 5000  

增加一個(gè)redis處理類RedisConfig,此處做了redis前綴的處理

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;

@Configuration
public class RedisConfig {	
    @Autowired  
    private Environment env;  

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        // 為了開發(fā)方便,一般使用<String, Object>
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        // Json序列化配置
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);        
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        // 設(shè)置key的序列化方式
        redisTemplate.setKeySerializer(stringRedisSerializer);
        // 設(shè)置hashkey的序列化方式
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        // 設(shè)置value的序列化方式
//        template.setValueSerializer(stringRedisSerializer);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        // 設(shè)置hashvalue的序列化方式
//        template.setHashValueSerializer(stringRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);        
//        template.setBeanClassLoader(this.getClass().getClassLoader());
//        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
    @Bean("redisCacheManager")
    //@Primary
    public RedisCacheManager myRedisCacheManager(RedisConnectionFactory redisConnectionFactory){
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();

        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);     
        String prefixStr = env.getProperty("spring.application.name") + ":";
        if(!'prod'.equals(env.getActiveProfiles()[0])) {
        	prefixStr += env.getActiveProfiles()[0]  + ":";
        }
        
        // 配置序列化(解決亂碼的問題)
//        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(this.getClass().getClassLoader())
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
//        		.computePrefixWith(cacheName -> env.getProperty("spring.application.name").concat(":")
//        				.concat(env.getActiveProfiles()[0])
//        				.concat(":")
//        				.concat(cacheName))
        		.prefixKeysWith(prefixStr)
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();

        RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).build();
        return cacheManager;
    }

    @Bean("defaultCacheManager")
    @Primary
    public ConcurrentMapCacheManager cacheManager() {
    	ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager();
		return cacheManager;
	}	
}

注:RedisCacheManager 和 RedisTemplate 里的json處理要注意一致性。

這邊配置了2個(gè)cacheManager:(ConcurrentMapCacheManager 默認(rèn)緩存、RedisCacheManager redis緩存)

必須要默認(rèn)一個(gè)cacheManager,哪個(gè)是默認(rèn)的就在哪個(gè)bean上加注解@Primary

如果不寫會(huì)報(bào)下列錯(cuò)誤:

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
19:42:21.462 [restartedMain] ERROR o.s.b.SpringApplication:858 - Application run failed
java.lang.IllegalStateException: No CacheResolver specified, and no unique bean of type CacheManager found. Mark one as primary or declare a specific CacheManager to use.
at org.springframework.cache.interceptor.CacheAspectSupport.afterSingletonsInstantiated(CacheAspectSupport.java:223)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:866)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)

增加MyKeyGenerator,做redis后綴處理

CachingConfigurerSupport 這個(gè)接口默認(rèn)就有@Primary功能,無需額外配置

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.lang.reflect.Method;

@Configuration
public class MyKeyGeneratorConfig extends CachingConfigurerSupport {
	private final Logger logger = LoggerFactory.getLogger(this.getClass());	
    @Bean
//    @Primary
//    @Override
    public KeyGenerator myKeyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
//                String re= String.format("%s::%s(%s)",target.getClass().getName(),method.getName(),
//                        CollectionUtils.arrayToList(params));//Arrays.asList(params)
            	
        		StringBuilder sb = new StringBuilder();
        		String valueStr = null;
        		if (method.isAnnotationPresent(Cacheable.class)) {
        			Cacheable ca = method.getAnnotation(Cacheable.class);
        			if (ca.value() != null) {
        				valueStr = ca.value()[0];
        			}
        		} else if(method.isAnnotationPresent(CacheEvict.class)) {
        			CacheEvict ce = method.getAnnotation(CacheEvict.class);
        			if (ce.value() != null) {
        				valueStr = ce.value()[0];
        			}
        		}
        		
        		if (valueStr != null) {
        			sb.append(valueStr + ":");
        		} else {
        			sb.append(target.getClass().getName() + ":");
        			sb.append(method.getName() + ":");
        		}
        		for (Object obj : params) {
        			sb.append(obj.toString() + ":");
        		}
//        		return sb.toString();
        		String re = sb.toString();
            	
            	
                logger.debug("緩存生成的key:{}。",re);
                return re;
            }
        };
    }	
}

緩存類處理:

 @Cacheable(value = "XXX", keyGenerator = "myKeyGenerator", cacheManager = "redisCacheManager")
 public List<String> getXXXX(String userCode) {
  XXXXXXXXXX
 }

對(duì)應(yīng)的@CacheEvict 記得也把該屬性加上,如果不是默認(rèn)的話: keyGenerator = “myKeyGenerator”

權(quán)限類處理:

針對(duì)權(quán)限類controller增加注解判斷,沒權(quán)限直接報(bào)錯(cuò)

@PreAuthorize(“hasAuthority(‘privileges')”)

權(quán)限緩存加載類:

 @Cacheable("privileges")
 private List<GrantedAuthority> makeAuth(String userCode) {
  List<MyGrantedAuthority> privileges = XXX;
  return privileges;
 }

權(quán)限類:

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion;
import org.springframework.util.Assert;
public class MyGrantedAuthority  implements GrantedAuthority {
	private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
	private String authority;	
    public MyGrantedAuthority() {
    	super();
    }

	public MyGrantedAuthority(String authority) {
		Assert.hasText(authority, "A granted authority textual representation is required");
		this.authority = authority;
	}

	@Override
	public String getAuthority() {
		return authority;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}

		if (obj instanceof MyGrantedAuthority) {
			return authority.equals(((MyGrantedAuthority) obj).authority);
		}

		return false;
	}

	@Override
	public int hashCode() {
		return this.authority.hashCode();
	}

	@Override
	public String toString() {
		return this.authority;
	}
}

異常問題解決

如果項(xiàng)目中存在LocalDateTime會(huì)報(bào)錯(cuò):

Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.LocalDateTime` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (byte[])
[truncated 981 bytes]; line: 1, column: 360] (through reference chain: ["createdTime"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1452)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1028)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1297)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:116)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromAny(AsArrayTypeDeserializer.java:71)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserializeWithType(UntypedObjectDeserializer.java:712)
at com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer.deserialize(TypeWrappedDeserializer.java:68)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3129)
at org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer.deserialize(Jackson2JsonRedisSerializer.java:73)
... 112 common frames omitted

需要對(duì)類里面的LocalDateTime增加注解

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;

    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
 private LocalDateTime XXX;

如不存在jsr310的包可以增加pom配置

  <!-- 緩存、權(quán)限 -->
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>2.9.8</version>
        </dependency>

UserDetails子類代碼

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
//import com.fasterxml.jackson.annotation.JsonIgnore;
public class JwtUser implements UserDetails {
	private String username;
	private String userCode;
	private String password;
	private Collection<? extends GrantedAuthority> authorities;
	private Boolean enabled;
	private Boolean accountNonExpired = true;
	private Boolean accountNonLocked = true;
	private Boolean credentialsNonExpired = true;	
	public JwtUser() {
		super();
	}
	String getPassword();
	...
	...
	...
}

這邊需要寫一個(gè)無參數(shù)構(gòu)造函數(shù),因?yàn)閖son反序列化原因

UserDetails 這個(gè)里面對(duì)應(yīng)getXXX(例如getPassword)的對(duì)象都要寫對(duì)應(yīng)的參數(shù),否則json轉(zhuǎn)義的時(shí)候會(huì)報(bào)錯(cuò),如果用不到就增加注解@JsonIgnore。

org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Unrecognized field "accountNonLocked" ]; line: 1, column: 18401] (through reference chain: JwtUser["accountNonLocked"])
at org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer.deserialize(Jackson2JsonRedisSerializer.java:75)
at org.springframework.data.redis.serializer.DefaultRedisElementReader.read(DefaultRedisElementReader.java:48)
at org.springframework.data.redis.serializer.RedisSerializationContext$SerializationPair.read(RedisSerializationContext.java:226)
at org.springframework.data.redis.cache.RedisCache.deserializeCacheValue(RedisCache.java:254)
at org.springframework.data.redis.cache.RedisCache.lookup(RedisCache.java:88)
at org.springframework.cache.support.AbstractValueAdaptingCache.get(AbstractValueAdaptingCache.java:58)
at org.springframework.cache.interceptor.AbstractCacheInvoker.doGet(AbstractCacheInvoker.java:73)
at org.springframework.cache.interceptor.CacheAspectSupport.findInCaches(CacheAspectSupport.java:554)
at org.springframework.cache.interceptor.CacheAspectSupport.findCachedItem(CacheAspectSupport.java:519)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:401)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:345)
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$UserDetailsServiceDelegator.loadUserByUsername(WebSecurityConfigurerAdapter.java:451)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:96)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:117)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:106)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)

權(quán)限類異常

使用SimpleGrantedAuthority會(huì)因無參數(shù)構(gòu)造函數(shù)報(bào)錯(cuò),因?yàn)閖son反序列化原因,需要重新建一個(gè)子類,并且增加無參數(shù)構(gòu)造函數(shù),類名為MyGrantedAuthority(此類上面詳細(xì)代碼已寫,故不重復(fù)寫了)。

報(bào)錯(cuò)內(nèi)容

org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Cannot construct instance of `org.springframework.security.core.authority.SimpleGrantedAuthority` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (byte[])"["XXX["authorities"]->java.util.ArrayList[0])
at org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer.deserialize(Jackson2JsonRedisSerializer.java:75)
at org.springframework.data.redis.serializer.DefaultRedisElementReader.read(DefaultRedisElementReader.java:48)
at org.springframework.data.redis.serializer.RedisSerializationContext$SerializationPair.read(RedisSerializationContext.java:226)
at org.springframework.data.redis.cache.RedisCache.deserializeCacheValue(RedisCache.java:254)
at org.springframework.data.redis.cache.RedisCache.lookup(RedisCache.java:88)
at org.springframework.cache.support.AbstractValueAdaptingCache.get(AbstractValueAdaptingCache.java:58)
at org.springframework.cache.interceptor.AbstractCacheInvoker.doGet(AbstractCacheInvoker.java:73)
at org.springframework.cache.interceptor.CacheAspectSupport.findInCaches(CacheAspectSupport.java:554)
at org.springframework.cache.interceptor.CacheAspectSupport.findCachedItem(CacheAspectSupport.java:519)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:401)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:345)
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$UserDetailsServiceDelegator.loadUserByUsername(WebSecurityConfigurerAdapter.java:451)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:96)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:117)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:106)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Spring activiti如何實(shí)現(xiàn)指定任務(wù)處理者

    Spring activiti如何實(shí)現(xiàn)指定任務(wù)處理者

    這篇文章主要介紹了Spring activiti如何實(shí)現(xiàn)指定任務(wù)處理者,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • 如何使用IDEA從SVN服務(wù)端檢出項(xiàng)目

    如何使用IDEA從SVN服務(wù)端檢出項(xiàng)目

    這篇文章主要介紹了如何使用IDEA從SVN服務(wù)端檢出項(xiàng)目問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Java中synchronized關(guān)鍵字的使用和原理詳解

    Java中synchronized關(guān)鍵字的使用和原理詳解

    這篇文章主要介紹了Java中synchronized關(guān)鍵字的使用和原理詳解,JVM 是通過進(jìn)入、退出 對(duì)象監(jiān)視器(Monitor)來實(shí)現(xiàn)對(duì)方法、同步塊的同步的,而對(duì)象監(jiān)視器的本質(zhì)依賴于底層操作系統(tǒng)的互斥鎖實(shí)現(xiàn),需要的朋友可以參考下
    2023-09-09
  • 詳解Java程序啟動(dòng)時(shí)-D指定參數(shù)是什么

    詳解Java程序啟動(dòng)時(shí)-D指定參數(shù)是什么

    java服務(wù)啟動(dòng)的時(shí)候,都會(huì)指定一些參數(shù),下面這篇文章主要給大家介紹了關(guān)于Java程序啟動(dòng)時(shí)-D指定參數(shù)是什么的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • Java反射技術(shù)原理與用法實(shí)例分析

    Java反射技術(shù)原理與用法實(shí)例分析

    這篇文章主要介紹了Java反射技術(shù)原理與用法,結(jié)合實(shí)例形式分析了Java反射技術(shù)的基本概念、功能、原理、用法及操作注意事項(xiàng),需要的朋友可以參考下
    2020-04-04
  • intelliJ idea 2023 配置Tomcat 8圖文教程

    intelliJ idea 2023 配置Tomcat 8圖文教程

    這篇文章主要介紹了intelliJ idea 2023 配置Tomcat 8教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06
  • Springboot創(chuàng)建項(xiàng)目的圖文教程(idea版本)

    Springboot創(chuàng)建項(xiàng)目的圖文教程(idea版本)

    這篇文章主要介紹了Springboot創(chuàng)建項(xiàng)目的圖文教程(idea版本),本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • centos 安裝java環(huán)境的多種方法

    centos 安裝java環(huán)境的多種方法

    本文給大家分享三種方法幫助大家安裝jdk,有利用yum來安裝jdk還有通過手動(dòng)解壓jdk的操作方法,每種方法給大家介紹的都非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • Java為什么占用四個(gè)字節(jié)你知道嗎

    Java為什么占用四個(gè)字節(jié)你知道嗎

    這篇文章主要介紹了Java為什么占四個(gè)字節(jié),文中介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • 使用Hibernate根據(jù)實(shí)體類自動(dòng)生成表的方法

    使用Hibernate根據(jù)實(shí)體類自動(dòng)生成表的方法

    這篇文章主要介紹了使用Hibernate根據(jù)實(shí)體類自動(dòng)生成表的方法,該篇提供了兩種方法,可以根據(jù)需要選擇其一,希望對(duì)你有所幫助,如有不對(duì)的地方還望指正
    2023-03-03

最新評(píng)論