从教科书“RESTful Java with JAX-RS”我们可以阅读:
如果我们的应用服务器支持JAX-RS,或者换句话说,它与JAX-R紧密集成,则将我们的
ShoppingApplication
类声明为servlet:<?xml version="1.0"?> <web-app> <servlet> <servlet-name>Rest</servlet-name> <servlet-class> com.restfully.shop.services.ShoppingApplication </servlet-class> </servlet> <servlet-mapping> <servlet-name>Rest</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
如果我们的应用程序服务器不支持JAX-RS,则必须指定处理JAX-RS调用的JAX-RS提供程序的servlet。应该将Application类指定为servlet的init-param:
现在我的问题是:Tomcat是否是一个支持JAX-RS的Servlet容器?你如何区分一个不知道JAX-RS的servlet容器JAX-RS?为什么在第一种情况下可以使用自定义类,将javax.ws.rs.core.Application
扩展为Servlet?
答案 0 :(得分:8)
&#34; Tomcat是否是一个支持JAX-RS的Servlet容器?&#34;
没有
&#34;你如何区分一个不知道JAX-RS的servlet容器JAX-RS?&#34;
事实上,它只是一个Servlet容器,应该告诉你它是不&#34; JAX-RS意识到&#34;。 JAX-RS是Java EE规范的一部分。 Servlet容器支持其名称所暗示的内容; Servlets的容器。他们可能支持JSP等其他一些小功能,但不支持整个EE规范。这不是他们设计的一部分。如果要在Servlet容器中使用JAX-RS,则需要添加一个实现,如Jersey或Resteasy
当你说Servlet容器时,你会想到Jetty,Tomcat,Undertow,Grizzly等服务器。如果您需要完整的Java EE支持,那么您需要获得支持整个规范的实际Java EE应用服务器,如JBoss / Wildfly,Glassfish,TomEE,WebSphere,WebLogic。
&#34;为什么在第一种情况下可以使用自定义类将javax.ws.rs.core.Application扩展为Servlet?&#34;
如果&#34;与JAX-RS&#34;紧密集成,则作者意味着服务器默认符合JAX-RS规范(几乎是Java EE应用程序服务器),然后是以下语句(沿使用相应的web.xml配置)完全错误:
&#34;如果我们的应用服务器支持JAX-RS,或者换句话说,它与JAX-RS紧密集成,则将我的ShoppingApplication类声明为servlet:&#34;
我无法使用Glassfish 4.0或Wildfly 8.1生成一个工作示例,也未在JAX-RS specification中的任何位置指定。在Glassfish中,我会得到关于ShoppingApplication
不是Servlet的例外情况,而在Wildfly中我只会得到NotFoundException
,这意味着应用程序永远不会被加载。
我能找到的最接近的内容是将该应用程序类的名称指定为<servlet-name>
(是 JAX-RS规范的一部分,但是完全不依赖于部署到Java EE服务器)
<servlet>
<servlet-name>com.restfully.shop.services.ShoppingApplication</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>com.restfully.shop.services.ShoppingApplication</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
这是来自JAX-RS规范
如果存在未由现有servlet处理的
Application
子类,则ContainerInitializer
添加的servlet必须使用Application
子类的完全限定名称命名。