如何从同一Servlet中递归调用Servlet

3
我希望能够递归调用一个servlet,直到我的操作完成。我需要这样做的原因是我的托管服务对所有RPC调用都有一个必须满足的硬性截止日期。因此,我需要将操作分解成可管理的块,并为每个块递归调用servlet,直到操作完成。
我觉得下面的代码应该可以工作,但当HttpURLConnection被打开和连接时,它没有调用servlet。也没有抛出任何错误。任何帮助将不胜感激。
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class ServletExample extends HttpServlet {

HttpServletRequest request;

public void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

    request = req;

    String strRequestIndex = request.getParameter("requestIndex");
    int intRequestIndex = 0;

    if (strRequestIndex != null) {
        intRequestIndex = Integer.parseInt(strRequestIndex);
    }

    if (intRequestIndex < 10) {
        try {
            callSameServlet(intRequestIndex);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

private void callSameServlet(int requestIndex) throws Exception {

    URL recursiveUrl = new URL(request.getRequestURL().toString()
            + "?requestIndex=" + (requestIndex + 1));

    HttpURLConnection connection = (HttpURLConnection) recursiveUrl
            .openConnection();

    connection.setRequestMethod("POST");
    connection.setDoInput(true);
    connection.setDoOutput(true);
    connection.setUseCaches(false);
    connection.connect();

    DataOutputStream dos = new DataOutputStream(
            connection.getOutputStream());

    dos.flush();
    dos.close();

}

}

在 callSameServlet 中,您使用 POST 请求,但覆盖了 HttpServlet.doGet() 方法。这样做正确吗? - PeterMmm
2
如果调用1执行调用2,那么调用1不需要等待调用2完成吗?除非我漏掉了什么,否则你的策略是有缺陷的。 - Buhb
1个回答

2
关于您提出的技术问题: URLConnection 是延迟执行的。在您的代码中,URLConnection#getOutputStream() 只返回一个句柄以写入请求体。您需要使用URLConnection#getInputStream()来实际触发HTTP请求并获取响应体。

另请参阅:


但是,您的代码中还有更多问题:

您正在触发POST请求,但是您的servlet中没有定义doPost()方法。您需要触发普通的GET请求或者实现doPost()。但是这将通过调查上面链接中描述的获得的错误响应来明显。

此外,您的servlet不是线程安全的。您永远不应将请求/会话范围的数据声明/分配为servlet的实例变量。阅读此答案以了解更多信息。

最后,您有考虑过使用RequestDispatcher#include()吗? 这将在内部处理并节省您触发HTTP请求的成本/开销。

request.getRequestDispatcher("servleturl").include(request, response);

接下来,您可以使用请求属性而不是请求参数。顺便说一句,整个功能需求并没有多大意义。我只会在您想要递归执行的代码上使用forwhile循环。但那是一个不同的问题。


+1:你的回答第二部分和我对此的想法非常相似。 - Tomas Narros
感谢您的帮助。我尝试使用RequestDispatcher,但是收到了一个InvalidState错误。看起来响应已经被提交,因此我无法执行任何操作,例如转发或重定向响应。 - Fishbone
1
在你所提出的问题中,代码还有更多内容。在最后一次迭代之前,不应该提交响应。 - BalusC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接