如何从Java调用servlet

6
我有一个第三方servlet在JAR文件中,我无法更改它。我扩展了该servlet并像通常使用servlet一样使用它,客户端通过HTTP请求调用我的servlet。
但现在客户需要自动服务,也就是说,我需要从同一个Web应用程序向第三方servlet发出一些请求。
我查看了第三方servlet代码,但没有找到绕过servlet的地方,因为HttpServletRequest和HttpServletResponse对象是从方法传递到方法...基本上看起来我需要重新实现所有第三方代码。
解决方案我找到了,但不满意:
- 使用HttpURLConnection从URL调用servlet:我的常识告诉我,从URL调用第三方servlet不是最好的方法,除了增加开销外,我不想暴露第三方servlet。从URL调用我的servlet还会带来会话和其他问题。 - 直接调用doGet:这似乎是不可能的,因为没有HttpServletRequest和HttpServletResponse的实现。 - 使用jMock或类似的东西:尚未探索此解决方案,但在真实环境中使用测试驱动库似乎是错误的。
有人有什么想法如何与第三方servlet交互吗?
编辑:
由于我的英语不太好,我发现很难解释自己,所以这里有一个示意图,试图更好地解释
第三方制造商在会议后提供了隔离我需要避免调用servlet的方法。如果你没有像我一样幸运,那就看看gigadot和BalusC的答案吧。

你想用Servlet做什么?答案取决于它。由于你没有提供任何相关信息,我认为对你来说并没有通用的解决方案。 - gigadot
2
自动化服务。它是什么? - gigadot
将请求转发到该servlet不是一个选项吗? - Bhesh Gurung
@gigadot Servlet是一个复杂的第三方解决方案,可以完成许多任务,基本上就像报告工具。在这种情况下,我需要请求Servlet为特定的报告类型生成报告(以及其他参数),然后我不需要结果,但它们将保留在会话中,然后我将再次调用Servlet来请求带有会话结果的xls文件。我不知道我是否解释得清楚,但这是一个非常复杂的系统。 - Jose Antonio
你可以尝试使用现有的Servlet API类的存根实现。虽然通常它们是大型项目(如Spring Test)的一部分,但有许多这样的实现。 - axtavt
显示剩余5条评论
3个回答

1
如果我理解你的问题正确,你已经实现或者有一个第三方servlet可以为你生成报告。
现在你想要做的是定期生成报告并将其存储在会话中,这样当用户想要获取报告时,他们可以使用另一个servlet检索它。
如果是这种情况,那么您希望任务定期在您的服务器上运行。您需要一些类型的任务计划程序在您的服务器上运行,任务所做的只是向您的servlet发出http请求(可以是http GET或POST)。

这有点类似,但与我找到的第一个解决方案相似,我必须暴露servlet(我不太愿意这样做,因为它没有任何安全类型实现),使用请求进行回环似乎非常正确。但似乎这将是唯一的解决方法。 - Jose Antonio
写一个过滤器来拒绝所有不来自你自己的servlet的请求,这个怎么样? - gigadot
如果您想使用会话(session),请阅读BalusC的答案,因为它可能对用户不可见。 - gigadot
但是如果我需要进行回环操作,过滤器也会拒绝我的请求。我需要更多地思考你的想法,它可能会带我去某个地方。 - Jose Antonio
你可以创建一个过滤器,只拒绝不来自你自己 IP 的请求。 - gigadot
谢谢你的帮助,幸运的是第三方提供了隔离我需要的方法。我将你的答案标记为正确,以便帮助其他人。谢谢! - Jose Antonio

1
如果从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会话,还需要关注系统会话,并将其与用户名关联起来。可能需要为此创建一个特定的用户。 - Jose Antonio
你想要同时使用当前正在运行的 HttpSession 用于其他的 servlet 吗?换句话说,你是从一个 servlet 中调用另一个 servlet 吗?(这是我最初理解的,也可以看编辑历史,但当我重新解释了你问题中的“自动服务”短语时,我改变了我的想法和答案;自动服务当然不能从 servlet 中启动)。 - BalusC
不,我正在尝试单独调用第三方servlet。第三方servlet没有映射(我的有,但它运行了很多不必要的代码),我可以将其映射为最后的资源。但是,首先我在哪里获取请求,因为没有向服务器发送请求(因为正在运行的代码已经在服务器内部)。//请参见我在问题中添加的示意图。 - Jose Antonio
感谢您的帮助,幸运的是第三方提供了隔离我所需方法的解决方案。我将Gigadot的回答标记为正确答案,但由于无法同时标记两个答案,我已在问题中添加了一个建议,以查看您的答案。谢谢! - Jose Antonio

0
你可以尝试将你的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)来完成你想做的事情,然后对响应进行处理。如果只返回一个字符串不够,你可以制作任何你想要的返回类型,可能是一个包含标题列表、响应代码和内容模板的东西。


问题在于这是第三方包内部完成的部分,我无法更改... - Jose Antonio

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