Glassfish web.xml中的servlet映射到@WebService会得到ClassCastException异常

4

我试图在部署到Glassfish(最好也适用于TomEE)的Web服务中获得对URL端点的控制。

我有一个类:

@Stateless
@WebService(
    targetNamespace = "http://foo.net/doc/2012-08-01",
    name = "FooService",
    portName = "FooPort",
    serviceName = "FooService")
public class FooSoapService extends SoapBase {
...
}

还有一个web.xml文件:

<servlet>
    <description>SOAP Endpoint for Foo operations.</description>
    <servlet-name>Foo</servlet-name>
    <servlet-class>com.foo.FooSoapService</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>FooPack</servlet-name>
    <url-pattern>/soap/FooPack</url-pattern>
</servlet-mapping>

如果我在Glassfish中访问/context-root/soap/FooPack?wsdl,我会得到以下结果:

java.lang.ClassCastException: com.foo.FooSoapService cannot be cast to javax.servlet.Servlet

除了一些jax-rs内容,web.xml中几乎没有其他东西。

有什么想法吗?

2个回答

2

嗯,你所声称的 FooSoapService 类是一个 Web 服务实现类,需要实现服务接口,可能是在你的 @WebService 注解的 serviceName 属性中定义的 FooService 接口。

之所以出现此异常是因为你的 FooSoapService 类不是 javax.servlet.Servlet 的实例,肯定也不需要成为一个。在 web.xml 文件中不能公开你的 Web 服务端点。这需要通过 sun-jaxws.xml 实现。像这样:

<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
     <endpoint name="FooPort" implementation="com.foo.FooSoapService" url-pattern="/services/FooService"/>
</endpoints>

您的web.xml应该类似于以下内容:
<listener>
    <listener-class>
            com.sun.xml.ws.transport.http.servlet.WSServletContextListener
    </listener-class>
</listener>
<servlet>
    <servlet-name>Foo</servlet-name>
    <servlet-class>
        com.sun.xml.ws.transport.http.servlet.WSServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Foo</servlet-name>
    <url-pattern>/services/FooService</url-pattern>
</servlet-mapping>

如果您进行这些更改,那么您将能够从以下位置获取WSDL:
/context-root/services/FooService?wsdl

这在部署到 TomEE 上可能行不通,对吧?我真的很希望能够实现兼容性,特别是在决定在生产中使用哪个时(我们甚至可以同时使用两者)。 - jmkgreen
1
你为什么认为它在TomEE中不起作用?这是创建基于JAX-WS的Web服务的通用方式。这不是某种变通方法,而是应该在支持JAX-WS的所有容器上正常工作的方式。 - Paulius Matulionis
由于TomEE没有com.sun.xml.ws.transport.http.servlet.WSServletContextListener(请参见http://cxf.apache.org/javadoc/latest/)。 - jmkgreen
那么问题出在哪里呢?只需将 jaxws-rt-x.x.x.jar 添加到您的类路径中即可。从您提供的链接中,我假设您正在使用 CXF,那么为什么不直接使用 CXF 方法来公开 Web 服务呢? - Paulius Matulionis
制作一个同时支持两者的构建非常困难。坦白地说,厂商中立的部署描述符需要包含特定于厂商的引用才能正常工作,这令人失望。这也会使其看起来非常复杂,如果再添加另一个应用服务器,您可能还需要为其进行配置。 - jmkgreen
显示剩余2条评论

0

glassfish 4.0也具备这个功能。配置可在不出错的情况下部署。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接