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

标签 asynchronous jetty servlet-3.0 ssi

我正在尝试实现一个异步 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/

相关文章:

java - MessageBrokerServlet 与 XmlWebAppInitializer 方法

java - 使用 servlet 3.0 的 JBoss 6 session 安全特性的问题

java - 等待 ServerSocket accept() 将套接字置于 "listen"模式

python - 扭曲/执行异步http请求

javascript - 跨站脚本有帮助吗?

java - 我在 Spring 使用加载时间编织。我如何在 jetty 中设置类加载器?

java - Jetty WebSocketException 无法调用方法

java - 使用java servlet 3.0文件上传,如何获取最大文件大小值

python - pg.内部错误 : SSL SYSCALL error: EOF detected

java - 如何在 Android 上建立异步 URL 连接?