如何将 requestdispatcher 转发到远程 URL
Posted
技术标签:
【中文标题】如何将 requestdispatcher 转发到远程 URL【英文标题】:How to forward the requestdispatcher to a remote URL 【发布时间】:2013-01-05 17:50:35 【问题描述】:我有一个 html 页面 http://www.mywebapp.com/sample.html
用于远程服务器。我在同一个 HTML 表单中将 HTML URL 作为隐藏表单传递,
<form action="/myservlet?userid=12345" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="Submit">
<input type="hidden" name="url" value="http://www.mywebapp.com/sample.html"/>
</form>
在我的 servlet 中,我得到了隐藏的 URL http://www.mywebapp.com/sample.html
并将其存储为
String fieldValue = http://www.mywebapp.com/sample.html
现在当我尝试RequestDispatcher
并将页面转发到这样的隐藏 URL 时,
RequestDispatcher rd = req.getRequestDispatcher(fieldValue);
rd.forward(req, resp);
收到ERROR 404
。
谁能给我一个解决这个问题的想法。
已编辑
我真正想做的是,从远程服务器一个 HTML 页面将请求我的 REST Web 服务。 Web 服务的响应将在 JSON 输出中。现在我想将此 JSON 响应发送到请求的 HTML 表单(即发送到远程服务器 HTML 页面)
任何人都可以提出解决此问题的想法。 您的帮助将不胜感激。
【问题讨论】:
***.com/a/3916286/3767784 虽然 @fanaj 链接不包含描述 - 我强烈建议您查看它,因为它描述了您需要如何使用 307 重定向,因此“客户端将在新 URL 上重新应用相同的 POST 查询参数“其他重定向不这样做。我正在研究同样的问题 【参考方案1】:您不能将请求转发到您的 web 应用程序外部的 URL。您可能想改为发送到此 URL 的重定向。见HttpServletResponse.sendRedirect()
。
见Difference between JSP forward and redirect
【讨论】:
如果我使用HttpServletResponse.sendRedirect()
得到不应该发生的 302 状态码。您能否建议我如何响应作为 HTML 页面的远程服务器。我的响应包含 JSON 输出
如何响应 HTML 页面的远程服务器:我不明白这是什么意思。你想达到什么目标。
一个远程 HTML 表单正在向我的 REST Web 服务发送数据。我将响应作为 JSON 输出提供给请求的远程 HTML 表单。这是我正在尝试的,希望你得到它。现在我的问题是我想将 JSON 输出发送到请求的远程 HTML 表单
@sathya 老实说,这听起来有点乱——我还没有尝试过,但您必须将 JSON 响应编码为您将重定向到的 URL 上的参数,我只是看不到工作(逃跑将是一场噩梦)。调用 RESTful 服务的页面应该使用 javascript 根据需要处理来自该服务的 JSON 响应。
@NickHolt 非常感谢尼克的建议。【参考方案2】:
如果您绝对需要转发请求而不是重定向(例如,如果远程 URL 只能由服务器访问而用户不能访问),则可以进行自己的转发。在您的 servlet 中,您可以向远程 URL 发出请求,并将该请求中的 InputStream 写入您的 servlet 中的 OutputStream。不过,您显然希望查找并处理请求中的任何错误,并确保正确关闭流。您还需要手动将请求中的任何参数转发到新参数。
基本方法是:
URL url = new URL("http://www.externalsite.com/sample.html");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
String postParams = "foo="+req.getParameter("foo");
DataOutputStream paramsWriter = new DataOutputStream(con.getOutputStream());
paramsWriter.writeBytes(postParams);
paramsWriter.flush();
paramsWriter.close();
InputStream remoteResponse = conn.getInputStream();
OutputStream localResponder = resp.getOutputStream();
int c;
while((c = remoteResponse.read()) != -1)
localResponder.write(c);
remoteResponse.close();
localResponder.close();
conn.disconnect();
这显然不能处理您示例中的多部分请求,但它为您提供了有关如何实现所需内容的基本概念。我建议使用 Apache HTTP 组件而不是 HttpURLConnection 来执行请求,因为它会使带有文件的多部分请求更容易实现(我想您必须使用 HttpURLConnection 手动创建多部分/表单数据主体) .可以在How can I make a multipart/form-data POST request using Java? 找到发出请求的示例。可以通过调用 getContent() 从 HttpEntity 获取 InputStream(在示例中相当于 conn.getInputStream())。
使用 Apache Commons IO IOUtils.copy() 方法也可以更轻松地将 InputStream 写入 OutputStream。
编辑: 可以使用 req.getInputStream() 获取原始请求正文并将其写入 paramsWriter.writeBytes() 但我没有尝试过,所以不能保证它会起作用。我不确定 req.getInputStream() 包含的 post 请求到底是什么。
【讨论】:
【参考方案3】:您无法转发到其他服务器。
您可以使用resp.sendRedirect(url)
http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletResponse.html#sendRedirect%28java.lang.String%29
该方法将返回 302 重定向到指定的 URL。
【讨论】:
是的,我可以理解它上升了 302,这就是为什么要尝试另一种方式。您能否建议我如何响应作为 HTML 页面的远程服务器。我的响应包含 JSON 输出 一个远程 HTML 表单正在向我的 REST Web 服务发送数据。我将响应作为 JSON 输出提供给请求的远程 HTML 表单。这是我正在尝试的,希望你得到它。现在我的问题是我想将 JSON 输出发送到请求的远程 HTML 表单以上是关于如何将 requestdispatcher 转发到远程 URL的主要内容,如果未能解决你的问题,请参考以下文章
Servlet请求转发RequestDispatcher接口
JAVA记录-Servlet RequestDispatcher请求转发
通过 Java 过滤器后使用 RequestDispatcher 转发
重定向(response.sendRedirect())与请求转发(RequestDispatcher.foward())