本次问题(结尾解答):
1.java.lang.IllegalArgumentException: Invalid character found in method name [0x160x030x01错误
2.Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisException: Could not get a resource from the pool] with root cause
3.自定义模板,解决序列化问题
正题开始,在 SpringBoot2.x 之后,原来使用的jedis 被替换为了 lettuce
jedis : 采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全的,使用 jedis pool 连接
池!
lettuce : 采用netty,实例可以再多个线程中进行共享,不存在线程不安全的情况!可以减少线程数据。
在pom.xml文件添加依赖:这里我使用的连接池技术是jedis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<!-- 1.5的版本默认采用的连接池技术是jedis 2.0以上版本默认连接池是lettuce, 在这里采用jedis,所以需要排除lettuce的jar -->
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 添加jedis客户端 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!-- 将作为Redis对象序列化器 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
然后application.properties添加:
(假如redis有密码的话:自行添加 spring.redis.password=xxxxx)
spring.redis.host=120.25.26.86
spring.redis.port=6379
在service层简单实现普通添加数据进入redis:
public interface RedisService {
void addkey(String key,String value);
}
@Service
public class RedisServiceImp implements RedisService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Override
public void addkey(String key,String value) {
redisTemplate.opsForValue().set(key,value);
}
}
在控制层实现service操作redis的方法:
@Autowired
private RedisService redisService;
@RequestMapping("/redis")
public @ResponseBody String RedisDemo(@RequestParam String key, String value){
System.out.println(key);
System.out.println("进来了");
redisService.addkey(key,value);
return "ok";
}
启动springboot测试一下:
http://localhost:8080/redis?key=hi&value=hi
图片.png
遇到的问题:
1.java.lang.IllegalArgumentException: Invalid character found in method name [0x160x030x01错误解决
将https://localhost:8080/ 改为http://localhost:8080/
2.Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisException: Could not get a resource from the pool] with root cause
假如引入的依赖没错的话,有可能是你的远程redis的不对外连接,需要修改一下redis配置文件:
图片.png
还不行的话,看看你的远程服务器6379端口有没有开放。
3.redis有一个问题,就是在存对象的时候,会序列化成2进制文件。
原因:
spring-data-redis的RedisTemplate<K, V>模板类在操作redis时默认使用JdkSerializationRedisSerializer来进行序列化
解决:
自定义RestTemplate,使用GenericJackson2JsonRedisSerializer解决序列化问题。
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
// // 使用Jackson2JsonRedisSerialize 替换默认序列化
// 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);
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// 设置value的序列化规则和 key的序列化规则
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
redisTemplate.setDefaultSerializer(genericJackson2JsonRedisSerializer);
redisTemplate.setEnableDefaultSerializer(true);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
自定义redisTemple后,使用自动注入@Autowired即可使用。
网友评论