如何使用异步servlet修改代理响应?

mab*_*abi 1 asynchronous jetty ssi servlet-3.0

我正在尝试实现一个异步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();
    }
}
Run Code Online (Sandbox Code Playgroud)

Joa*_*elt 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字符串.