SpringBoot基础设施配置(Redis序列化,JJWT新版)

Redis序列化配置

  • 使用
java 复制代码
@Autowired
private RedisTemplate<String,String> redisTemplate;

public void Message(){
    Set<String> token = redisTemplate.
            <String,String>opsForHash()
            .keys("token");
}
  • maven配置项
xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
java 复制代码
@Configuration
public class RedisConfig  {

    // redis序列化
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        // key序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        // value序列化
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
        // 连接工厂
        redisTemplate.setConnectionFactory(factory);
        return redisTemplate;
    }

}

JSON序列化配置

非常常用,包括MQ, 同步,发送等等

xml 复制代码
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>
java 复制代码
@Configuration
public class JSONConfig {

    public static final ObjectMapper mapper=new ObjectMapper();

    // 实体类转JSON
    public static<T> String ObjectTransformJSON(Class<T> object) throws JsonProcessingException {
        return mapper.writeValueAsString(object);
    }

    // JSON转实体类
    public static<T> T JSONTransformObject(String json,Class<T> object) throws JsonProcessingException {
        return mapper.readValue(json,object);
    }

}

HttpClient配置

为什么使用httpclient作为基础配置项,因为适用范围广,包括爬虫。而且能细粒度控制操作。

xml 复制代码
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.14</version>
    <scope>compile</scope>
</dependency>
java 复制代码
@Configuration
public class RequestConfig {

    // 会话保持功能
    private final CookieStore cookieStore = new BasicCookieStore();
    // 保证Httpclient使用同一个cookieStore
    private final CloseableHttpClient httpClient = HttpClients.custom()
            .setDefaultCookieStore(cookieStore)
            .build();

    // GET请求
    public  String HttpGet(String url, Map<String, String> params) throws IOException, URISyntaxException {

        //组装url
        URIBuilder builder = new URIBuilder(url);
        // 进行Params传参
        for (Map.Entry<String, String> entry : params.entrySet()) {
            builder.addParameter(entry.getKey(), entry.getValue());
        }
        //进行GET请求
        HttpGet httpGet = new HttpGet(builder.build());
        // 执行GET请求
        CloseableHttpResponse response = httpClient.execute(httpGet);
        // 返回JSON数据
        String result = EntityUtils.toString( response.getEntity());
        return result;
    }

    // POST请求
    public String HttpPost(String url,String json) throws IOException {
        // 进行POST请求
        HttpPost post = new HttpPost(url);
        // 进行Body传参
        StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
        // 设置实体类
        post.setEntity(entity);
        // 执行post请求
        CloseableHttpResponse response = httpClient.execute(post);
        // 返回JSON结果
        String result = EntityUtils.toString(response.getEntity());
        return result;
    }
}

web配置

webmvcConfigurer组件非常多常记

java 复制代码
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    // cors跨域
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowCredentials(true)
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedOrigins("http://localhost", "https://your-domain.com")
                .allowedHeaders("*")
                .exposedHeaders("Authorization")
                .maxAge(3600);
    }
    
    // 配置拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new WebInterceptor())
                .addPathPatterns("/*")
                .excludePathPatterns("/login");
    }
    
}

拦截器配置

springmvc的拦截器和tomcat的过滤器本质上实现的功能是一样。但是有几点注意一下,

  1. Filter 属于 Servlet 规范,由 Tomcat 等 Servlet 容器管理,执行在 DispatcherServlet 之前,能覆盖所有 Servlet 请求,包括静态资源和非 Spring MVC 的请求。
  2. Interceptor 属于 Spring MVC,由 DispatcherServlet 调用,只能作用于进入 Spring MVC 的 Handler 请求,且能拿到 HandlerMethod、访问 Spring 容器上下文
  3. Tomcat 是 Servlet 容器,和 Spring MVC 没有绑定关系。纯 Servlet 项目也可以跑在 Tomcat 上;Spring MVC 也可以跑在 Jetty/Undertow 或外部 Tomcat 上。Spring Boot 只是把两者自动装配在一起,方便开发。
  4. Filter 的注册不属于 Spring MVC 配置体系,在 Spring Boot 中应通过 FilterRegistrationBean 或 @WebFilter注册,而不是 WebMvcConfigurer;WebMvcConfigurer 只负责拦截器、消息转换器等 MVC 组件
java 复制代码
@Configuration
@Slf4j
public class WebInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    if(request.getHeader("Authorization")!=null){
            Set<String> token = redisTemplate.
                    <String,String>opsForHash()
                    .keys("token");

            for (String t : token) {
                if(JJWTConfig.parseToken(t)){
                    return true;
                };
            }

        }
        return  false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

JJWT配置

  • 之前的JJWT文章有点老了
xml 复制代码
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.12.5</version>
</dependency>
java 复制代码
@Component
@Configuration
public class JJWTConfig {


    private  static String secretKey;

    /** 强类型 SecretKey,自动校验长度 */
    private static final SecretKey SECRET_KEY =
            Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));

    public static String tokenSecretKey(){
        return secretKey;
    }

    // 生成token
    public static String generateToken(String username, String password, Map<String, Object> extraClaims) {
        // 0.12.0--0.13.0版本 不需要手写Header了
        // 载荷只存储用户信息
        HashMap<String,String> claims = new HashMap<>();
        claims.put("username", username);

        return Jwts.builder()
                 // 载荷
                .subject("Authorization Token") // 主题
                .issuer(username) //发行人
                .issuedAt(new Date()) // 签发时间
                .notBefore(new Date()) // 生效时间
                .expiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 7)) //失效时间
                .claims(claims) //自定义
                .id(UUID.randomUUID().toString()) //jwt唯一ID
                 // 签名
                .signWith(SECRET_KEY, Jwts.SIG.HS256)
                .compact();
    }

    /**
     * 解析 Token,
     */
    public static Boolean parseToken(String token) {

        Jws<Claims> claims = Jwts.parser().verifyWith(SECRET_KEY).build().parseSignedClaims(token); //解析Token
        System.out.println(claims.getPayload()); // 只能返回自定义的载荷
        System.out.println(claims.getHeader()); //返回JWT头部信息
        System.out.println(claims.getSignature()); // 返回签名
        return true;
    }

}
相关推荐
吃饱了得干活1 小时前
RabbitMQ 原理解析(下):存储、集群与可靠投递
后端·rabbitmq
SelectDB1 小时前
某头部保险公司基于 SelectDB 的统一 OLAP 架构实践
后端
ServBay2 小时前
ServBay 1.33.0 来了:AI Gateway 一键接管主流 AI CLI 与多模型
后端·aigc·ai编程
行者全栈架构师2 小时前
Spring Boot 接入 MaxKey 单点登录:6 个内部系统,一次登录全通行
java·vue.js·后端
JuiceFS2 小时前
卓驭:百 PB 级智驾数据存储架构演进
后端·自动驾驶
鱼弦2 小时前
跨模态迁移的极限:语言模型的逻辑能力能否完全迁移到视觉?
后端
ModStart2 小时前
写歌、翻唱、可编辑乐谱,YuE2-3B 在 AIGCPanel 一键跑通
后端
故作春风2 小时前
elpis-core 核心从入门到理解
后端·架构·node.js
LEE2 小时前
前端转型全栈 01:数据建模,前端最大的盲区
前端·javascript·后端