当它在反向代理后面时,我遇到了这个问题.后端应用程序部署在上下文中 - 让我们称之为/上下文.
当我直接点击它时,GWT应用程序正常工作:
HTTP://主机:8080 /上下文/
我可以在它前面配置一个反向代理.这是我的nginx示例:
upstream backend { server 127.0.0.1:8080; } ... location / { proxy_pass http://backend/context/; }
但是,当我通过反向代理时,GWT感到困惑,说:
2009-10-04 14:05:41.140:/:WARN: Login: ERROR: The serialization policy file '/C7F5ECA5E3C10B453290DE47D3BE0F0E.gwt.rpc' was not found; did you forget to include it in this deployment? 2009-10-04 14:05:41.140:/:WARN: Login: WARNING: Failed to get the SerializationPolicy 'C7F5ECA5E3C10B453290DE47D3BE0F0E' for module 'https://hostname:444/'; a legacy, 1.3.3 compatible, serialization policy will be used. You may experience SerializationExceptions as a result. 2009-10-04 14:05:41.292:/:WARN: StoryService: ERROR: The serialization policy file '/0445C2D48AEF2FB8CB70C4D4A7849D88.gwt.rpc' was not found; did you forget to include it in this deployment? 2009-10-04 14:05:41.292:/:WARN: StoryService: WARNING: Failed to get the SerializationPolicy '0445C2D48AEF2FB8CB70C4D4A7849D88' for module 'https://hostname:444/'; a legacy, 1.3.3 compatible, serialization policy will be used. You may experience SerializationExceptions as a result.
换句话说,GWT没有得到它需要前置/上下文/ hen寻找C7F5ECA5E3C10B453290DE47D3BE0F0E.gwt.rpc这个词,但只有当请求来自代理时.解决方法是将上下文添加到网站的URL:
location /context/ { proxy_pass http://backend/context/; }
但这意味着上下文现在是用户看到的网址的一部分,而且很难看.
有人知道如何让GWT在这种情况下开心吗?
软件版本:
GWT - 1.7.0(与1.7.1相同的问题)
Jetty - 6.1.21(但tomcat下存在同样的问题)
nginx - 0.7.62(apache 2.x下同样的问题)
我使用DonsProxy查看了代理和后端之间的流量,但没有什么值得注意的.
我有同样的问题,我打开了一个错误报告:
http://code.google.com/p/google-web-toolkit/issues/detail?id=4817
问题是它被标记为"As Design",所以我认为它不会被修复.
我找到了这个解决方案.我扩展了类RemoteServiceServlet,并强制GWT从ContextName而不是URL开始加载序列化策略文件.然后我扩展了我的服务我的类而不是RemoteServiceServlet类.通过这种方式,应用程序将从其将被调用的URL取消链接.
这里有我的自定义类:
import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.text.ParseException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import com.google.gwt.user.server.rpc.RemoteServiceServlet; import com.google.gwt.user.server.rpc.SerializationPolicy; import com.google.gwt.user.server.rpc.SerializationPolicyLoader; public class MyRemoteServiceServlet extends RemoteServiceServlet { @Override protected SerializationPolicy doGetSerializationPolicy(HttpServletRequest request, String moduleBaseURL, String strongName) { return MyRemoteServiceServlet.loadSerializationPolicy(this, request, moduleBaseURL, strongName); } /** * Used by HybridServiceServlet. */ static SerializationPolicy loadSerializationPolicy(HttpServlet servlet, HttpServletRequest request, String moduleBaseURL, String strongName) { // The serialization policy path depends only by contraxt path String contextPath = request.getContextPath(); SerializationPolicy serializationPolicy = null; String contextRelativePath = contextPath + "/"; String serializationPolicyFilePath = SerializationPolicyLoader.getSerializationPolicyFileName(contextRelativePath + strongName); // Open the RPC resource file and read its contents. InputStream is = servlet.getServletContext().getResourceAsStream( serializationPolicyFilePath); try { if (is != null) { try { serializationPolicy = SerializationPolicyLoader.loadFromStream(is, null); } catch (ParseException e) { servlet.log("ERROR: Failed to parse the policy file '" + serializationPolicyFilePath + "'", e); } catch (IOException e) { servlet.log("ERROR: Could not read the policy file '" + serializationPolicyFilePath + "'", e); } } else { String message = "ERROR: The serialization policy file '" + serializationPolicyFilePath + "' was not found; did you forget to include it in this deployment?"; servlet.log(message); } } finally { if (is != null) { try { is.close(); } catch (IOException e) { // Ignore this error } } } return serializationPolicy; } }
米歇尔,
感谢您使用示例servlet来处理此问题.但是,当我尝试使用您的方法时,它在反向代理环境中工作,但不在我的开发模式eclipse环境中.
我采取了一种方法,可以让我在开发和生产环境之间无缝移动.
正如你所做的那样,我覆盖了RemoteServiceServlet,但我只更换了以下内容......
@Override protected SerializationPolicy doGetSerializationPolicy( HttpServletRequest request, String moduleBaseURL, String strongName) { //get the base url from the header instead of the body this way //apache reverse proxy with rewrite on the header can work String moduleBaseURLHdr = request.getHeader("X-GWT-Module-Base"); if(moduleBaseURLHdr != null){ moduleBaseURL = moduleBaseURLHdr; } return super.doGetSerializationPolicy(request, moduleBaseURL, strongName); }
在我的apache配置中,我添加了...
ProxyPass /app/ ajp://localhost:8009/App-0.0.1-SNAPSHOT/
RequestHeader edit X-GWT-Module-Base ^(.*)/app/(.*)$ $1/App-0.0.1-SNAPSHOT/$2
这种方法适用于所有场景,并将url"mucking"委托给apache的代理设置,这是我一直采用的方法.
对此方法的评论表示赞赏