如何使用 Spring/Servlets 支持批量 Web api 请求处理
Posted
技术标签:
【中文标题】如何使用 Spring/Servlets 支持批量 Web api 请求处理【英文标题】:How to support batch web api request processing using Spring/Servlets 【发布时间】:2016-09-26 19:17:38 【问题描述】:我们的 Web API 使用 RESTEasy 编写。我们希望以Google Batch request 处理的工作方式为批处理请求提供支持。
以下是目前使用的方法,
我们有一个过滤器,它接受传入的多部分请求。然后这个过滤器创建多个模拟请求和响应对象,然后使用这些模拟请求调用chain.doFilter。
public class BatchRequestProcessingFilter extends GenericFilterBean
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException
HttpServletRequest request = (HttpServletRequest)req;
MockHttpServletRequest[] mockRequests = BatchRequestProcessorUtils.parseRequest(request);
MockHttpServletResponse[] mockResponses = new MockHttpServletResponse[mockRequests.length];
for(int i=0 ; i <= mockRequests.length ; i++ )
chain.doFilter(mockRequests[i], mockResponses[i], chain);
BatchRequestProcessingUtils.populateResponseFromMockResponses(res, mockResponses);
MockHttpServletResponse
类返回一个虚拟的OutputStream
,它包装了ByteArrayOutputStream
。
BatchRequestProcessorUtils
解析多部分请求并返回模拟请求,该模拟请求包装了实际请求,但返回实际请求正文的拆分正文中指定的标头。
我找不到任何支持批处理请求处理的现有库。所以我的问题是,这是支持批处理请求的正确方法还是应该使用任何标准方法?
请注意,我们使用的是 Tomcat 8。
【问题讨论】:
我目前正在研究相同的主题。我目前会以完全相同的方式进行。结果如何?这是解决方案还是您以不同的方式解决了问题? 关于MockHttpServletRequest
:您是在使用实际的测试框架进行生产吗?这似乎不对。
@HerrDerb MockHttpServletRequest 只是一个占位符,实际类名不同。此外,这可行,但当然不会对此过滤器中创建的请求执行过滤器。
【参考方案1】:
萨钦·戈拉德。我没有听说过这样的库,但我认为你的方法是合理的。如果我必须解决这个问题,我会这样想:
-
在我们的 HTTP servlet 中,我们只能单独处理请求,这就是为什么我们应该将所有要发送的请求包装到客户端的另一个单独请求中的原因。
因为在我们的服务器端我们只有一个请求,所以我们应该解开我们放入其中的所有请求。而且,因为我们不知道如何处理批处理机制中的每个请求 - 我们将通过所有过滤器/servlet 发送它。这也是将我们的批处理过滤器放在顺序第一位的原因。
最终,当所有请求都处理完毕后,我们应该将响应发送回客户端。同样,要做到这一点,我们应该将所有响应包装成一个。
在客户端,我们应该解开响应并将每个响应发送到一些可以处理它的对象。
在我看来应该有两种机制:
-
客户端的批处理发送方,负责收集和包装请求、解包响应并将它们发送到他们的处理器(处理常规响应的方法)。
服务器端的批处理器,负责解包请求以及收集和包装响应。
当然,这两个部分可能是耦合的(例如共享“Wrapper”模块),因为我们必须以相同的方式包装和展开对象。
另外,如果我致力于它,我会尝试在我用来发送常规请求的类上开发客户端机制,就像装饰器一样。在这种情况下,我可以在需要时随时替换常规/批处理模式。
希望我的意见对你有所帮助。
【讨论】:
@leksandr-semyannikov,这个批处理过滤器不应该在顺序的第一个位置,至少它应该在 authentication 之后(不验证用户 10 次包含 10 个 API 调用的批次),但肯定应该在 授权 之前进行 - 因为我们需要分别检查每个 API 调用的权限。 还需要考虑应用程序的架构,因为 authentication / authorization 可能是基于拦截器和/或基于过滤器的。正如@sachin-gorade 所提到的,主要问题是,不幸的是,他在问题过滤器链中描述的方法不起作用。 @Aleksandr 感谢您的回答,我们在客户端做了同样的事情。以上是关于如何使用 Spring/Servlets 支持批量 Web api 请求处理的主要内容,如果未能解决你的问题,请参考以下文章
python 如何使用SQL Alchemy编译INSERT ... ON DUPLICATE KEY UPDATE并支持批量插入。