jfinal main方法里操作数据库+redis

本文介绍了一种将数据库中的数据同步到Redis的方法,并提供了一个Java实现的示例。该示例通过切换不同的数据源,从两个不同的MySQL数据库读取数据,并将其存储到Redis中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近项目中需要写一个小程序 将数据库的数据转存到redis 中,下面是简单的demo 用到了两个数据源 一个redis
package com.xc.main;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.redis.Cache;
import com.jfinal.plugin.redis.Redis;
import com.jfinal.plugin.redis.RedisPlugin;

public class AppRedis {
static int m=0;//此变量是为了切换数据源
public static void main(String[] args) {
RedisPlugin rp = new RedisPlugin("lenglh_hal", "127.0.0.1");
rp.start();
Cache redis=Redis.use();
if(m==0){
String jdbcUrl = "jdbc:mysql://localhost:3306/xc-cool-app?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull";
DruidPlugin druidPlugin = new DruidPlugin(jdbcUrl,"root", "");
druidPlugin.start();
ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
arp.start();

List<Record> list=Db.find("select deviceId,status from xc_cool_device");
for(Record r:list){
redis.set(r.get("deviceId"), r.get("status"));
System.err.println(r.get("deviceId")+"===>"+ r.get("status"));
}

String sql="select r.id ,d.deviceId,r.channelId,r.compareType,r.threshold from xc_cool_alarm_rule r "
+" INNER JOIN xc_cool_device d on d.id=r.deviceId";
List<Record> rules=Db.find(sql);
for(Record r:rules){
Map<Object, Object> rule = new HashMap<Object,Object>(); 
rule.put("ruleId", r.get("id"));
rule.put("type", r.get("compareType"));
rule.put("threshold", r.get("threshold"));
rule.put("status", false);
rule.put("value", "-999");
redis.hset("R_"+r.getStr("deviceId")+"_"+r.getInt("channelId"), r.get("id"), rule);
System.err.println("R_"+r.getStr("deviceId")+"_"+r.getInt("channelId")+"---"+r.get("id")+"--"+rule);
}
arp.stop();
m=1;
}
   //切换数据源
if(m==1){
String jdbcUrlHal = "jdbc:mysql://localhost:3306/xc-cool-hal?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull";
DruidPlugin druidPluginhal = new DruidPlugin(jdbcUrlHal,"root", "");
druidPluginhal.start();
ActiveRecordPlugin arphal = new ActiveRecordPlugin(druidPluginhal);
arphal.start();

List<Record> channel=Db.find("select deviceId,channelId,status from xc_cool_rds_channel");
for(Record r:channel){
redis.set("C_"+r.getStr("deviceId")+"_"+r.getInt("channelId"), r.get("status"));
System.err.println("C_"+r.getStr("deviceId")+"_"+r.getInt("channelId")+"===>"+ r.get("status"));
}
m=3;
arphal.stop();
}
}
}

  666导航网    可以自由收藏管理个人常用网址的便捷上网工具 
<think>嗯,用户想要用Spring Security Web、JWT和Redis来搭建用户登录模块,需要完整的代码。首先,我得确认用户的需求。他们可能是在开发一个需要用户认证的Web应用,希望实现基于Token的无状态认证,同时利用Redis管理Token的有效性。可能的应用场景包括分布式系统或者需要横向扩展的服务,需要确保用户登录状态的高效管理。 首先,我应该考虑整个架构的组成部分。用户模块通常包括用户注册、登录、登出,以及权限控制。使用Spring Security作为安全框架,JWT用于生成和验证Token,Redis用来存储有效的Token或者黑名单,以增强安全性,比如实现Token的主动失效。 接下来,需要确定各个组件之间的交互流程。用户登录时,系统验证用户名密码,生成JWT并存入Redis,返回给客户端。之后的请求需要携带JWT,Spring Security的过滤器会验证Token的有效性,并检查Redis中是否存在,以确定是否允许访问。登出时,将Token加入黑名单,防止继续使用。 然后,考虑各个技术点的实现细节。比如,如何集成Spring Security的配置,自定义UserDetailsService来从数据库加载用户,JWT工具类的编写,以及Redis操作。需要处理密码加密,使用BCryptPasswordEncoder。还要处理异常情况,比如Token过期、无效等情况,返回相应的错误信息。 可能遇到的问题包括Spring Security的过滤器链配置,确保JWT过滤器在合适的位置;Token的生成和验证过程中的签名算法是否正确;Redis的键值设计,比如存储Token时使用用户ID作为键的一部分,方便管理和清除。另外,需要考虑Token的刷新机制,但用户可能暂时不需要,所以暂时可以不实现。 现在,需要分步骤构建代码结构。首先,项目的依赖管理,比如pom.xml中添加Spring Security、JWT、Redis相关的依赖。然后,配置Spring Security,禁用默认的Session管理,配置密码编码器,设置权限规则。编写JWT过滤器,继承OncePerRequestFilter,在请求头中提取Token并进行验证。验证通过后,将用户信息存入SecurityContextHolder。 用户实体类和Repository需要与数据库交互,这可能需要使用Spring Data JPA。自定义UserDetailsService实现,从数据库加载用户信息。然后,编写认证逻辑,在登录接口中调用AuthenticationManager的authenticate方法,生成Token并保存到Redis。 在控制器层,需要处理登录、登出、测试接口。登出接口需要将当前Token加入Redis黑名单,并在后续请求中检查黑名单中的Token是否有效。 还需要配置RedisTemplate,确保能够正确操作Redis中的数据。异常处理方面,使用Spring的全局异常处理来捕获认证和授权相关的异常,返回统一的响应格式。 测试时需要注意的事项包括正确设置请求头中的Authorization字段,携带Bearer Token。登出后,该Token应无法再次使用。另外,Redis中存储的Token需要有合理的过期时间,与JWT的过期时间一致或更长,避免Token失效后Redis中仍有残留。 可能还需要考虑安全性问题,比如HTTPS的使用,Token的存储位置(如HttpOnly的Cookie),但用户的问题主要集中在功能实现上,这些高级安全措施可能暂时不需要深入。 最后,确保代码结构清晰,模块分明,各部分职责明确。提供完整的代码示例,帮助用户理解每个部分的作用,并能够根据自身需求进行调整。</think>以下是一个基于Spring Security + JWT + Redis的完整登录模块实现方案,包含关键代码和配置说明: --- ### 一、项目结构 ``` src/main/java ├── com.example.demo │ ├── config │ │ ├── SecurityConfig.java │ │ └── RedisConfig.java │ ├── controller │ │ └── AuthController.java │ ├── filter │ │ └── JwtAuthenticationFilter.java │ ├── pojo │ │ ├── dto │ │ │ ├── LoginDTO.java │ │ │ └── ResponseResult.java │ │ ├── entity │ │ │ └── User.java │ ├── repository │ │ └── UserRepository.java │ ├── service │ │ ├── impl │ │ │ └── UserDetailsServiceImpl.java │ │ └── LoginService.java │ ├── utils │ │ ├── JwtUtil.java │ │ └── RedisCache.java │ └── DemoApplication.java ``` --- ### 二、核心代码实现 #### 1. 依赖配置(pom.xml) ```xml <dependencies> <!-- Spring Security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- JWT --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> <!-- Redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- 其他必要依赖... --> </dependencies> ``` #### 2. Security配置类 ```java @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .csrf().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() .antMatchers("/user/login").anonymous() .anyRequest().authenticated() .and() .addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); return http.build(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public JwtAuthenticationFilter jwtAuthenticationFilter() { return new JwtAuthenticationFilter(); } } ``` #### 3. JWT工具类 ```java @Component public class JwtUtil { private static final String SECRET_KEY = "your-secret-key"; private static final long EXPIRATION = 86400000; // 24小时 public String generateToken(String username) { return Jwts.builder() .setSubject(username) .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION)) .signWith(SignatureAlgorithm.HS512, SECRET_KEY) .compact(); } public String getUsernameFromToken(String token) { return Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody() .getSubject(); } } ``` #### 4. Redis工具类 ```java @Component public class RedisCache { @Autowired private RedisTemplate<String, Object> redisTemplate; public void set(String key, Object value) { redisTemplate.opsForValue().set(key, value); } public Object get(String key) { return redisTemplate.opsForValue().get(key); } public Boolean delete(String key) { return redisTemplate.delete(key); } } ``` #### 5. JWT认证过滤器 ```java public class JwtAuthenticationFilter extends OncePerRequestFilter { @Autowired private JwtUtil jwtUtil; @Autowired private RedisCache redisCache; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String token = request.getHeader("Authorization"); if (StringUtils.hasText(token) && token.startsWith("Bearer ")) { token = token.substring(7); try { String username = jwtUtil.getUsernameFromToken(token); // 检查Redis中是否存在有效token String redisKey = "login:" + username; String redisToken = (String) redisCache.get(redisKey); if (redisToken != null && redisToken.equals(token)) { UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>()); SecurityContextHolder.getContext().setAuthentication(authentication); } } catch (Exception e) { // Token验证失败处理 } } filterChain.doFilter(request, response); } } ``` #### 6. 登录接口实现 ```java @RestController public class AuthController { @Autowired private AuthenticationManager authenticationManager; @Autowired private JwtUtil jwtUtil; @Autowired private RedisCache redisCache; @PostMapping("/user/login") public ResponseResult<String> login(@RequestBody LoginDTO loginDTO) { // 执行认证 Authentication authentication = authenticationManager.authenticate( new UsernamePasswordAuthenticationToken( loginDTO.getUsername(), loginDTO.getPassword() ) ); // 生成Token String username = authentication.getName(); String token = jwtUtil.generateToken(username); // 存储到Redis String redisKey = "login:" + username; redisCache.set(redisKey, token); return ResponseResult.success(token); } } ``` --- ### 三、关键配置说明 1. **Redis配置**: ```java @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; } } ``` 2. **用户认证服务**: ```java @Service public class UserDetailsServiceImpl implements UserDetailsService { @Autowired private UserRepository userRepository; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userRepository.findByUsername(username); if (user == null) { throw new UsernameNotFoundException("用户不存在"); } return new org.springframework.security.core.userdetails.User( user.getUsername(), user.getPassword(), new ArrayList<>() ); } } ``` --- ### 四、功能流程 1. **登录流程**: ``` 客户端请求 -> 校验用户名密码 -> 生成JWT -> 存入Redis -> 返回Token给客户端 ``` 2. **请求鉴权流程**: ``` 客户端携带Token -> 过滤器验证Token有效性 -> 检查Redis是否存在 -> 设置SecurityContext -> 访问受保护资源 ``` 3. **登出实现**: ```java @PostMapping("/user/logout") public ResponseResult<Void> logout() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String username = authentication.getName(); redisCache.delete("login:" + username); return ResponseResult.success(); } ``` --- ### 五、注意事项 1. 需要配置`application.yml`中的Redis连接信息 2. 生产环境需要配置HTTPS 3. 建议使用更复杂的密钥管理方案 4. 可添加Token刷新机制 5. 需要实现用户角色权限控制时可扩展`UserDetails` 以上实现方案可根据具体业务需求进行扩展和调整,建议结合Spring Boot Actuator进行健康监控。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值