我有一个工作的spring集成应用程序,我在/requests
下添加了一个HTTP端点,以便从REST客户端(实际是Web浏览器)接收POST数据;我也通过 Spring MVC 添加了一组其他REST端点,其中一个端点处理对/api/requests
的GET请求 - 这些REST端点se旨在提供一个读取只与客户互动。
弹簧集成端点在按预期调用时工作(即直接调用/requests
),但我体验到它是"捕捉"甚至要求它不应该:/api/requests
。
我没有使用Spring Boot。我从Integration home上的示例中对我的配置进行了适配,稍后将其从应用程序移动到Web应用程序。
这是context.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:...>
<ctx:component-scan base-package="services,api" />
<int-http:inbound-channel-adapter id="httpInboundAdapter"
channel="httpRequestsChannel"
path="/requests"
supported-methods="POST">
<int-http:cross-origin allow-credentials="false" allowed-headers="*" origin="*" />
</int-http:inbound-channel-adapter>
<!-- other channels and endpoints -->
<!-- misc beans -->
<!-- other beans: jdbc-datasource, etc -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
</beans>
web.xml
的(相关部分):
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<!-- [a] -->
<servlet>
<servlet-name>httpInboundAdapter</servlet-name>
<servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
</servlet>
<!-- [b] -->
<servlet-mapping>
<servlet-name>httpInboundAdapter</servlet-name>
<url-pattern>/requests</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/META-INF/spring.integration/context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
</web-app>
初步问题:
[a]
中正确配置的servlet吗?这有效,但我不清楚哪个servlet名称应该匹配哪个bean名称(如Http Inbound Components中所述),也许它的 context bean id ↔< em> web.xml servlet名称?[b]
中的映射?如果没有它,我无法使入站适配器工作,但是可能应该以另一种方式配置,因为上面提到的文档没有显示HttpRequestHandlerServlet
servlet的映射主要问题:
为什么该适配器拦截其他休息呼叫?我得到了:
HTTP Status 405 - Request method 'GET' not supported
调用/api/requests
时,清楚地显示适配器插入。
我做了一些调试,行为似乎由UrlPathHelper.alwaysUseFullPath
控制,改变了&#34; / api / requests&#34; to&#34; / requests&#34;。
如果此属性可以设置为true
,那么整个会起作用,我该怎么做?
我在this answer之后更新了我的配置,但我仍然遇到了麻烦。
我从客户端请求获得404,并且此警告显示在应用程序日志中:
WARNING: No mapping found for HTTP request with URI [/api/requests] in DispatcherServlet with name 'app'
这是新的context.xml
新id
s:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:...>
<ctx:component-scan base-package="services,api" />
<ctx:annotation-config />
<mvc:annotation-driven />
<int-http:inbound-channel-adapter id="/api/requests"
channel="httpRequestsChannel"
path="/api/requests"
supported-methods="POST">
<int-http:cross-origin allow-credentials="false" allowed-headers="*" origin="*" />
</int-http:inbound-channel-adapter>
<int-http:inbound-channel-adapter id="/api/requests"
channel="nullChannel"
path="/api/requests"
supported-methods="OPTIONS">
<int-http:cross-origin allow-credentials="false" allowed-headers="*" origin="*" />
</int-http:inbound-channel-adapter>
<!-- other channels and endpoints -->
<!-- misc beans -->
<!-- other beans: jdbc-datasource, etc -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
</beans>
我从web.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
<!-- ... -->
另一篇评论,删除重复的id bean,我仍然得到相同的警告:
WARNING: No mapping found for HTTP request with URI [/api/requests] in DispatcherServlet with name 'app'
这是新的context.xml
新id
s:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:...>
<ctx:component-scan base-package="services,api" />
<ctx:annotation-config />
<mvc:annotation-driven />
<int-http:inbound-channel-adapter id="/api/requests"
channel="httpRequestsChannel"
path="/api/requests"
supported-methods="POST,OPTIONS">
<int-http:cross-origin allow-credentials="false" allowed-headers="*" origin="*" />
</int-http:inbound-channel-adapter>
<int:channel id="httpRequestsChannel" />
<!-- other channels, endpoints and beans -->
</beans>
正如所指出的,我已经编辑了path
属性:POST请求现在可以正常工作,但GET请求现在已经被破坏,产生:
WARNING: Request method 'GET' not supported
虽然上面没有显示,但这个应用程序与this other question中的应用程序相同,此处的控制器应响应GET
上的/api/requests
:
package api;
// imports
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping(path="/api/requests", produces="application/json")
public class RequestController {
// ...
已编辑context.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:...>
<ctx:component-scan base-package="services,api" />
<ctx:annotation-config />
<mvc:annotation-driven />
<int-http:inbound-channel-adapter id="/api/requests"
channel="httpRequestsChannel"
path="/requests"
supported-methods="POST,OPTIONS">
<int-http:cross-origin allow-credentials="false" allowed-headers="*" origin="*" />
</int-http:inbound-channel-adapter>
<int:channel id="httpRequestsChannel" />
<!-- other channels, endpoints and beans -->
</beans>
在此更新中,我修复了从path="/api/requests"
到path="/requests"
的REST控制器主路径映射。
package it.cgt.api;
// imports
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping(path="/requests", produces="application/json")
public class RequestController {
@Autowired
private RequestService requestService;
@Autowired
private ProductService productService;
@GetMapping(path= "")
public ApiResponse<List<Request>> getRequests(RequestFilters filters) {
return new ApiResponse<List<Request>>(requestService.getRequests(filters));
}
// ...
此更改使GET
再次起作用,但POST
不再有效。
这似乎是由DispatcherServlet#getHandler()
中的代码引起的,其中RequestMappingInfoHandlerMapping
成员中的handlerMappings
类型的实例会识别对/api/requests
的请求,但拒绝POST方法抛出使执行落在请求处理程序查找之外的异常。
答案 0 :(得分:1)
在那份文件中我们有这句话:
如果您在Spring MVC应用程序中运行,则不需要前面提到的显式servlet定义。
由于您有DispatcherServlet
,因此HttpRequestHandlerServlet
不需要具体的httpInboundAdapter
。
因此,您还会删除<url-pattern>/requests</url-pattern>
,并且所有REST API都位于/api/*
下,并且不会根据提到的/requests
公开UrlPathHelper.alwaysUseFullPath
。