likes
comments
collection
share

重学 Java 设计模式:实战外观模式

作者站长头像
站长
· 阅读数 15

重学 Java 设计模式:实战外观模式

在 Java 开发中,设计模式是一种十分常见的编程思想,它可以帮助我们解决很多实际开发中的问题。本篇文章将介绍一种常见的设计模式——外观模式,并结合实际的开发场景进行讲解。本文将以 SpringBoot 开发门面模式中间件,实现一个统一控制接口白名单的场景来展示外观模式的应用。

什么是外观模式?

外观模式是一种结构型设计模式,它可以为一组复杂的子系统提供一个简单的接口。通过使用外观模式,我们可以将系统中的复杂逻辑隐藏起来,并对外提供简单的接口。外部调用者无需关心具体的执行细节,只需要调用外观方法即可。外观模式可以减少系统的耦合度,提高系统的可维护性和可扩展性。

SpringBoot 开发门面模式中间件

在实际的开发中,我们可能会遇到这样的需求:需要对系统中的接口进行控制,只允许某些特定的 IP 地址访问特定的接口,这时候,外观模式就可以帮助我们实现这个功能。

我们可以使用 SpringBoot 开发一个门面模式中间件,让中间件来完成接口的白名单控制。中间件会检查访问的 IP 地址是否在白名单列表中。如果是,则继续请求,如果不在,则直接返回错误信息。

接下来,我们将一步步地实现这个中间件,以介绍外观模式的应用。

中间件基本流程

在实现中间件之前,我们需要先确定中间件的基本流程。具体来说,我们需要实现一个方法 handle,这个方法需要根据配置的白名单列表,对传入的 HTTP 请求进行判断,如果 IP 地址在白名单列表中,则正常处理请求。否则,直接返回错误信息。代码如下所示:

public interface GatewayFilter {

    void handle(HttpServletRequest request, HttpServletResponse response, GatewayFilterChain filterChain) throws ServletException, IOException;

}

在这个方法中,我们需要调用 filterChain.doFilter 方法来处理请求,同时需要使用 response 对象来返回错误信息。

中间件的具体实现

现在,我们已经确定了中间件的基本流程,接下来,我们需要根据这个流程来实现具体的中间件。在这个例子中,我们使用了 SpringBoot 开发工具来实现代码的自动配置功能。

首先,需要创建一个 GatewayProperties 类来保存配置的白名单列表。

@ConfigurationProperties("gateway")
public class GatewayProperties {
    // 配置白名单列表
    private List<String> allowList = new ArrayList<>();

    public List<String> getAllowList() {
        return allowList;
    }

    public void setAllowList(List<String> allowList) {
        this.allowList = allowList;
    }
}

然后,需要创建一个 GatewayFilter 接口,并实现白名单过滤逻辑。

public class GatewayFilterImpl implements GatewayFilter {

    public static final String X_REAL_IP = "X-Real-IP";
    private List<String> allowList;

    public GatewayFilterImpl(List<String> allowList) {
        this.allowList = allowList;
    }

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, GatewayFilterChain filterChain) throws ServletException, IOException {
        String remoteAddr = request.getHeader(X_REAL_IP);
        if (validateIp(remoteAddr)) {
            filterChain.doFilter(request, response);
        } else {
            response.sendError(HttpStatus.UNAUTHORIZED.value(), "Your IP address is not allowed to access the API.");
        }
    }

    // 验证当前 IP 是否在白名单列表中
    private boolean validateIp(String remoteAddr) {
        if (allowList == null || allowList.isEmpty()) {
            return true;
        }

        return allowList.contains(remoteAddr);
    }
}

在这里,我们从请求头中获取了客户端的 IP 地址,并使用 validateIp 方法来判断这个 IP 是否在白名单列表中。如果符合要求,则调用 filterChain.doFilter 方法进行下一步处理。否则,直接返回错误信息。

最后,需要创建一个 GatewayAutoConfiguration 类,用于自动配置当前的中间件。

@Configuration
@ConditionalOnClass(GatewayFilter.class)
@ConditionalOnProperty(prefix = "gateway", name = "enabled", havingValue = "true", matchIfMissing = true)
@EnableConfigurationProperties(GatewayProperties.class)
public class GatewayAutoConfiguration {

    @Bean
    public GatewayFilter gatewayFilter(GatewayProperties gatewayProperties) {
        return new GatewayFilterImpl(gatewayProperties.getAllowList());
    }

    @Bean
    public FilterRegistrationBean registration(GatewayFilter gatewayFilter) {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(gatewayFilter);
        registration.addUrlPatterns("/*");
        registration.setName("gatewayFilter");
        registration.setOrder(Ordered.LOWEST_PRECEDENCE);
        return registration;
    }

}

在这个类中,我们使用 @ConditionalOnProperty 来控制中间件是否开启,使用 @ConfigurationProperties 来读取配置的白名单配置信息,并使用 GatewayFilterImpl 类来处理请求。

使用中间件

使用该中间件很简单,只需要在 application.properties 中配置白名单列表即可。例如:

# application.properties

gateway.enabled=true
gateway.allowList=127.0.0.1,192.168.1.2

在这里,我们配置了两个 IP 地址,分别是 127.0.0.1192.168.1.2。如果请求的 IP 地址不在这个列表中,则无法访问 API。

总结

外观模式是一种常见的设计模式,它可以为一组复杂的子系统提供一个简单的接口。通过使用外观模式,我们可以将系统中的复杂逻辑隐藏起来,并对外提供简单的接口,从而减少系统的耦合度,提高系统的可维护性和可扩展性。

在本文中,我们以 SpringBoot 开发门面模式中间件为例,展示了外观模式的应用。通过对请求进行白名单过滤,来限制客户端对接口的访问。通过合理地使用外观模式,我们可以减少开发工作量,提高代码的可重用性和可维护性。