【问题标题】:HTTP Proxy Servlet ErrorHTTP 代理 Servlet 错误
【发布时间】:2015-08-02 06:18:07
【问题描述】:

首先让我说这是昨天的工作,所以我完全不知道为什么它突然停止工作。而且 Java / 插件真的不是我的专长。

我正在开发一个对另一个域上的服务器进行 POST 和 GET 调用的应用程序。这是一个 Maven 项目。为了避免跨域问题,我有一个 httpproxy.ProxyServlet 插件。

我将在这里列出所有工作的部分,但基本上问题和错误总结在这篇文章的底部。

pom.xml

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.mitre.dsmiley.httpproxy</groupId>
        <artifactId>smiley-http-proxy-servlet</artifactId>
        <version>1.6</version>
    </dependency>

</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.0.2</version>
            <configuration>
                <source>1.5</source>
                <target>1.5</target>
            </configuration>
        </plugin>
        <!--        War plugin below is required for above plugin to build project without errors.    http://stackoverflow.com/questions/7539970/cannot-construct-org-apache-maven-plugin-war-util-webappstructure-as-it-does-not-->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.1.1</version>
        </plugin>
    </plugins>

web.xml

第二个 servlet 部分是有问题的。我只发布第一个,因为第一个工作正常。供参考。

<servlet>
    <servlet-name>ad_auth</servlet-name>
    <servlet-class>org.mitre.dsmiley.httpproxy.ProxyServlet</servlet-class>
    <init-param>
        <param-name>targetUri</param-name>
        <param-value>${authserver}/aaenroll/rest/authContext</param-value>
    </init-param>
    <init-param>
        <param-name>log</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>ad_auth</servlet-name>
    <url-pattern>/adauth</url-pattern>
</servlet-mapping>


<servlet>
    <servlet-name>user_profile</servlet-name>
    <servlet-class>org.mitre.dsmiley.httpproxy.ProxyServlet</servlet-class>
    <init-param>
        <param-name>targetUri</param-name>
        <param-value>${authserver}/aaenroll/rest/userProfile/userName/{_username}.json?user={_username}</param-value>
        <!--<param-value>${authserver}/aaenroll/rest/userProfile/userName/segotac.json?user=segotac</param-value>-->
    </init-param>
    <init-param>
        <param-name>log</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>user_profile</servlet-name>
    <url-pattern>/userProfile</url-pattern>
</servlet-mapping>

Javascript Ajax 调用

function checkEnrollment() {
var username = Cookies.get('username');
var authToken = Cookies.get('authToken');
$.ajax({
    type: "GET",
    beforeSend: function(request)
    {
        request.setRequestHeader("Authorization", authToken);
    },
    url: "userProfile?_username=" + username, //**PROBLEM HERE** -> Url intercepted by servlet plugin. Full path mapping is available in web.xml. As per the Plugin syntax, param _username will replace all "{_username}" in web.xml userProfile targetUri param-values.
    success: function(msg, success) {
        window.location.replace("enroll.jsp");
    },
    error: function(xhr, ajaxOptions, thrownError) {
        console.log('false Enrollment');
    }
});

上面传递的截获 URL 的语法位于此链接的底部。哪个是插件。这又是……昨天还在工作……https://github.com/mitre/HTTP-Proxy-Servlet

终于。错误:

<html><head><title>Apache Tomcat/7.0.39 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 500 - Trying to process targetUri init parameter: java.net.URISyntaxException: Illegal character in path at index 71: http://cslxintwebdev3.csmc.edu:8087/aaenroll/rest/userProfile/userName/{_username}.json?user={_username}</h1><HR size="1" noshade="noshade"><p><b>type</b> Exception report</p><p><b>message</b> <u>Trying to process targetUri init parameter: java.net.URISyntaxException: Illegal character in path at index 71: http://cslxintwebdev3.csmc.edu:8087/aaenroll/rest/userProfile/userName/{_username}.json?user={_username}</u></p><p><b>description</b> <u>The server encountered an internal error that prevented it from fulfilling this request.</u></p><p><b>exception</b> <pre>javax.servlet.ServletException: Trying to process targetUri init parameter: java.net.URISyntaxException: Illegal character in path at index 71: http://cslxintwebdev3.csmc.edu:8087/aaenroll/rest/userProfile/userName/{_username}.json?user={_username}
org.mitre.dsmiley.httpproxy.ProxyServlet.initTarget(ProxyServlet.java:156)
org.mitre.dsmiley.httpproxy.ProxyServlet.init(ProxyServlet.java:140)
javax.servlet.GenericServlet.init(GenericServlet.java:160)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:947)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
java.lang.Thread.run(Thread.java:722)

根本原因

java.net.URISyntaxException:索引 71 处路径中的非法字符:http://example.com:8087/aaenroll/rest/userProfile/userName/{_username}.json?user={_username}
    java.net.URI$Parser.fail(URI.java:2829)
    java.net.URI$Parser.checkChars(URI.java:3002)
    java.net.URI$Parser.parseHierarchical(URI.java:3086)
    java.net.URI$Parser.parse(URI.java:3034)
    java.net.URI.(URI.java:595)
    org.mitre.dsmiley.httpproxy.ProxyServlet.initTarget(ProxyServlet.java:154)
    org.mitre.dsmiley.httpproxy.ProxyServlet.init(ProxyServlet.java:140)
    javax.servlet.GenericServlet.init(GenericServlet.java:160)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:947)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    java.lang.Thread.run(Thread.java:722)

注意 Apache Tomcat/7.0.39 日志中提供了根本原因的完整堆栈跟踪。

Apache Tomcat/7.0.39

所以简短的问题是,为什么发送到 HttpProxy 插件的用户名参数没有被正确拦截和替换?

很抱歉,如果这有太多信息要扔在这里。希望熟悉这些技术的人能够快速识别问题或指出正确的调试路径。

非常感谢!

编辑

web.xml

<servlet-class>org.mitre.dsmiley.httpproxy.URITemplateProxyServlet</servlet-class>
<url-pattern>/userProfile/*</url-pattern>

js

url: "userProfile?_username=" + username,

错误:

HTTP Status 500 - Missing HTTP parameter _username to fill the template

我知道用户名在 javascript 调用中有一个值。变量未正确应用于 web.xml 中的模板

再次感谢!

【问题讨论】:

  • 用户名中缺少 $ 符号? (而不是 {_username} 不应该是 web.xml 中的 ${_username} 吗?)
  • 它不是一个 jQuery 变量。这是我知道这种语法的唯一原因。此外,插件页面底部的示例概述了如何编写参数化代理 URL 显示变量上没有 $
  • 在 javascript 中打印 var username - 它的价值是什么?
  • 用户名变量在 javascript 中正确填充。它在插件拦截的某个地方丢失了。

标签: java maven tomcat servlets proxy


【解决方案1】:

主要是你的servlet映射有问题。 根据documentation,我没有看到任何迹象表明ProxyServlet 类允许参数化(尽管可能确实如此)。也许您应该改用URITemplateProxyServlet 类。 您可以这样更改您的 servlet 定义:

<servlet-class>org.mitre.dsmiley.httpproxy.URITemplateProxyServlet</servlet-class>
<init-param>
    <param-name>targetUri</param-name>
    <param-value>{authserver}/aaenroll/rest/userProfile/userName/{_username}.json?user={_username}</param-value>
    ...

以及 servlet 映射,(注意 '*'):

<servlet-mapping>
  <servlet-name>user_profile</servlet-name>
  <url-pattern>/userProfile/*</url-pattern>
</servlet-mapping>

然后在你的 ajax 中:

...
url: "userProfile/?authserver=" + authserver + "&_username=" + username;
...

所以我正在阅读the source 的URITemplateProxyServlet,我认为它可能期待一对一的args 匹配。换句话说,对于 targetUri 中的每个参数,查询字符串中必须有一个匹配的参数(即您的 ajax 生成的 URL)。不幸的是,我无法测试,但您应该能够快速判断这是否是事实。

试试这个:

  • 为避免混淆,请将 url 模式设置为第二个“/”,例如 &lt;url-pattern&gt;/userProfile/*&lt;/url-pattern&gt;,就像他们的 documentation 一样。
  • 更改 ajax 生成的 URL 以匹配此模式 AND 有第二个参数:"userProfile/subpath?_username=" + username + "&amp;_username2=" + username;
  • 根据需要更改目标 uri:&lt;param-value&gt;${authserver}/aaenroll/rest/userProfile/userName/{_username}.json?user={_username2}&lt;/param-value&gt;

【讨论】:

  • 这似乎更接近了。 ${authServer} 实际上是一个服务器属性。最终将成为应用程序属性。所以我只需要传递用户名参数。现在的错误是 HTTP Status 500 - Missing HTTP parameter _username to fill the template,我打印出我的用户名 var 的值。所以我知道它在 javascript 变量中。它在 ajax 调用和插件拾取它并使用它来替换 URL 模板中的参数之间的某个地方丢失了。嗯。
  • 你的javascript生成的url是什么?确保它不是时髦的。还可以考虑在 URL 的最后一个斜杠之后添加其他内容(尽管没有它应该可以工作?),例如 "userProfile/blah?_username=" + username;
  • url 正是“userProfile?_username=segotac”
  • 删除了 userProfile 之后的“/”,因为这似乎使情况变得更糟
  • URL 必须与 servlet 映射中的模式匹配。对于&lt;url-pattern&gt;/userProfile/*&lt;/url-pattern&gt;,URL 必须有一个起始“/”、字符串 userProfile、另一个“/”,然后是其他任何内容。如果您的网址实际上是http://server/userProfile?_username=segotac,那么模式应该是&lt;url-pattern&gt;/userProfile*&lt;/url-pattern&gt; - 但我不知道如果URITemplateProxyServlet 不接近文档链接中的模式(见上文)是否会很好。
【解决方案2】:

好吧,我终于弄清楚了问题所在。由于我试图使用相同的 _username 参数来填充 targetUri 中的两个位置,因此其中一个位置丢失了。基本上你不能使用这个插件两次将相同的参数应用到 targetUri。

解决方案: web.xml

<servlet>
    <servlet-name>user_profile</servlet-name>
    <servlet-class>org.mitre.dsmiley.httpproxy.URITemplateProxyServlet</servlet-class>
    <init-param>
        <param-name>targetUri</param-name>
        <param-value>${authserver}/aaenroll/rest/userProfile/userName/{_username}.json?user={_username2}</param-value>
    </init-param>
    <init-param>
        <param-name>log</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>user_profile</servlet-name>
    <url-pattern>/userProfile/*</url-pattern>
</servlet-mapping>

ajax 调用

$.ajax({
    type: "GET",
    beforeSend: function(request)
    {
        request.setRequestHeader("Authorization", authToken);
    },
    url: "userProfile?_username=" + username + "&_username2=" + username;, //Url intercepted by servlet plugin. Full path mapping is available in web.xml
    success: function(msg, success) {
    },
    error: function(xhr, ajaxOptions, thrownError) {
    }
});

【讨论】:

    猜你喜欢
    • 2011-03-21
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 2017-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-20
    相关资源
    最近更新 更多