【问题标题】:How to call servlet from java如何从java调用servlet
【发布时间】:2012-01-09 01:59:15
【问题描述】:

我在 JAR 中有一个无法更改的第三方 servlet。我已经扩展了该 servlet 并正常使用它,因为应该使用 servlet,客户端发出一个调用我的 servlet 的 HTTP 请求。

但是现在客户端想要一个自动服务,也就是说,我需要从 servlet 所在的同一个 webapp 向那个第三方 servlet 发出一些请求。

我查看了第三方 servlet 代码,但我没有找到绕过 servlet 的地方,因为 HttpServletRequest 和 HttpServletResponse 对象是从一个方法传递到另一个方法...基本上看来我需要重新实现所有第三方代码。

我找到但不满意的解决方案:

使用 HttpURLConnection 从 URL 调用 servlet: 我的常识是从 url 调用第三方 servlet 并不是最好的方法 去吧,除了增加的开销,我不想暴露第三方 小服务程序。从 url 调用我的 servlet 也会带来问题 会议和其他事情。

直接调用doGet:这似乎是不可能的,因为没有HttpServletRequest的实现和 HttpServletResponse。

使用 jMock 或类似的东西: 尚未探索此解决方案,但在实际中使用测试驱动库似乎是错误的 环境。

有人知道如何与第三方 servlet 交互吗?

编辑:

由于我的英语不是很好,而且我发现自己很难在这里解释自己,所以这里有一个示意图来尝试更好地解释

EDIT2:在与第三方制造商会面后,他们提出隔离我需要避免调用 servlet 的方法。如果你没有同样的运气,我确实检查了 gigadotBalusC 的答案。

【问题讨论】:

  • 你想用 servlet 做什么?答案将取决于它。既然你什么都没说,我认为你没有通用的解决方案。
  • “自动服务”是什么?
  • 将请求转发到该 servlet 不是一种选择?
  • @gigadot servlet 是一个复杂的第三方解决方案,可以做很多事情,基本上它就像一个报告实用程序。在这种情况下,我需要让 servlet 及时为我生成特定报告类型的报告(和其他参数),然后我不需要结果,但它们将保留在会话中,然后我会做另一个调用 servlet 以在会话中请求一个带有结果的 xls 文件。我不知道我是否解释得很好,但它是一个非常复杂的系统。
  • 您可以尝试使用 Servlet API 类的现有存根实现。有很多这样的实现,尽管它们通常是大型项目的一部分,例如 Spring Test。

标签: java servlets


【解决方案1】:

如果我正确理解您的问题,您已经实施或拥有为您生成报告的第三方 servlet。

现在您要做的是定期生成报告并存储在会话中,以便当用户想要获取报告时,他们可以使用另一个 servlet 检索它。

如果是这种情况,那么您希望该任务在您的服务器上定期运行。您将需要某种任务调度程序在您的服务器上运行,而该任务所做的只是向您的 servlet 发出一个 http 请求(这可以是 http GET 或 POST)。

【讨论】:

  • 有点像,但它类似于我找到的第一个解决方案,我必须公开 servlet(我不太热衷于这样做,因为它没有任何类型的操作系统安全性实现)并且对请求进行环回似乎非常正确。但似乎这将是唯一的出路。
  • 写一个过滤器来拒绝所有不是来自你自己的servlet的请求怎么样?
  • 如果您想使用会话,也请阅读 BalusC 的答案,因为它可能对用户不可见。
  • 但如果我必须进行环回,过滤器也会拒绝我的请求。我将不得不更多地考虑你的想法,它可以引导我一些
  • 你可以做一个过滤器,只拒绝不是来自你自己ip的请求。
【解决方案2】:

从 url 调用我的 servlet 也会带来会话和其他方面的问题。

如果这是唯一的问题,那么只需使用 CookieManager 在随后的 URLConnection 调用中维护 cookie(以及会话)。

// First set the default cookie manager.
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

// All the following subsequent URLConnections will use the same cookie manager.
URLConnection connection = new URL(url).openConnection();
// ...

connection = new URL(url).openConnection();
// ...

connection = new URL(url).openConnection();
// ...

另见:

【讨论】:

  • 这是有用的信息。它并不能完全解决问题,但我可以使用一些知识。我的会话问题更深入,因为它不是我必须关心的 http 会话,而是一个必须与用户名相关联的系统会话。可能必须为这只海豚创建一个特定的用户。
  • 您是否也想将当前正在运行的HttpSession 用于其他 servlet?换句话说,您是从 servlet 内部调用另一个 servlet? (这是我最初的理解,另见编辑历史,但是当我重新解释您问题中的“自动服务”短语时,我改变了主意和答案;当然,自动服务可以(应该)永远不会从内部启动servlet)。
  • 不,我正在尝试自己调用第三方 servlet。第三方 servlet 没有被映射(我的是,但它运行了很多在这种情况下不需要的代码),我可以将它映射为最后一个资源。但是我首先从哪里获得请求,因为没有对服务器的请求(因为正在运行的代码已经在服务器内部)。 //看我在问题中添加的示意图
  • 感谢您的帮助,幸运的是第三方提供了隔离我需要的方法。我将 gigadot 答案标记为正确,但由于我无法将两个答案都标记为正确,因此我在我的问题中添加了一个建议来检查您的答案。谢谢!
【解决方案3】:

您可以尝试将您的 servlet 逻辑分成几个阶段。获取请求/结果的入口点,处理发送的参数并生成输出的操作。

public void doGet(HttpServletRequest req, HttpServletResponse rsp){
    relay(rsp,act(req.getParameter("a"));
}

public static String act(String a){
    return "You provided: " + a;
}

public static void relay(HttpServletResponse rsp, String content){
    rsp.setResponseCode(200);
    rsp.getOutputStream().write(content.getBytes());
}

这让你可以调用 act(whatever) 来做你想做的事,然后用响应做你想做的事。如果返回字符串还不够,您可以创建任何您想要的返回类型,可能包含标题列表、响应代码和内容模板。

【讨论】:

  • 问题是我无法更改的第三方包内完成的部分......
猜你喜欢
  • 2014-03-28
  • 1970-01-01
  • 2011-03-16
  • 2012-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
相关资源
最近更新 更多