Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
反向代理背后的GWT存在问题-nginx或apache_Gwt_Reverse Proxy - Fatal编程技术网

反向代理背后的GWT存在问题-nginx或apache

反向代理背后的GWT存在问题-nginx或apache,gwt,reverse-proxy,Gwt,Reverse Proxy,当GWT位于反向代理之后时,我遇到了这个问题。后端应用程序部署在上下文中,我们称之为/context 当我直接点击GWT应用程序时,它工作正常: 我可以在它前面配置一个反向代理。以下是我的nginx示例: upstream backend { server 127.0.0.1:8080; } ... location / { proxy_pass http://backend/context/; } 上游后端{ 服务器127.0.0.1:8080; } ...

当GWT位于反向代理之后时,我遇到了这个问题。后端应用程序部署在上下文中,我们称之为/context

当我直接点击GWT应用程序时,它工作正常:

我可以在它前面配置一个反向代理。以下是我的nginx示例:

upstream backend { server 127.0.0.1:8080; } ... location / { proxy_pass http://backend/context/; } 上游后端{ 服务器127.0.0.1:8080; } ... 地点/{ 代理通行证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. 2009-10-04 14:05:41.140:/:警告:登录:错误:找不到序列化策略文件“/C7F5ECA5E3C10B453290DE47D3BE0F0E.gwt.rpc”;您是否忘记将其包含在此部署中? 2009-10-04 14:05:41.140:/:警告:登录:警告:无法获取模块的序列化策略“C7F5ECA5E3C10B453290DE47D3BE0F0E”https://hostname:444/'; 将使用与1.3.3兼容的传统序列化策略。因此,您可能会遇到序列化异常。 2009-10-04 14:05:41.292:/:警告:StoryService:错误:找不到序列化策略文件“/0445C2D48AEF2FB8CB70C4D4A7849D88.gwt.rpc”;您是否忘记将其包含在此部署中? 2009-10-04 14:05:41.292:/:警告:故事服务:警告:无法获取模块的序列化策略“0445C2D48AEF2FB8CB70C4D4A7849D88”https://hostname:444/'; 将使用与1.3.3兼容的传统序列化策略。因此,您可能会遇到序列化异常。 换句话说,GWT没有得到查找C7F5ECA5E3C10B453290DE47D3BE0F0E.GWT.rpc所需的前置词/context/hen,但仅当请求通过代理到达时。解决方法是将上下文添加到网站的url:

location /context/ { proxy_pass http://backend/context/; } 地点/背景/{ 代理通行证http://backend/context/; } 但这意味着上下文现在是用户看到的url的一部分,这很难看

有人知道在这种情况下如何让GWT开心吗

软件版本:
GWT-1.7.0(与1.7.1的问题相同)
Jetty-6.1.21(但tomcat下也存在同样的问题)
nginx-0.7.62(在Apache2.x下存在相同的问题)


我已经使用查看了代理和后端之间的通信量,但是没有什么值得注意的。

我遇到了类似的问题,一个成功的解决方法是让所有序列化对象实现GWT的IsSerializable接口(除了标准的Serializable接口)。如果您阅读该消息,它会声明“将使用与1.3.3兼容的旧版序列化策略”-1.3.3兼容策略要求所有序列化对象实现IsSerializable接口,因此通过添加它,一切都正常


我确实担心遗留策略将在未来版本的GWT中被取消支持,因此我自己也在寻找更好的解决方法。

我确信正确的答案是修补源代码并提交错误报告。另一个选项是在后端运行GWT应用程序


我更喜欢前者,但后者也行。如果您确实需要将内容分为多个上下文,请使用不同的端口号?

我也有同样的问题,我打开了一个错误报告:

问题是它被标记为“设计”,所以我认为它不会被修复

我找到了这个解决方案。我扩展了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/

这种方法适用于所有场景,并将url“mucking”委托给apache的代理设置,这是我一直采用的方法


对这种方法的评论非常感谢

KC的回答很好。对于那些不想使用apache配置的人,或者需要一种快速而肮脏的测试方法的人,这里有一个只使用代码的解决方案

protected SerializationPolicy doGetSerializationPolicy(final HttpServletRequest request, String moduleBaseURL, final String strongName) {
    final String moduleBaseURLHdr = request.getHeader("X-GWT-Module-Base");
    if (moduleBaseURLHdr != null) {
        moduleBaseURL = moduleBaseURLHdr.replace("foo/bar", "bar");
    }
    return super.doGetSerializationPolicy(request, moduleBaseURL, strongName);
}
应用程序已打开
http://server/bar
,代理服务器在
http://proxy/foo/bar
因此moduleBaseURL=moduleBaseURLHdr.replace(“foo/bar”、“bar”);让GWT开心。 同样,如果应用程序位于
http://server/bar
并且代理服务器在
http://proxy/
,您需要向moduleBaseURL添加条(就在包名称之前)。
这可以通过使用getServletContext().getContextPath()等来概括。

对RPC调用使用restful JSON,而不是GWT-RPC。
这解决了反向代理问题,因为不需要序列化文件。

我的目标是避免额外的头,这将使部署和配置更加困难。我通过重写
RemoteServiceServlet.doGetSerializationPolicy()
解决了这个问题:

@凌驾 受保护的序列化策略doGetSerializationPolicy(HttpServletRequest请求,字符串moduleBaseURL,字符串strongName){ 字符串localServerAddress=”http://127.0.0.1:“+getThreadLocalRequest().getLocalPort(); 字符串localContextPath=getServletConfig().getServletContext().getContextPath(); 字符串moduleName=extractGwtModuleName(moduleBaseURL); 字符串localModuleBaseURL=joinPath(localServerAddress、localContextPath、moduleName,“/”; 返回super.doGetSerializationPolicy(请求、localModuleBaseURL、strongName); } 在上述代码中:
extractGwtModuleName()
ext
protected SerializationPolicy doGetSerializationPolicy(final HttpServletRequest request, String moduleBaseURL, final String strongName) {
    final String moduleBaseURLHdr = request.getHeader("X-GWT-Module-Base");
    if (moduleBaseURLHdr != null) {
        moduleBaseURL = moduleBaseURLHdr.replace("foo/bar", "bar");
    }
    return super.doGetSerializationPolicy(request, moduleBaseURL, strongName);
}
@Override protected SerializationPolicy doGetSerializationPolicy(HttpServletRequest request, String moduleBaseURL, String strongName) { String localServerAddress = "http://127.0.0.1:" + getThreadLocalRequest().getLocalPort(); String localContextPath = getServletConfig().getServletContext().getContextPath(); String moduleName = extractGwtModuleName(moduleBaseURL); String localModuleBaseURL = joinPaths(localServerAddress, localContextPath, moduleName, "/"); return super.doGetSerializationPolicy(request, localModuleBaseURL, strongName); }