sping+redis实现消息队列的乱码问题

使用spring支持redis实现消息队列,参考官方样例:https://spring.io/guides/gs/messaging-redis/

实现后在运行过程中发现消费者在接收消息时会出现乱码的情况。经排查是由于序列化工具不同导致的。

生产者的配置

  <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">  
        <property name="connectionFactory" ref="connectionFactory"/>  
        <!--     如果不配置Serializer,那么存储的时候只能使用String,如果用对象类型存储,那么会提示错误 can't cast to String!!!-->  
        <property name="keySerializer">  
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>  
        </property>  
        <property name="valueSerializer">  
            <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>  
        </property>  
        <!--开启事务-->  
        <property name="enableTransactionSupport" value="true"/>  
    </bean> 

template默认是使用stringSerializer的,这里配置了JdkSerializationRedisSerializer来做一些对象的存储。

这就导致了消费端接受消息时反序列化会出现问题,解决方法可以在消费者配置监听器中注入生产者使用的序列化工具。

注意Serializer属性。

<bean id="listener" class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter">
           <constructor-arg index="0" ref= "receiver"/> 
           <constructor-arg index="1" value="receive" /> 
           <property name="serializer" >
            <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>  
            </property>
   </bean>

 

转载于:https://www.cnblogs.com/tangyuanyuan/p/8331243.html

### 回答1: 使用 Spring Security 自定义 Redis 密码验证的一个示例如下: 首先,你需要在你的项目中引入 Spring Security 和 Redis 相关的依赖。然后,你可以定义一个自定义的 `AuthenticationProvider` 来验证用户的密码。 下面是一个使用 Redis 连接池和模板类来验证密码的示例: ```java import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import java.util.Collection; public class RedisAuthenticationProvider implements AuthenticationProvider { private final JedisConnectionFactory connectionFactory; private final RedisTemplate<String, UserDetails> redisTemplate; public RedisAuthenticationProvider(JedisConnectionFactory connectionFactory, RedisTemplate<String, UserDetails> redisTemplate) { this.connectionFactory = connectionFactory; this.redisTemplate = redisTemplate; } @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String username = authentication.getName(); String password = (String) authentication.getCredentials(); UserDetails user = redisTemplate.opsForValue().get(username); if (user == null) { throw new BadCredentialsException("用户名不存在"); } if (!password.equals(user.getPassword())) { throw new BadCredentialsException("密码错误"); } Collection<? extends GrantedAuthority> authorities = user.getAuthorities(); return new UsernamePasswordAuthenticationToken(username, password, authorities); } @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); } } ``` 然后,你可以在你的 Spring Security 配置类中将这个自定义的 `AuthenticationProvider` 添加到认证管理器中: ```java ### 回答2: Spring Security是一个针对Spring应用程序的安全框架,它提供了一种灵活且功能强大的方式来实现身份验证和访问控制。Redis是一个开源的内存数据库,常用于缓存和会话管理。 在使用Spring Security和Redis进行自定义密码验证时,可以按照以下步骤来实现: 1. 配置Redis作为Spring Security的UserDetailsService。可以创建一个类来实现UserDetailsService接口,并重写loadUserByUsername方法,从Redis中查询用户信息。 ```java @Service public class UserDetailsServiceImpl implements UserDetailsService { @Autowired private RedisTemplate<String, Object> redisTemplate; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 从Redis中获取用户信息 User user = (User) redisTemplate.opsForHash().get("users", username); if (user == null) { throw new UsernameNotFoundException("User not found"); } // 创建UserDetails对象,并设置用户名、密码和权限 return User.withUsername(user.getUsername()) .password(user.getPassword()) .roles(user.getRoles().toArray(new String[0])) .build(); } } ``` 2. 配置使用Redis作为密码存储器。可以创建一个类来实现PasswordEncoder接口,并重写encode和matches方法,实现密码的加密和匹配。 ```java @Service public class RedisPasswordEncoder implements PasswordEncoder { @Override public String encode(CharSequence rawPassword) { // 在这里实现密码的加密逻辑,可以使用BCryptPasswordEncoder等加密算法 return rawPassword.toString(); } @Override public boolean matches(CharSequence rawPassword, String encodedPassword) { // 在这里实现密码的匹配逻辑 return rawPassword.toString().equals(encodedPassword); } } ``` 3. 在Spring Security的配置类中,配置自定义的UserDetailsService和PasswordEncoder。 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Autowired private PasswordEncoder passwordEncoder; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 配置使用自定义的UserDetailsService和PasswordEncoder auth.userDetailsService(userDetailsService) .passwordEncoder(passwordEncoder); } // 其他的配置和授权规则 } ``` 通过以上步骤的配置,就可以使用Spring Security和Redis进行自定义密码验证了。在Redis中存储用户信息,并在用户登录时从Redis中查询用户信息,并进行密码的加密和匹配。 ### 回答3: Spring Security是一个基于Spring框架的安全框架,用于帮助开发者实现应用程序的认证(Authentication)和授权(Authorization)功能。而Redis是一个内存数据库,被广泛应用于缓存、消息队列等场景。 在Spring Security中,可以自定义密码验证的方式来实现用户密码的认证。下面是一个基于Redis的自定义密码验证的示例: 首先,我们需要配置Redis作为Spring Security的认证数据源。可以使用Spring Data Redis来操作Redis。 ```java @Configuration @EnableRedisRepositories public class RedisConfig { @Bean public RedisConnectionFactory redisConnectionFactory() { // 配置Redis连接工厂 return new LettuceConnectionFactory(); } @Bean public RedisTemplate<Object, Object> redisTemplate() { // 配置Redis模板 RedisTemplate<Object, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory()); return template; } @Bean public UserDetailsRepository userDetailsRepository(RedisTemplate<Object, Object> redisTemplate) { // 自定义用户详情存储库,使用Redis作为数据源 return new RedisUserDetailsRepository(redisTemplate); } } ``` 上述代码中,我们配置了一个Redis连接工厂和一个Redis模板。然后,通过自定义的`UserDetailsRepository`接口,使用Redis作为数据源实现了用户详情的存储。 接下来,我们需要自定义一个认证提供者。可以实现`AuthenticationProvider`接口,并注入自定义的用户详情存储库。 ```java @Component public class RedisAuthenticationProvider implements AuthenticationProvider { private final UserDetailsRepository userDetailsRepository; public RedisAuthenticationProvider(UserDetailsRepository userDetailsRepository) { this.userDetailsRepository = userDetailsRepository; } @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { // 获取用户名和密码 String username = authentication.getName(); String password = authentication.getCredentials().toString(); // 从Redis中获取用户详情 UserDetails userDetails = userDetailsRepository.findByUsername(username); // 验证密码是否匹配 if (BCryptPasswordEncoder().matches(password, userDetails.getPassword())) { // 密码匹配,认证通过 return new UsernamePasswordAuthenticationToken(username, password, userDetails.getAuthorities()); } else { // 密码不匹配,抛出异常 throw new BadCredentialsException("Invalid username or password"); } } @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); } } ``` 上述代码中,我们通过重写`authenticate`方法实现了自定义的密码验证逻辑。首先,从Redis中获取用户的密码,并使用`BCryptPasswordEncoder`进行密码比对。如果密码匹配,就返回认证通过的`UsernamePasswordAuthenticationToken`对象;否则,抛出异常。 最后,我们还需要通过配置类来配置Spring Security。 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { private final RedisAuthenticationProvider redisAuthenticationProvider; public SecurityConfig(RedisAuthenticationProvider redisAuthenticationProvider) { this.redisAuthenticationProvider = redisAuthenticationProvider; } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 配置自定义的认证提供者 auth.authenticationProvider(redisAuthenticationProvider); } @Override protected void configure(HttpSecurity http) throws Exception { // 配置URL的访问权限 http .authorizeRequests() .antMatchers("/public/**").permitAll() .anyRequest().authenticated() .and() .formLogin().permitAll(); } } ``` 上述代码中,我们通过`configure`方法配置了自定义的认证提供者,并使用`antMatchers`方法来设置URL的访问权限。 以上就是一个基于Redis的自定义密码验证的示例。通过这个示例,我们可以了解如何使用Spring Security和Redis实现用户密码的认证功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值