在没有 Dispatcher Servlet 的情况下访问 Spring Rest 服务
Accessing Spring Rest Service without Dispatcher Servlet
这里实际上我正在尝试访问我的基于 spring 的完整服务,我没有在 web.xml 中配置 DispatcherServlet,而是使用 ContxtLoaderListener 加载我的 spring配置文件。
从我的日志中我可以看到我的服务正在初始化,当我访问上面的 url 时,ICallServlet 正在接收请求,因为它具有 url-模式作为'/*' (这个我不能修改)。
我的问题是无法访问我的服务,请求未到达我的服务。不使用 DispatcherServlet 有什么方法可以调用我的休息服务,请有人帮我解决这个问题。
我有一个 Rest 控制器 :
package mypackage;
@RestController
@RequestMapping("/api/casaOnboarding")
public class CasaOnboardingRestService {
@ResponseBody
@RequestMapping(value="/pwebXML", method=RequestMethod.POST, consumes={"application/json", "application/xml"})
public ResponseEntity pwebXML(@RequestBody OnboardingReq onboardingReq,
HttpServletRequest request, HttpServletResponse response){
System.out.println("Request Reached");
----
}
}
Web.xml(无 Dispatcher Servlet)
<?xml version="1.0" encoding="UTF-8"?>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:controllerServiceContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>iCallUI</servlet-name>
<servlet-class>com.ui.ICallServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>iCallUI</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
controllerServiceContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd">
<context:annotation-config />
<context:component-scan base-package="mypackage"/>
<task:annotation-driven />
</beans>
日志文件
10:45:41,643 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] (ServerService Thread Pool -- 62) Creating shared instance of singleton bean 'casaOnboardingRestService'
10:45:41,643 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] (ServerService Thread Pool -- 62) Creating instance of bean 'casaOnboardingRestService'
10:45:41,643 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] (ServerService Thread Pool -- 62) Eagerly caching bean 'casaOnboardingRestService' to allow for resolving potential circular references
10:45:41,643 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] (ServerService Thread Pool -- 62) Finished creating instance of bean 'casaOnboardingRestService'
URL:
http://localhost:8080/icall-ui/api/casaOnboarding/pwebXML
抱歉,如果没有 Dispatcher Servlet,您将无法分派 spring mvc 视图。您的上下文将通过 ContextLoaderListener 加载,但正如您所发现的,您的路由将永远不会被调用。
您可以做一些事情,例如将调度程序 servlet 映射到您的 api 端点,然后映射 iCallUI 以捕获默认路由“/”而不是“/*”:
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>iCallUI</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
ICallServlet 将替换默认的 servlet,这可能会或可能不会产生不良影响,具体取决于您的应用程序的设置方式。例如,静态文件服务可能会中断。
子类化 org.springframework.web.servlet.DispatcherServlet 是一种选择。但是不知道你在com.ui.ICallServlet中做了什么,谁知道扩展DispatcherServlet会有多困难。
另外,好像路途遥远。如果您使用 Spring 来声明您的 api 路由,为什么不使用它来声明它们呢?为什么要有两种调度机制?如果您需要对每个请求进行一些预处理,请使用 Servlet 过滤器。
最后,也许是最简单的解决方案。只需将 iCallUI 指向另一个 url 模式,例如:“/ui/*”。
这几乎用尽了所有可能性 :)。好吧,事实上您的 controllerServiceContext 文件未设置为解析 url 映射。您还需要添加
<mvc:annotation-driven />
不要忘记所有 xml 命名空间信息!
xmlns:mvc="http://www.springframework.org/schema/mvc"
.
.
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
.
最后我了解到,不使用 DispatcherServlet 就无法(据我所知)调用 spring 休息服务。
非常感谢@Robert 提出的宝贵建议。根据@Robert 的评论,我修改了如下代码以使其正常工作。
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:controllerServiceContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>iCallUI</servlet-name>
<servlet-class>com.ui.ICallServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>iCallUI</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
调度员-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<context:component-scan base-package="mypackage"/>
<mvc:annotation-driven />
</beans>
ControllerServiceContext.xml
我删除了以下代码行并保留了旧代码(此文件包含一些与项目相关的其他内容)。
<context:component-scan base-package="mypackage"/>
<task:annotation-driven />
- 日志文件
在日志中看到以下语句后,我可以说我的服务已准备好处理请求。
15:12:01,782 INFO [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping] (ServerService Thread Pool -- 58) Mapped "{[/api/casaOnboarding/pwebXML],methods=[POST],params=[],headers=[],consumes=[application/json || application/xml],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity mypackage.CasaOnboardingRestService.pwebXML(mypackage.OnboardingReq,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
URL -
我在下面使用 url 访问服务
http://localhost:8080/icall-ui/api/api/casaOnboarding/pwebXML
通过在 web.xml
中使用过滤器
<!-- Spring security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这里实际上我正在尝试访问我的基于 spring 的完整服务,我没有在 web.xml 中配置 DispatcherServlet,而是使用 ContxtLoaderListener 加载我的 spring配置文件。
从我的日志中我可以看到我的服务正在初始化,当我访问上面的 url 时,ICallServlet 正在接收请求,因为它具有 url-模式作为'/*' (这个我不能修改)。
我的问题是无法访问我的服务,请求未到达我的服务。不使用 DispatcherServlet 有什么方法可以调用我的休息服务,请有人帮我解决这个问题。
我有一个 Rest 控制器 :
package mypackage; @RestController @RequestMapping("/api/casaOnboarding") public class CasaOnboardingRestService { @ResponseBody @RequestMapping(value="/pwebXML", method=RequestMethod.POST, consumes={"application/json", "application/xml"}) public ResponseEntity pwebXML(@RequestBody OnboardingReq onboardingReq, HttpServletRequest request, HttpServletResponse response){ System.out.println("Request Reached"); ---- } }
Web.xml(无 Dispatcher Servlet)
<?xml version="1.0" encoding="UTF-8"?> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:controllerServiceContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>iCallUI</servlet-name> <servlet-class>com.ui.ICallServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>iCallUI</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
controllerServiceContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd"> <context:annotation-config /> <context:component-scan base-package="mypackage"/> <task:annotation-driven /> </beans>
日志文件
10:45:41,643 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] (ServerService Thread Pool -- 62) Creating shared instance of singleton bean 'casaOnboardingRestService' 10:45:41,643 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] (ServerService Thread Pool -- 62) Creating instance of bean 'casaOnboardingRestService' 10:45:41,643 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] (ServerService Thread Pool -- 62) Eagerly caching bean 'casaOnboardingRestService' to allow for resolving potential circular references 10:45:41,643 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] (ServerService Thread Pool -- 62) Finished creating instance of bean 'casaOnboardingRestService'
URL: http://localhost:8080/icall-ui/api/casaOnboarding/pwebXML
抱歉,如果没有 Dispatcher Servlet,您将无法分派 spring mvc 视图。您的上下文将通过 ContextLoaderListener 加载,但正如您所发现的,您的路由将永远不会被调用。
您可以做一些事情,例如将调度程序 servlet 映射到您的 api 端点,然后映射 iCallUI 以捕获默认路由“/”而不是“/*”:
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>iCallUI</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
ICallServlet 将替换默认的 servlet,这可能会或可能不会产生不良影响,具体取决于您的应用程序的设置方式。例如,静态文件服务可能会中断。
子类化 org.springframework.web.servlet.DispatcherServlet 是一种选择。但是不知道你在com.ui.ICallServlet中做了什么,谁知道扩展DispatcherServlet会有多困难。
另外,好像路途遥远。如果您使用 Spring 来声明您的 api 路由,为什么不使用它来声明它们呢?为什么要有两种调度机制?如果您需要对每个请求进行一些预处理,请使用 Servlet 过滤器。
最后,也许是最简单的解决方案。只需将 iCallUI 指向另一个 url 模式,例如:“/ui/*”。
这几乎用尽了所有可能性 :)。好吧,事实上您的 controllerServiceContext 文件未设置为解析 url 映射。您还需要添加
<mvc:annotation-driven />
不要忘记所有 xml 命名空间信息!
xmlns:mvc="http://www.springframework.org/schema/mvc"
.
.
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
.
最后我了解到,不使用 DispatcherServlet 就无法(据我所知)调用 spring 休息服务。
非常感谢@Robert 提出的宝贵建议。根据@Robert 的评论,我修改了如下代码以使其正常工作。
web.xml
<?xml version="1.0" encoding="UTF-8"?> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:controllerServiceContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>iCallUI</servlet-name> <servlet-class>com.ui.ICallServlet</servlet-class> </servlet> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/api/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>iCallUI</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
调度员-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd"> <context:component-scan base-package="mypackage"/> <mvc:annotation-driven /> </beans>
ControllerServiceContext.xml
我删除了以下代码行并保留了旧代码(此文件包含一些与项目相关的其他内容)。
<context:component-scan base-package="mypackage"/>
<task:annotation-driven />
- 日志文件
在日志中看到以下语句后,我可以说我的服务已准备好处理请求。
15:12:01,782 INFO [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping] (ServerService Thread Pool -- 58) Mapped "{[/api/casaOnboarding/pwebXML],methods=[POST],params=[],headers=[],consumes=[application/json || application/xml],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity mypackage.CasaOnboardingRestService.pwebXML(mypackage.OnboardingReq,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
URL - 我在下面使用 url 访问服务
http://localhost:8080/icall-ui/api/api/casaOnboarding/pwebXML
通过在 web.xml
中使用过滤器 <!-- Spring security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>