更改 GET 页面请求上的数据(处理预加载请求)

2022-09-04 04:40:45

我有一个 Portlet。当 Portlet 加载时,在呈现第一个视图之前,在某些情况下需要调用一个存储库来更改数据库中的数据。我不会更详细地解释为什么这是必要的,关于这是一个设计缺陷的答案是没有帮助的。我知道这是一个设计缺陷,但我仍然想找出以下问题的替代解决方案:

此设置的问题在于,浏览器会发送预加载请求。例如,Portlet 所在的页面的 URL 是 /test-portlet。现在,当您在地址栏中键入它时,如果您在浏览器历史记录中有它,则浏览器会在向您建议时向页面发送GET请求。如果在解析第一个 GET 请求之前按 Enter 键,则浏览器会发送新的 GET 请求。这意味着 Portlet 接收 2 个单独的请求,它开始并行处理这些请求。第一个数据库过程可能工作正常,但考虑到数据库过程的性质,第二个调用通常会给出一个异常。

从Java应用程序处理上述问题的好方法是什么?

旁注:我正在使用Spring MVC。

一个可能的控制器的简单示例:

@RequestMapping
public String index( Model model, RenderRequest request ){
    String username = dummyRepository.changeSomeData(request.getAttribute("userId"));
    model.add("userName", username);
    return "view";
}

我对完全阻止第一次执行的解决方案感兴趣。例如,从浏览器不会触发的控制器重定向到POST的某种重定向。不确定它是否可行。


答案 1

使用锁,我认为你可以解决它,让secound请求等待第一个完成,然后处理它。我没有Java中的锁的经验,但我发现了另一个关于jave中文件锁的堆栈交换帖子:如何使用java锁定文件(如果可能)


答案 2

请参考这个答案,它可能会帮助你检测和忽略一些预加载请求。但是,您还应该确保“最坏情况”有效,也许可以使用@jpeg建议的锁定,但它可能就像在某个地方使用块一样简单。synchronize


推荐