【基础架构设计】仿12306系统公共组件设计深度解析

仿12306系统学习

学习路线

12306 铁路购票系统学习总体分为三块:组件库开发、业务梳理以及业务系统开发。

【基础架构设计】仿12306系统公共组件设计深度解析_第1张图片

组件库开发

组件库的产出源于对公共功能的封装,避免了在不同项目之间相互复制代码的情况。当然,如果这种复制代码的方式出现问题,那么需要同时对所有项目进行改造,从成本和优雅设计的角度来看并不可取。

为了统一各个项目可能使用的公共内容,我们在这里规划了常用且通用的功能点,供大家使用,以提高编码效率。如果有一些好的想法,在通用的前提下,可以联系我们将其加入到各自语义的起始包中。

组件库的开发宗旨是汇总资源,更高效地提供业务敏捷开发的能力,后续的迭代也将遵循这一原则。目前,这只是一个起点,是整体规划的一部分,还有许多可以提升的空间。

目前已有组件如下,可能新增加的组件更新不及时,实际以代码库 /frameworks 目录下为准。

【基础架构设计】仿12306系统公共组件设计深度解析_第2张图片

业务梳理

在 12306 铁路购票系统中,包括会员、购票、订单、支付以及网关服务。

【基础架构设计】仿12306系统公共组件设计深度解析_第3张图片

GatewayServiceApplication<网关服务>

自定义局部过滤器

/**
 * SpringCloud Gateway Token 拦截器
 *
 * @公众号:马丁玩编程,回复:加群,添加马哥微信(备注:12306)获取项目资料
 */
@Component
public class TokenValidateGatewayFilterFactory extends AbstractGatewayFilterFactory<Config> {

    public TokenValidateGatewayFilterFactory() {
        super(Config.class);
    }

    /**
     * 注销用户时需要传递 Token
     */
    public static final String DELETION_PATH = "/api/user-service/deletion";

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            String requestPath = request.getPath().toString();
            if (isPathInBlackPreList(requestPath, config.getBlackPathPre())) {
                String token = request.getHeaders().getFirst("Authorization");
                // TODO 需要验证 Token 是否有效,有可能用户注销了账户,但是 Token 有效期还未过
                UserInfoDTO userInfo = JWTUtil.parseJwtToken(token);
                if (!validateToken(userInfo)) {
                    ServerHttpResponse response = exchange.getResponse();
                    response.setStatusCode(HttpStatus.UNAUTHORIZED);
                    return response.setComplete();
                }

                ServerHttpRequest.Builder builder = exchange.getRequest().mutate().headers(httpHeaders -> {
                    httpHeaders.set(UserConstant.USER_ID_KEY, userInfo.getUserId());
                    httpHeaders.set(UserConstant.USER_NAME_KEY, userInfo.getUsername());
                    httpHeaders.set(UserConstant.REAL_NAME_KEY, URLEncoder.encode(userInfo.getRealName(), StandardCharsets.UTF_8));
                    if (Objects.equals(requestPath, DELETION_PATH)) {
                        httpHeaders.set(UserConstant.USER_TOKEN_KEY, token);
                    }
                });
                return chain.filter(exchange.mutate().request(builder.build()).build());
            }
            return chain.filter(exchange);
        };
    }

    private boolean isPathInBlackPreList(String requestPath, List<String> blackPathPre) {
        if (CollectionUtils.isEmpty(blackPathPre)) {
            return false;
        }
        return blackPathPre.stream().anyMatch(requestPath::startsWith);
    }

    private boolean validateToken(UserInfoDTO userInfo) {
        return userInfo != null;
    }
}

Gateway 分类:局部过滤器全局过滤器

  • 局部过滤器(GatewayFilter):应用到单个路由或者一个分组的路由上。
  • 全局过滤器(GlobalFilter):应用到所有的路由上。

你可能感兴趣的:(java,开发语言)