spring cloud通过zuul网关结合redis进行权限校验

springboot+springsession+redis+zuul实现网关session共享以及zuul的动态配置 springboot-zuul-session-redis 1、springboot+zuul实现session共享 2、zuul实现动态配置 springboot+zuul实现session共享 1、说明 springsession+redis+springboot使用上一个repository就可以了。我们这里关注zuul的配置。 2、zuul的默认配置,引入zuul的依... 阅读详情

一.用户操作权限校验

1.环境准备

1.1 首先是开发环境的准备:

导入redis的jar包

	<!--redis存储-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>
1.2 yml中zuul的配置
server:
  port: 8010
spring:
  application:
    name: zuul-center #给服务起名
  profiles:
    active: innerTest
  servlet:
    multipart:
      max-request-size: 1000MB
      max-file-size: 1000MB
eureka:
  client:
    serviceUrl:
      defaultZone : http://eurekaServer1.com:8000/eureka,http://eurekaServer2.com:8001/eureka
    registry-fetch-interval-seconds: 5
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 6000 # 熔断超时时长:6000ms
  threadpool:
    default:
      coreSize: 500
      maximumSize: 1000
      allowMaximumSizeToDivergeFromCoreSize: true
      maxQueueSize: -1
feign:
  hystrix:
    enable: true
ribbon:
  ConnectTimeout: 2000 # ribbon链接超时时长
  ReadTimeout: 2000 # ribbon读取超时时长
  MaxAutoRetries: 0  # 当前服务重试次数
  MaxAutoRetriesNextServer: 1 # 切换服务重试次数
  OkToRetryOnAllOperations: false # 是否对所有的请求方式都重试,只对get请求重试
management:
  server:
    add-application-context-header: true
  endpoints:
    web:
      exposure:
        include: '*'

#进行token校验的url地址,全部小写
authfilter:
  ignoreUri: /user/sysuser/login,/user/sysuser/sendcode ,/user/sysuser/checkoutcode, /user/sysuser/getverify,/user/sysuser/checkverify

zuul:
  prefix: /api  #给网关加上前缀
  sensitive-headers: Access-Control-Allow-Origin
  routes:
    服务名1: /user/** #服务1映射到/user/**
    服务名2: /zhzd/** #服务2
    服务名3: /support/** #服务3的前缀
 

  ribbonIsolationStrategy: THREAD
  host:
    maxTotalConnections: 1000
    maxPerRouteConnections: 100
    socket-timeout-millis: 120000
    connect-timeout-millis: 120000

---
spring:
  profiles: innerTest
  redis:
    database: 0
    host: 192.168.1.199
    port: 6379
    password: XXX
    block-when-exhausted: true
    jedis:
      pool:
        max-idle: 200
        max-active: 200
        max-wait: -1
        min-idle: 0
    timeout: 10000
2.下面是具体代码

编写一个类AuthFileter继承ZuulFilter

package com.zhzd.zuulcenter.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.faw.jetta.diagnosisCommon.constant.RedisConstants;
import com.faw.jetta.diagnosisCommon.enums.ExceptionEnum;
import com.faw.jetta.diagnosisCommon.exception.ProjectException;
import com.faw.jetta.diagnosisCommon.http.HttpResult;
import com.faw.jetta.diagnosisCommon.utils.CookieUtils;
import com.faw.jetta.diagnosisCommon.utils.JsonUtils;
import com.faw.jetta.diagnosisCommon.utils.ResultUtils;
import com.faw.jetta.diagnosisCommon.utils.StringUtil;
import com.faw.jetta.pojo.diagUserPojo.DTO.SysMenuDTO;
import com.faw.jetta.pojo.diagUserPojo.DTO.SysRoleDTO;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.netflix.zuul.http.ServletInputStreamWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.validation.constraints.NotBlank;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

/**
 * 用户登录Token拦截器
 */
@Slf4j
@Component
public class AuthFilter extends ZuulFilter {
    @Value("${authfilter.ignoreUri}")
    private List<String> ignoreUri;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    //无权限时的提示语
    private static final String INVALID_TOKEN = "登录信息无效,请重新登录";
    private static final String INVALID_USERID = "用户信息无效,请重新登录";
    private static final String USERINFOREDISKEY = "user:login:dto:";

    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        String uri = request.getRequestURI().toLowerCase();
        //log.info("uri="+uri);
        //判断是否需要拦截
        if (request.getHeader("content-type") != null && request.getHeader("content-type").indexOf("multipart/form-data") > -1) {
            return false;
        }
        if (ignoreUri.contains(uri)) {
            return false;
        } else {
            if (request.getMethod().equals("OPTIONS")) {
                return false;
            }
            return true;
        }
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        try {
            //先从 cookie 中取 token,cookie 中取失败再从 header 中取,两重校验
            //通过工具类从 Cookie 中取出 token
            String token;
            String tokenCookie = CookieUtils.getCookieValue(request, "x-auth-token");
            String tokenHeader = request.getHeader("x-auth-token");
            token = tokenHeader;
            if (token == null || StringUtils.isEmpty(token)) {
                token = tokenCookie;
            }
            verifyToken(requestContext, request, token);
            //从redis中获取用户登陆信息, 用来校验用户的访问权限
            //1.获取到访问路径
            String requestURI = request.getRequestURI();
            //2.获取到用户登陆信息
            String userId = stringRedisTemplate.opsForValue().get(RedisConstants.loginUid + token);
            String userDTOJson = stringRedisTemplate.opsForValue().get(RedisConstants.loginUserDTO + userId);
            JSONObject jsonObject = JSONObject.parseObject(userDTOJson);
            JSONArray roleDTOListJson = jsonObject.getJSONArray("roleList");
            List<SysRoleDTO> roleDTOList = JsonUtils.jsonToList(roleDTOListJson.toJSONString(), SysRoleDTO.class);
            List<SysMenuDTO> menuDTOList = new ArrayList<>();
            //遍历角色集合, 给角色赋值
            for (SysRoleDTO sysRoleDTO : roleDTOList) {
                menuDTOList.addAll(sysRoleDTO.getSysMenuDTOList());
            }
            //校验是否具有该访问权限
            for (SysMenuDTO sysMenuDTO : menuDTOList) {
                String menuUrl = sysMenuDTO.getMenuUrl();
                if (StringUtils.isNotEmpty(requestURI)&&StringUtils.isNotEmpty(menuUrl)&&requestURI.equals(menuUrl)) {
                    return null;
                }
            }
            //TODO 没有权限访问时, 应该返回一个提示
            ResultUtils resultUtils = new ResultUtils<>();
            resultUtils.setCode(401);
            resultUtils.setMsg("没有权限访问");
            String responseJson = JsonUtils.objectToJson(resultUtils);
            requestContext.setResponseBody(responseJson);
        } catch (Exception e) {
            e.printStackTrace();
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
            log.error("非法访问,未授权,地址:{}", request.getRemoteHost(), e );
        }
        return null;
    }

    /**
     * 从Redis中校验token
     */
    private void verifyToken(RequestContext requestContext, HttpServletRequest request, String token) {
        //需要从cookie或header 中取出 userId 来校验 token 的有效性,因为每个用户对应一个token,在Redis中是以 TOKEN_userId 为键的
        String userIdFromCookie = CookieUtils.getCookieValue(request, "uid");
        String userIdFromHeader = request.getHeader("uid");

        //禁止前端直接从参数中传递uid参数,防止进行跨用户攻击
        /**
         String uid = request.getParameter("uid") ;//从参数中获取uid


         if(uid == null || StringUtils.isEmpty(uid))
         {
         uid = userIdFromHeader;
         }
         if(uid == null || StringUtils.isEmpty(uid))
         {
         uid = userIdFromCookie;
         }
         **/
        String uid = null;
        //如果传递了token,则要校验token的有效性
        if (token != null && !StringUtils.isEmpty(token)) {
            String redisUid = stringRedisTemplate.opsForValue().get(RedisConstants.loginUid + token);
            if (uid == null || StringUtils.isEmpty(uid)) { //客户端没有传递uid
                uid = redisUid;// 系统自动将token转成uid
                if (uid != null && !StringUtils.isEmpty(uid)) {
                    addUidParam(uid, requestContext, token);
                } else { //客户端传递了一个无效的token
                    setUnauthorizedResponse(requestContext, INVALID_TOKEN);
                }
            } else { //有token,有uid,验证二者是否一致
                if (redisUid.equalsIgnoreCase(uid)) {
                    addUidParam(uid, requestContext, token);
                } else { //传递的token 和uid不一致
                    setUnauthorizedResponse(requestContext, INVALID_USERID);
                }
            }
        } else { //没有传递token,放过,微服务进行验权
            addUidParam("0", requestContext, token);
        }
    }

    /**
     * 向请求信息中增加uid参数
     *
     * @param uid 用户uid值
     * @param ctx
     */
    private void addUidParam(String uid, RequestContext ctx, String sessionIdInHeader) {
        try {
            if (sessionIdInHeader != null && !StringUtils.isEmpty(sessionIdInHeader)) {
                ctx.addZuulRequestHeader("x-auth-token", sessionIdInHeader);
            }
            //获取Redis中的用户信息
            //TODO 现在dealerId和comId指的是一个id,提供给外部调用的是comId(整型id)
            String dealerId = "0";
            String comId = "0";
            String comIdStr = "0";
            String userType = "0";
            //整型userId用作门店请求头
            String userIdInt = "0";
            try {
                String userStr = stringRedisTemplate.opsForValue().get(USERINFOREDISKEY + uid);
                if (!StringUtils.isEmpty(userStr)) {
                    JSONObject object = JSONObject.parseObject(userStr);
                    dealerId = object.getString("dealerId");
                    comId = object.getString("companyIdInt");
                    comIdStr = object.getString("companyId");
                    userType = object.getString("userType");
                    userIdInt = object.getString("idInt");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            HttpServletRequest request = ctx.getRequest();
            String method = request.getMethod();
            log.info(String.format("%s >>> %s", method, request.getRequestURL().toString()));
            InputStream in = request.getInputStream();
            String body = StreamUtils.copyToString(in, Charset.forName("UTF-8"));
            // 如果body为空初始化为空json
            if (StringUtils.isBlank(body)) {
                body = "{}";
            }
            //log.info("body" + body);
            // 转化成json
            //JSONObject json = JSONObject.parseObject(body);
            if ("GET".equalsIgnoreCase(method)) {
                request.getParameterMap();
                Map<String, List<String>> requestQueryParams = ctx.getRequestQueryParams();
                if (requestQueryParams == null) {
                    requestQueryParams = new HashMap<>();
                }
                //1.将字符串型用户id放入head中
                List<String> uids = new ArrayList<>();
                uids.add(uid);
                requestQueryParams.put("uid", uids);

                //2.将整型用户id放入head中
                List<String> userIdInts = new ArrayList<>();
                userIdInts.add(userIdInt);
                requestQueryParams.put("userIdInt", userIdInts);
                //3.将dealerId(整型)放入head中
                List<String> dealerIds = new ArrayList<>();
                dealerIds.add(dealerId);
                requestQueryParams.put("dealerId", dealerIds);
                //4.将comId(整型)放入head中
                List<String> comIds = new ArrayList<>();
                comIds.add(comId);
                requestQueryParams.put("comId", comIds);
                //4.1将comIdStr(字符串类型放入head中)
                List<String> comIdStrList = new ArrayList<>();
                comIdStrList.add(comIdStr);
                requestQueryParams.put("comIdStr", comIdStrList);
                //5.将用户类型放入head中
                List<String> userTypes = new ArrayList<>();
                userTypes.add(userType);
                requestQueryParams.put("userType", userTypes);

                ctx.setRequestQueryParams(requestQueryParams);
            } else if ("POST".equalsIgnoreCase(method)) {
                //json.put("uid",uid);
                // byte[] reqBodyBytes = JSON.toJSONString(json).getBytes();
                byte[] reqBodyBytes = body.getBytes("UTF-8");
                Map<String, List<String>> requestQueryParams = ctx.getRequestQueryParams();
                if (requestQueryParams == null) {
                    requestQueryParams = new HashMap<>();
                }
                List<String> uids = new ArrayList<>();
                uids.add(uid);
                requestQueryParams.put("uid", uids);

                List<String> dealerIds = new ArrayList<>();
                dealerIds.add(dealerId);
                requestQueryParams.put("dealerId", dealerIds);

                List<String> comIds = new ArrayList<>();
                comIds.add(comId);
                requestQueryParams.put("comId", comIds);

                List<String> userTypes = new ArrayList<>();
                userTypes.add(userType);
                requestQueryParams.put("userType", userTypes);

                ctx.setRequestQueryParams(requestQueryParams);
                ctx.setRequest(new HttpServletRequestWrapper(request) {
                    @Override
                    public ServletInputStream getInputStream() throws IOException {
                        return new ServletInputStreamWrapper(reqBodyBytes);
                    }

                    @Override
                    public int getContentLength() {
                        return reqBodyBytes.length;
                    }

                    @Override
                    public long getContentLengthLong() {
                        return reqBodyBytes.length;
                    }
                });
            }
            // ctx.setSendZuulResponse(false);
        } catch (Exception e) {
            log.error("addUidParam", e);
        }
    }

    /**
     * 设置 401 无权限状态
     */
    private void setUnauthorizedResponse(RequestContext requestContext, String msg) {
        requestContext.setSendZuulResponse(false);
        requestContext.setResponseStatusCode(HttpStatus.OK.value());
        HttpResult vo = HttpResult.error();
        vo.setCode(401);
        vo.setMsg(msg);
        String result = JSON.toJSONString(vo);
        requestContext.setResponseBody(result);
    }
}

未完待续

Spring Cloud分布式网关实现框架深度解析与性能对比 分布式网关是微服务架构的“交通指挥官”,其选型与优化直接影响系统的稳定性和扩展性。Spring Cloud Gateway凭借其响应式模型和灵活的谓词机制,成为大多数Java项目的首选;而Zuul更适合历史遗留系统的平滑过渡。未来,随着云原生技术的普及,‌服务网格(如Istio)‌可能进一步解耦网关与业务逻辑,但现阶段Spring Cloud Gateway仍是平衡功能与性能的最佳实践。Spring Cloud Gateway官方文档Zuul GitHub仓库。 阅读详情

相关推荐

Spring-Cloud-Gateway介绍(上篇)

虽然Netflix 早就发布了最新的 Zuul 2.x,但 Spring Cloud 貌似没有整合计划。,而且Gateway是SpringCloud团队研发的,是亲儿子产品,值得信赖。“post”类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控**等有着非常重要的作用。以上是字节二面的一些问题,面完之后其实挺后悔的,没有提前把各个知识点都复习到位。Filter在**“pre”类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换。它由ID、目标URI、谓词集合和过滤器集合定义。

2401_84010176的博客 1111

Zuul网关学习,使用redis+ZuulFilter实现访问其他页面身份信息的验证

一、Zuul介绍 什么是Zuul? Spring Cloud Zuul是整合Netflflix公司的Zuul开源项目实现的微服务网关,它实现了请求路由、负载均衡、校验过 虑等 功能。 官方:https://github.com/Netflflix/zuul 什么是网关? 服务网关是在微服务前边设置一道屏障,请求先到服务网关,网关会对请求进行过虑、校验、...

cnsummerLi 797

springcloud网关拦截+redis+自定义token做登录验证操作

网上看到的token做起来都太复杂,介绍说耗费的内存较大,写的封装方法非常多,看来看去非常不方便,自己就借助token思想,和网关拦截器组合操作的登录验证机制。 1.下面这段代码就是用户请求,验证数据库是否有这个用户名和密码,用户登录成功与否,成功登录就生成token存储到redis里 package gsa.rest.datacenter.rest.login; import gsa.b...

dfBeautifulLive的博客 9852

服务网关 Zuul 与 Redis 结合实现 Token 权限校验

这两天在写项目的全局权限校验,用 Zuul 作为服务网关,在 Zuul 的前置过滤器里做的校验。 权限校验或者身份验证就不得不提 Token,目前 Token 的验证方式有很多种,有生成 Token 后将 Token 存储在 Redis 或数据库的,也有很多用 JWT(JSON Web Token)的。 说实话这方面我的经验不多,又着急赶项目,所以就先用个简单的方案。 登录成功后将 Token ...

weixin_33852020的博客 967

Spring Cloud Gateway 2.2.2 是 Spring Cloud 家族中的一个重要组件,它在1.x版本Zuul网关的基础上进行了增强和改进

Spring Cloud Gateway 2.2.2 是 Spring Cloud 家族中的一个重要组件,它在1.x版本Zuul网关的基础上进行了增强和改进。这个版本的网关提供了灵活的请求过滤器(Predicates)配置能力,允许开发者基于特定的URL路径、HTTP方法、头信息等条件来路由和控制请求。请注意,这只是一部分内置过滤器,实际可用的过滤器可能随着Spring Cloud Gateway版本的更新而增加。通过这种方式,你可以自定义过滤逻辑,对每个进入或离开网关的应用请求进行特定的操作。

[Blog][Domain] programb.blog.youkuaiyun.com 1637

Android11 关于三方应用获取su权限

SELinux,全称Security-Enhanced Linux,是一种基于Linux内核的安全机制。它通过强制访问控制(MAC)来增强Linux系统的安全性,如果不禁用SELinux,完成下面的修改可能会导致设备进入Recovery界面!adb shell getenforce 为Permissive(宽容模式),查看报错日志,发现是客户apk想使用su命令提权,但是没有权限!对于保护系统资源和防止未经授权访问非常有帮助!系统这边做修改,让su权限下放到三方应用.客户的apk运行报错。

sinat_37429535的博客 1901

面试总结3 Zuul工作流程、ningix具体过程、 IO流的适配器模式和装饰者模式、用prepredStament为什么能防止sql注入、Spring boot 与spring cloud的区别

总内容 Zuul工作流程? ningix具体过程 IO流的适配器模式和装饰者模式 为什么用prepredStament为什么能防止sql注入 Spring boot 与spring cloud的区别 接口中只能有抽象方法吗? 大根堆,小根堆解决Top k问题 排序算法的时间复杂度和稳定性和原地排 IO流读写文件以及要是文件不存在会抛出异常 redis数据类型 linux命令抓...

weixin_41847891的博客 886

隐藏技巧!用ArcGIS Pro像素编辑器实现PS级影像编辑(附地貌伪装案例)

本文深入探讨ArcGIS Pro像素编辑器的创意应用,从基础操作到高级影像处理实战,展示了其在城市规划、环境分析等领域的独特价值。通过详细的功能解析和地貌伪装等案例,帮助用户实现媲美专业图像处理软件的精细操作,提升GIS工作效率。

weixin_28520495的博客 335

SpringCloud 使用Zuul防止xss攻击和sql注入

SpringCloud -ZUULSpringCloud 使用Zuul防止xss攻击和sql注入导入zuul的jar包编写一个过滤器SqLinjectionFilter,继承ZuulFilter SpringCloud 使用Zuul防止xss攻击和sql注入 导入zuul的jar包 <!--zuul--> <dependency> ...

Alone5256的博客 3550

新手别怕!用‘东北天’和‘右前上’坐标系,5分钟搞懂惯性导航姿态矩阵(含Python验证代码)

本文通过‘东北天(ENU)’和‘右前上(RFU)’坐标系,详细解析惯性导航中的姿态矩阵概念。包含Python代码验证,帮助新手快速理解坐标变换、欧拉角及旋转矩阵的构建与应用,特别强调有限转动不可交换性与无限转动次序无关的区别。

weixin_29062255的博客 331

(赛事-2022)[re:Invent 2018]-002:通过分析log多次迭代优化奖励函数后- 最快7.6s / 圈

Deepracer training 流程

Rainbow 4711

如何快速掌握Spring Cloud API网关:从Zuul到Gateway的终极实战指南

Spring Cloud API网关是现代微服务架构中的核心组件,它作为所有外部请求的统一入口,负责路由转发、安全认证、限流熔断等关键功能。在CodeGuide项目中,作者小傅哥详细讲解了从Zuul到Spring Cloud Gateway的完整API网关实现方案,为Java开发者提供了清晰的学习路径。💡 ## 🔥 为什么需要API网关? 在微服务架构中,每个服务都有独立的API接口,客户

gitblog_00376的博客 682

动力锂电池-二阶RC模型等效电路-RLS参数辨识-Simulink

1.锂电池二阶RC等效电路模型

QQ1978009424的博客 1万+

面试基础---Spring Cloud 微服务架构中的网关:Spring Cloud Gateway 与 Zuul 深度解析

Spring Cloud Gateway 和 Zuul 都是优秀的微服务网关解决方案,各有其适用场景。Spring Cloud Gateway 凭借其高性能和灵活的功能,逐渐成为主流选择,而 Zuul 则更适合传统的 Spring MVC 项目。在实际项目中,选择哪种网关需要根据具体需求和团队技术栈来决定。通过本文的源码分析和案例讲解,希望能帮助读者更好地理解网关的实现原理,并在实际项目中灵活应用。参考文献Spring Cloud Gateway 官方文档Zuul 官方文档。

weixin_43290370的博客 1349

ECN实战指南:如何用SAP系统搞定工程变更(附库存处理避坑技巧)

本文详细解析了如何在SAP系统中高效执行工程变更通知(ECN),特别聚焦PP模块的操作流程与库存处理技巧。通过实战案例和系统操作指南,帮助制造业企业避免库存混乱和生产中断,实现从创建到生效的全流程管理。

m5n6o7的博客 1079

64.企业级案例(上)-金融行业DDD落地全流程支付系统-附架构演进图

本文以金融支付系统为例,完整展示了DDD在企业级项目中的落地流程。首先通过事件风暴识别核心业务领域,包括交易、渠道、账务等限界上下文。在战略设计中划分上下文边界,确定交易上下文为核心域。战术设计聚焦交易上下文,详细设计了支付单聚合、值对象和支付路由服务。架构实现采用CQRS+EDA模式,通过命令端处理交易,查询端异步更新读模型,并利用防腐层隔离外部渠道。案例展示了DDD从业务探索到架构实现的全过程,体现了其在复杂业务系统中的价值。

yonggeit的博客 3033

Spring cloud gateway 详解和配置使用(文章较长)

目录 spring cloud gateway 介绍 1. 网关是怎么演化来的 2. 网关的基本功能 3.关于Spring Cloud Gateway 4.Spring Cloud Gateway 功能特征 5.predicate简介 6.GatewayFilter 工厂介绍 7.集成Hystrix的断路器功能 8.请求限流 pom.xml application.ym...

荡漾 21万+

【一 扣子客户案例合集】【 1.3 识典古籍基于扣子智能助手的古籍数字化全流程技术解析】

古籍数字化智能处理系统全流程解析 本文详细介绍了基于扣子智能助手的古籍数字化解决方案,核心技术包括: 多层级架构设计:采用"云-边-端"三层次架构,整合高精度扫描设备与AI处理模块,实现从物理古籍到结构化数据的全流程自动化。 智能图像处理:通过12道预处理工序(包括畸变校正、污渍去除和对比度增强)处理古籍图像,采用改进的EAST算法和ViT模型实现高精度文字检测与识别,准确率达98.7%。 NLP增强处理:结合Transformer-XL预训练模型和N-gram语言模型进行文本校正,基于

商务合作|问题讨论|交流学习 请联系作者微信,加微信请务必注明来意,博客主页有联系方式 1440

Springcloud zuul和shiro结合

一.目标1.外部请求统一从网关zuul进入,并且服务内部互相调用接口要校验权限 2.cloud和shiro结合,达到单点登录,和集中一个服务完成权限管理,其他业务服务不需要关注权限如何实现 3.其他服务依然可以控制权限细粒度到接口,如在接口上使用@RequirePermisson等注解,方便开发 二.思路SpirngCloud zuul网关有两个作用,一个是分配路由,一个是过滤。 ...

weixin_30699465的博客 1101

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Spring Cloud API 网关 Spring Cloud Gateway

API 网关是一种设计模式,用于为客户端提供统一的接口。所有客户端的请求都会经过网关处理,然后转发到具体的后端服务。Spring Cloud Gateway 是一个强大且灵活的 API 网关解决方案,具有高性能、丰富的扩展能力以及与 Spring 生态的深度集成。在微服务架构中,Spring Cloud Gateway 能够很好地处理请求路由、认证授权、限流降级等功能,是实现企业级 API 网关的理想选择。

Flying_Fish_roe的博客 1325

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

网关Spring Cloud Gateway

Spring Cloud Gateway 是基于 Spring Boot 和 Spring WebFlux 构建的 API 网关,主要用于微服务架构中的流量管理和请求转发。它提供了动态路由、负载均衡、权限控制、限流等功能,能够替代传统的 Zuul 网关,并且性能更优。Spring Cloud Gateway 主要由 三大核心组件 组成:在 中定义路由规则: 解释:可以创建自定义过滤器来处理请求,例如记录日志:  Spring Cloud Gateway 的优势 基于 WebFlux,性能更高

gggfJJ的博客 696

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Spring-cloud---网关gateway

gateway 作为Spring Cloud官方推出的第二代网关框架,取代Zuul网关。 主要功能包括:路由转发、权限校验、限流控制 网关作为系统的入口,起到的作用: 协议转换,路由转发 流量聚合,对流量进行监控,日志输出 作为整个系统的前端工程,对流量进行控制,有限流的作用 作为系统的前端边界,外部流量只能通过网关才能访问系统 可以在网关层做权限的判断 可以在网关层做缓存 初探大...

咆哮大熊猫的博客 411

微服务网关

一、前言 随着微服务的兴起,基于其业务耦合性低、负载能力强、服务边界清晰等优点,大家纷纷使用微服务架构来实现新系统或进行老系统的改造。微服务在带来诸多好处的同时,也有一些问题需要解决,比如:如何做到有效拆分、减少服务间调用,如何统一管理所有服务的接口,如何进行自动化部署等。本文阐述微服务的API网关的一些主要功能,并例举了几种常用的网关,最后结合spring cloud微服务框架...

nsxqf的博客 1万+

微服务_Spring Cloud_OpenFeign与网关

OpenFeign 是声明式 Web 服务客户端,用于微服务之间远程 HTTP 调用,特点: 只需要定义接口 + 添加注解,就能像调用本地 Service 一样调用远程微服务接口,写法风格和 Controller 完全一致,屏蔽了 RestTemplate、原生 HttpClient 拼接 URL、处理请求的繁琐过程。

2501_93103214的博客 269

微服务组件2(网关、分布式事务)

网关是微服务架构中的关键组件,作为系统入口,负责请求的路由、安全校验、限流、监控等功能。常见的网关类型包括API网关和服务网关,常用的技术有Nginx、Zuul和Spring Cloud Gateway。网关的核心功能包括路由转发、身份验证、限流、协议转换和安全防护。在Spring Cloud Gateway中,路由由ID、目标URI、断言和过滤器组成,断言用于判断请求是否匹配路由,过滤器用于修改请求或响应。网关登录校验可以通过JWT、OAuth2.0或自定义过滤器实现。限流方式包括计数器、滑动窗口、令牌桶

sv 888
上一篇: 使用mybatisPlus驼峰映射出现问题, 数据库字段没有采用下划线的方式
下一篇: 添加远程github仓库时报错 Warning: Permanently added the RSA host key for IP address 52.74.223.119
意田天
博客等级 码龄7年 41粉丝 89原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

意田天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值