我正在尝试实现一个异步 servlet,它将接收最终用户的请求,将其传递到后端服务器并获取响应。
到目前为止,这听起来像是 Jetty 的 ProxyServlet
的一个非常标准的应用程序。
现在,不同之处在于我的后端将使用 include 语句(有点像 Server-Side-Includes)进行响应,我需要对其进行解析、查询后端并插入到最终用户响应流中的适当位置。
您将如何实现?我特别好奇在 onResponseContent
回调期间解析和触发中间请求,据我所知,它可能包含也可能不包含完整响应(因此可能只包含 include 语句的一部分)。
为了说明,这是我目前拥有的:
@WebServlet(name = "MyServlet",
urlPatterns = {"/my/outbounduri/*"},
initParams = {
@WebInitParam(name = "proxyTo", value = "/servlet/backend")
}
)
public class MyHandler extends ProxyServlet {
@Override
protected void customizeProxyRequest(HttpServletRequest srequest,
HttpServletResponse sresponse ) {
// add custom headers for the backend
}
@Override
protected void onResponseContent(HttpServletRequest request,
HttpServletResponse response, Response proxyResponse,
byte[] buffer, int offset, int length, Callback callback) {
try {
// instead of passing the content on, we need to catch
// include statements
// response.getOutputStream().write(buffer, offset, length);
callback.succeeded();
} catch (Throwable x) {
callback.failed(x);
}
}
@Override
protected void onResponseSuccess(HttpServletRequest request,
HttpServletResponse response, Response proxyResponse) {
AsyncContext asyncContext = request.getAsyncContext();
asyncContext.complete();
}
}
最佳答案
如果您在内容代理期间修改内容,请使用 Jetty 10.x(或更新版本)及其 org.eclipse.jetty.proxy.AsyncMiddleManServlet
.
注意:这是全新的功能,在实现过程中肯定会有一些缺点。
这是一个专门的 AsyncProxyServlet
旨在简化修改来自客户端的请求内容和/或来自远程服务器的响应内容的复杂性。 (当代理的两端有不同的 Transfer-Encoding 时,这尤其复杂)
在您的用例中,从覆盖 AsyncMiddleManServlet.newServerResponseContentTransformer(HttpServletRequest clientRequest, HttpServletResponse proxyResponse, Response serverResponse)
开始并让它返回 ContentTransformer
的新实例执行此转换所需逻辑的设计。
实现您自己的 ContentTransformer
它在 .transform(ByteBuffer input, boolean finished, List<ByteBuffer> output)
中做了它需要做的事情
从 input
中阅读您可以阅读的内容,一旦你有东西要写,做一个output.add(modified)
.关注finished
标志,因为它可以让您知道何时收到了最后一位输入内容。
另外请注意,如果您需要控制从客户端请求端到远程服务器端的 URL 差异,请覆盖 String rewriteTarget(HttpServletRequest clientRequest)
方法,读取客户端请求信息,返回修改后的远程URL字符串。
关于asynchronous - 如何使用异步 servlet 修改代理响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28694124/