Java 如何忽略不耐烦用户的多次点击?

Java 如何忽略不耐烦用户的多次点击?,java,rest,tomcat,jersey,Java,Rest,Tomcat,Jersey,我有一个查询来回答远程客户端的标准请求。标准,即它不从服务器外部获取任何参数。无论何时 任何人都可以向URL提交请求,例如,他/她在响应的主体中获得reply.xml的内容, 取决于数据库当时提供的内容。 reply.xml的内容仅在服务器上的数据库内容中更改,在任何外部内容上都不会更改 比如谁进行查询,在哪个输入上等等,因此不从客户机获取参数。我甚至没有检查任何身份验证——我们把一切都留给防火墙 因此,我编写了一个@POST方法,比如query(),以便在发送到的请求中调用,并传递结果。我用了

我有一个查询来回答远程客户端的标准请求。标准,即它不从服务器外部获取任何参数。无论何时 任何人都可以向URL提交请求,例如,他/她在响应的主体中获得
reply.xml
的内容, 取决于数据库当时提供的内容。
reply.xml
的内容仅在服务器上的数据库内容中更改,在任何外部内容上都不会更改 比如谁进行查询,在哪个输入上等等,因此不从客户机获取参数。我甚至没有检查任何身份验证——我们把一切都留给防火墙

因此,我编写了一个
@POST
方法,比如
query()
,以便在发送到的请求中调用,并传递结果。我用了
Jersey
,一切都符合规格,除了

请求应该是跨时间独占的。 也就是说,一次应该处理一个请求——除非服务器没有运行由我的方法
query()
调用的查询进程,否则随后的用户单击应该会得到一条HTTP状态为309的消息

如何做到这一点?我试着做出
query()
service
@PUT
而不是
@POST
响应,得到了相同的结果

也许是关于这个话题的一个天真的问题。但是,我对Restful服务不是很熟悉

我可以通过在令牌上执行线程来控制一次只运行一个查询,并使同步请求接收HTTP 309。但是,必须有更好、更简单的方法在服务器上实现这一点

我用的是Tomcat 8,Jersey 1.19

蒂亚

注:我已经阅读了其他一些有用的讨论

//=====================

编辑:

哪个用户提交查询在任何时候都没有任何区别

假设
userA
提交了一个查询。当该查询仍在运行时,即在
query()
返回对
userA
的响应之前,
userB
提交了一个查询
userB
应该得到一个309——仅仅因为当时正在处理一个查询

无论
userA
=
userB
还是
userA
userB
在这里都是无关紧要的,都应该返回309,因为其中一个查询请求正在运行。这是用户唯一一次获得309

//==============================================

编辑-2:


我了解带有并发控制的解决方案。我猜有一个使用Restful特性。这是一个相当学术性的问题。

我认为你的观点是错误的。多次单击的用户是使用前端客户端连接到服务器的用户。因此,由客户机来确保不会发生多次单击。Javascript完全可以抵御这种请求

话虽如此,应您的要求:事实上,309应该被退回。这是一个并发问题。
如果我正确阅读了您的规范,那么它与正在执行的数据库查询有关。 考虑下面的代码:

result = do_database_thing();
out = make_up_result(result);
return out;
根据这些规范,唯一的要求是在dou数据库上。如果补货结果很慢,则允许多个请求。因此,自然的解决方案是对数据库使用锁定。如果它应该包含整个query()方法(即不是数据库查询本身),那么尽早请求锁,最后释放锁。 然后代码变成:

boolean locked = get_lock();
if(!locked) return 302;
result = do_database_thing();
release_lock();
out = make_up_result(result);
return out;
  • @Koos Gadella说客户机应该阻塞是正确的 第二个请求,直到响应到达。让我解释一下为什么这是最好的做法在架构上,它与关注点相关。服务器没有上下文意识到为什么两个请求并行到达。因此,依靠带外知识来知道并行请求是不好的。任何带外知识都会产生耦合,这意味着如果你改变系统的一部分工作方式,你就必须改变另一部分。RESTful架构很流行,因为它们减少了耦合。如果同一用户登录到两个客户端,则系统将中断。您永远不希望构建具有这种类型的客户机-服务器耦合的系统

  • 关于服务器的责任,良好的编码实践发挥作用,最好的做法是确保服务不会受到来自用户的多个并行请求的阻碍。缓存可能是你的朋友。根据查询参数,可以将响应写入磁盘上的缓存文件。客户端将始终使用HTTP 303重定向到缓存文件URL。可以使用304 Not Modified,这样客户端就不必下载两次答案。在这个场景中,唯一的带外知识是HTTP规范的正确实现,该规范具有良好的规定性和健壮性

  • 如果服务过载,相应的响应代码似乎是503

    由于服务器临时过载或维护,服务器当前无法处理请求。这意味着,这是一种暂时的情况,延迟一段时间后会得到缓解。如果已知,延迟的长度可以在Retry After标头中指示。如果没有在之后重试,客户端应该像处理500响应一样处理响应

         Note: The existence of the 503 status code does not imply that a
         server must use it when becoming overloaded. Some servers may wish
         to simply refuse the connection.
    
  • 既然您是从这里指导我的,那么您似乎想知道正确的RESTful方法。这将比上面的解决方案更复杂,我猜你不想走这条路,但它就在这里

    如果服务器需要与客户机通信请求正在执行以及请求完成时,则需要为这些概念创建资源。这感觉很奇怪,因为它们的概念存在于HTTP中,在更高的级别(架构气味)重新实现它们是很奇怪的

  • 客户将