【问题标题】:Access GWT POST parameters via servlet?通过 servlet 访问 GWT POST 参数?
【发布时间】:2013-08-30 14:23:43
【问题描述】:

我正在创建一个将由 POST 请求访问的 GWT 应用程序,其中包含我关心的参数(用户 ID 等)。

到目前为止,我所做的所有阅读都让我相信我应该创建一个 servlet(我使用的是 tomcat)来处理 POST 参数,然后转发到我的 GWT 应用程序。我已经完成了这项工作,但我仍然无法将此数据传递给我的应用程序。我已经看到了 3 种建议的方法:

  • 将数据保存到上下文中:我现在可以使用此功能,但我对此并不满意。当访问 servlet 时,我解析参数并更新我的 GWT Web 应用程序的上下文,然后转发到我进行 RPC 调用以读取上下文的应用程序。这符合我的要求,但是当多个用户尝试同时访问应用程序并且上下文快速变化时,这会产生竞争条件。
  • 在会话中存储数据:我尝试将数据保存到我的 servlet 中的请求会话中,然后在我的 RPC 中访问该会话,但我总是得到一个新的/不同的会话,所以我假设我在搞砸这个在某处。

在 servlet 上保存会话

HttpSession session = request.getSession();
session.setAttribute("test", "testValue");
response.sendRedirect(response.encodeRedirectURL("/GWT_Application"));

在 RPC 中访问会话

HttpSession session = this.getThreadLocalRequest().getSession();
session.getAttribute("test");

这会返回一个不同的会话,从而导致“test”属性为空。

  • 在 URL 中传递数据:我的应用程序将在 iframe 中打开,这意味着 Window.location.getParameter() 将不可用。

任何帮助将不胜感激!我仍在学习 GWT 和一般的 Web 开发,所以不要害怕指出任何明显或愚蠢的错误。

谢谢!

解决方案

我发现我的会话方法存在什么问题:我之前尝试在其中保存会话数据的 servlet 位于与我的 GWT 应用程序不同的 tomcat Web 应用程序中。将它们移动到同一个网络应用程序解决了我的问题,它现在可以工作了。我不确定,但我猜这是一个问题,因为重定向到另一个 Web 应用程序会切换上下文。我将概述我的整个方法,希望这可以在以后节省其他人:

将您的 servlet 代码放在 GWT 项目的服务器文件夹中:

package GWTApplication.server;
public class myServlet extends HttpServlet {
  protected void doPost(HttpServletRequest request, HttpServletResponse response) {
    session.setAttribute("myAttribute", request.getParameter("myParam");
    // handle rest of POST parameters
    response.sendRedirect(response.encodeRedirectURL("/GWTApplication");
  }
}

在您的 GWT 应用程序的 web.xml 中映射 servlet:

<servlet>
  <servlet-name>myServlet</servlet-name>
  <servlet-class>GWTApplication.myServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>myServlet</servlet-name>
  <url-pattern>/myServlet</url-pattern>
</servlet-mapping>

这个 servlet 现在应该可以通过 .../GWTApplication/myServlet 访问了

接下来制作一个标准的 RPC。无论您将在服务器上的 ServiceImpl 类中调用什么方法:

HttpSession session = this.getThreadLocalRequest().getSession();
return session.getAttribute("myAttribute");

最后,在 GWT 应用程序的 onModuleLoad() 方法中进行 RPC 调用。回顾一下:

  1. 将原始 POST 请求发送到 servlet
  2. 将 POST 参数保存到会话变量中
  3. 重定向到 GWT 应用程序
  4. onModuleLoad()中进行RPC调用
  5. 读取ServiceImpl类中的会话变量

【问题讨论】:

  • 不太确定我是否理解这里的问题。你能详细说明一下流程吗?
  • 有一个现有的应用程序(Sakai - 一个学习管理系统),它向我的 GWT 应用程序发出 POST 请求,并将其显示在现有应用程序的 iFrame 中。我基本上只是想找到将 POST 参数传递给我的 GWT 应用程序的最佳方法。这有帮助吗?

标签: java session gwt tomcat servlets


【解决方案1】:

您可以通过 GWT 中的 RPC 调用与 servlet 对话

您需要在 GWT 应用程序的起点进行 RPC 调用。

将该数据设置为服务器端会话,并在extendsRemoteServiceServlet. 的 GWT 调用中获取会话数据 servceImpl

例子:

YourServiceImpl extends RemoteServiceServlet  {

@ovveride
doGet(){
  //you can access session here
}

@ovveride
doPost(){
//you can access session here
}

@ovveride
doPut(){
//you can access session here
}

----your other methods




}

我在这里写的一个简短的例子:How to make an GWT server call(GWT RPC?)

【讨论】:

  • 您是否建议我将参数存储到我的 servlet 上的会话中,然后在 GWT RPC 调用中访问会话?我已经尝试过了,但无法访问同一会话。
  • @quickity 能否请您说明您是如何访问session 的??如果您无法访问session,这很奇怪,并且会导致越来越多的问题。
  • 我更新了我的问题,以显示我如何在我的 servlet 上保存会话、重定向到我的 GWT 应用程序,然后在我的 RPC 中访问会话。
  • 这真的很难相信..如果您不犹豫,请检查两个会话的 ID 吗??
  • 我已经将两者都打印到了我的 tomcat 日志中,它们总是不同的。也许我没有在正确的地方调用我的 RPC?我正在 GWT 应用程序的 onModuleLoad(入口点)中进行 RPC 调用。对吗?
【解决方案2】:

由于RemoteServiceServlet 扩展了HttpServlet,您只需覆盖doPost() 方法即可访问您的POST 请求。不要忘记调用super.doPost() 编辑:这不起作用,因为该方法已在AbstractRemoteServiceServlet 中完成,因此不能被覆盖。

此外,GWT Servlets 使用专有的 GWT RPC 格式发布数据。在此处阅读有关该格式以及如何解释它的更多信息:GWT RPC data format

编辑

您可以在扩展RemoteServiceServletServiceImpl 类中覆盖几种方法:

  1. public String processCall(String payload) 将为您提供传入请求的字符串表示形式。
  2. protected void onAfterRequestDeserialized(RPCRequest rpcRequest) 将为您提供一个 RPCRequest 对象,该对象具有一组参数以及被调用的方法。
  3. public void service(ServletRequest request, ServletResponse response) 将为您提供 HTTP 请求的所有属性。

【讨论】:

  • 我所做的所有阅读都表明您无法在 GWT 应用程序中直接访问 POST 参数。
  • 很抱歉,您可以覆盖 ServiceImpl 类中的 service(ServletRequest, ServletResponse) 方法或 processCall(String) 方法。如果你使用service(),你可以使用request.getParameterMap()来获取参数。如果你使用processCall(),你会看到POST请求是一个字符串,包含参数。
  • 好的,我尝试了一些代码,结果如下:如果你覆盖protected void onAfterRequestDeserialized(RPCRequest rpcRequest)RPCRequest 对象会给你一个参数列表。我认为这是最好的方法。在此方法中,您不必调用 super.onAfterRequestDeserialized(),因为超级实现中没有任何内容,因为它打算被覆盖。
  • 你试过了吗?运气好吗?
  • 是的,很抱歉没有回复您。当 servlet 和 GWT 应用程序在我的服务器上是单独的 Web 应用程序时,我无法让它工作。不过,在将 servlet 移动到与 GWT 应用程序相同的 Web 应用程序中后,我从未尝试过,这可能是我的问题。
猜你喜欢
  • 2011-11-04
  • 2014-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-14
  • 1970-01-01
相关资源
最近更新 更多