在应用 运行 时从 .txt 更新哈希集

Update hashset from .txt while app is running

目标是阻止访问 IP 地址列表中的页面。此列表在文件 list.txt 中。 我制作了根据请求检查 IP 的服务,并使用“不需要的”地址的 HashSet,但子目标是“即时捕获”这个 list.txt。我的意思是:如果我向这个文件添加一些 IP,它应该被阻止而无需重新启动应用程序。而且我不知道如何解决这个问题,因为我的应用程序仅在重新启动后才刷新此列表。我的代码如下

    @Service
public class BlackListService {

    public Set<String> loadBlackList() {
        java.util.Set<java.lang.String> blackList = new HashSet<>();
        InputStream resource = null;
        try {
            resource = new ClassPathResource(
                    "blacklist.txt").getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource))) {
            blackList = reader.lines().collect(Collectors.toSet());
            for (java.lang.String address:
                    blackList) {
                System.out.println(address);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return blackList;
    }

    public boolean isNowAllowedIP(Set<String> blackList, String requestIP) {
        return blackList.contains(requestIP);
    }

}

和控制器:

@Controller
public class MainController {

    private final BlackListService blackListService;

    public MainController(BlackListService blackListService) {
        this.blackListService = blackListService;
    }

    @GetMapping("/")
    public String mainPage(HttpServletRequest request, Model model) {
        Set<String> blackList = blackListService.loadBlackList();

        if (blackListService.isNowAllowedIP(blackList, request.getRemoteAddr())) {
            Logger logger = Logger.getLogger("Access logs");
            logger.warning("Access disallowed");
            model.addAttribute("message", request.getRemoteAddr() + ": Access disallowed");
            return "index";
        }
        model.addAttribute("message", "Access allowed");
        return "index";
    }

}

有人可以帮助实现这个“子目标”吗?

您需要的是一个经常性的后台作业,它将在您更改黑名单后重新加载它。此 blog 将讨论使用 Spring 进行此操作的“现代”方法。

  • 在程序启动和首次加载时保存文件的最后修改时间。请参阅 this 查看文件修改时间。
  • 将后台作业安排为每分钟 运行(或 5 分钟或任何足以满足您需要的频率)。
  • 当作业 运行s 检查文件的当前上次更新时间,如果它与保存的时间不同,那么是时候重新加载您的列表了。

在 loadBlackList() 中,您正在从类路径中读取资源。这可能是选择一个内置到您的 jar 文件中的文件或不是您正在编辑的文件的构建目录?我会尝试更改 loadBlackList() 以使用 FileReader 和文件系统上的路径而不是类路径中的路径而不是 InputStreamReader。