我正在尝试实现异步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();
}
}
答案 0 :(得分:6)
如果您在代理该内容期间修改内容,请使用Jetty 9.2.8.v20150217
及其新org.eclipse.jetty.proxy.AsyncMiddleManServlet
。
注意:这是全新的功能,实施中肯定会有一些瑕疵。
这是一个专门的AsyncProxyServlet
,旨在简化从客户端修改请求内容和/或从远程服务器修改响应内容的复杂性。 (当代理的两面具有不同的传输编码时,这尤其复杂)
在您的使用案例中,首先覆盖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字符串