WildFly:此 URL 不支持 HTTP 方法 POST

WildFly: HTTP method POST is not supported by this URL

我正在 WildFly 18 上开发 Java EE Web 应用程序 运行,并在前端开发 Angular。从 Angular 到 Wildfly 的所有 HTTP 调用都是 POST。该应用程序运行良好,但每月一次,当我启动它时,我无法使用它,因为 Wildfly 拒绝请求说 HTTP method POST is not supported by this URL(请参阅下面浏览器控制台上的错误)。只是为了确保不是 Angular,我从 Java 程序调用了 POST,但得到了同样的错误。

解决方案是关闭所有内容并重新启动,有时不止一次。为什么会发生这种情况以及如何解决这个问题?最大的问题是这可能会发生在生产中。

visualcode/rest/getbropr:1 Failed to load resource: the server responded with a status of 405 (Method Not Allowed) main.js:1127 HttpErrorResponse error: "Error HTTP method POST is not supported by this URL" headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ} message: "Http failure response for http://localhost:4400/visualcode/rest/getbropr: 405 Method Not Allowed" name: "HttpErrorResponse" ok: false status: 405 statusText: "Method Not Allowed" url: "http://localhost:4400/visualcode/rest/getbropr"

更新

我在两台具有相同 Wildfly 配置的不同机器上发生过这种情况,所以这一定与 JAX-RS 或任何其他相关组件的设置方式有关。

更新 2

我收到错误,这是服务器日志:

11:46:17,306 DEBUG [io.undertow.request] (default I/O-12) Matched prefix path /visualcode for path /visualcode/rest/getbropr
11:46:17,306 DEBUG [io.undertow.request.security] (default task-1) Attempting to authenticate /visualcode/rest/getbropr, authentication required: false
11:46:17,306 DEBUG [io.undertow.request.security] (default task-1) Authentication outcome was NOT_ATTEMPTED with method io.undertow.security.impl.CachedAuthenticatedSessionMechanism@2d8f2c0a for /visualcode/rest/getbropr
11:46:17,306 DEBUG [io.undertow.request.security] (default task-1) Authentication result was ATTEMPTED for /visualcode/rest/getbropr
11:46:17,307 INFO  [io.undertow.request.dump] (default task-1) 
----------------------------REQUEST---------------------------
               URI=/visualcode/rest/getbropr
 characterEncoding=null
     contentLength=2
       contentType=[application/json]
            cookie=_ga=GA1.1.1378850711.1587329434
            header=accept=application/json, text/plain, */*
            header=accept-language=en-US,en;q=0.9,es;q=0.8
            header=accept-encoding=gzip, deflate, br
            header=sec-fetch-mode=cors
            header=origin=http://localhost:4400
            header=user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
            header=sec-fetch-dest=empty
            header=connection=close
            header=sec-fetch-site=same-origin
            header=cookie=_ga=GA1.1.1378850711.1587329434
            header=content-type=application/json
            header=content-length=2
            header=referer=http://localhost:4400/login
            header=host=localhost:8080
            locale=[en_US, en, es]
            method=POST
          protocol=HTTP/1.1
       queryString=
        remoteAddr=/127.0.0.1:51323
        remoteHost=kubernetes.docker.internal
            scheme=http
              host=localhost:8080
        serverPort=8080
          isSecure=false
--------------------------RESPONSE--------------------------
     contentLength=104
       contentType=text/html;charset=UTF-8
            header=Connection=close
            header=Content-Type=text/html;charset=UTF-8
            header=Content-Length=104
            header=Date=Thu, 09 Jul 2020 15:46:17 GMT
            status=405

==============================================================

这是(有时)失败的代码:

@Path("/")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public class LoginService {
    
    @Inject
    private SomeBean bean;
    
    @Context
    private HttpServletRequest httpRequest;

    @POST
    @Path("/getbropr")
    public Response getBrowserProperties() {
          // process response
    }

目前我在他的问题跟踪器中没有发现任何类似的问题。我在 wildfly 17 和 19 上也没有遇到过类似的问题。

所以,我建议您检查解决问题的第一件事是进行以下检查并收集某些信息以提供帮助:

  1. 首先检查wildfly日志并在跟踪或调试模式下更改它们
  2. 其次确认您没有通过平衡器、反向代理、防火墙或任何可能是您在客户端中看到的响应的发布者的中介
  3. 记录调用,包括(url、headers、http方法、参数和body)和接收到的答案的相同数据,或者尝试是否可以使用像邮递员这样的可视化工具或通过命令行使用像 curl.
  4. 这样的命令重现调用

通过这些测试,您可以首先确定服务响应的真实来源。有时平衡器、网络等中的错误配置会导致呼叫未到达目的地,而应答的是另一项服务。

检查包含的 headers 很有用,因为有时会发现痕迹。或者响应的 body 中的格式或消息,这可以是确定来源的另一个指示。

如果我们已经确认源是服务,那么我们可以方便地查看从它开始故障回复的那一刻起的痕迹wards。 当内部发生故障时,可能会有故障或错误处理异常的线索。例如,如果我们将 Resteasy (jax-rs) 与 wildfly(这很常见)一起使用,则在出现内部错误(数据库不可用、内部服务无法访问等)或异常映射器时抛出异常错误是错误...它可能导致打印不正确的消息和错误代码,这会分散解决实际问题的注意力(这不会发生很常见的事情,但要记住这一点并查看日志可以在这里帮忙)。

如果在分析响应、确认其来源、分析痕迹和异常后,您的问题仍然存在...我建议您在此线程中提供应用程序的更多详细信息(例如,java 版本, libs, implement direct with servlet or resteasy?, authentication?, etc) ... 任何你能提供的信息,例如跟踪或具有类似特征的小演示,可以用来重现问题,欢迎帮助你解决问题。

更新:

知道您是 运行 本地服务,我要求您配置 Wildfly 以在您的日志中打印调用及其参数。 Wildfly 使用 undertow 作为引擎,因此请在您的 undertow 配置中添加一个过滤器以记录您的请求。添加到您的 standalone.xml -> 子系统“undertow”以下配置:

<subsystem xmlns = "urn:jboss:domain: undertow: 3.0">
         <server name = "default-server">
             <host name = "default-host" alias = "localhost">
...
                 <filter-ref name = "request-logger" />
             </host>
         </server>
         <filters>
...
             <filter name = "request-logger" module = "io.undertow.core"
               class-name = "io.undertow.server.handlers.RequestDumpingHandler" />
         </filters>
     </subsystem>

或者,您可以使用以下脚本通过 jboss-cli.sh 更改 xml 配置:

$WILDFLY_HOME/bin/jboss-cli.sh --connect --file=script.cli

script.cli 文件:

batch
/subsystem=undertow/configuration=filter/custom-filter=request-logging-filter:add(class-name=io.undertow.server.handlers.RequestDumpingHandler, module=io.undertow.core)
/subsystem=undertow/server=default-server/host=default-host/filter-ref=request-logging-filter:add
run-batch

任何通过开放端口到达 undertow 的调用都应在您的日志中记录收到的数据,这将有助于了解调用是否到达 wildfly 并能够跟踪问题。如果调用实际到达 wildfly,稍后也欢迎调试日志。

另一方面,您是否测试过Wildfly 20是否仍然存在该问题? 18-20之间更新wildfly比较简单

更新 2:

请求看起来不错,所以我建议你检查启动日志。似乎是开始时的竞争条件,Wildfly 同时运行许多任务以尽快开始。

通常,当类路径或启动代码中有重复的配置文件时,可能会导致意外行为,因此比较日志很有帮助。检查您的 .war 文件中是否只有 web.xml 和文件描述符。

希望能帮到你