在基于 SEI 的 JAX-WS Web Service 中公开方法
您可以在服务端点实现上使用 @WebService 和 @WebMethod 注释来指定要公开为 Java API for XML-Based Web Services (JAX-WS) Web Service 的 Java™ 方法。
准备工作
JAX-WS 技术基于标准服务端点接口和 Provider 接口来启用 Web Service 的实现。 从现有 Java 类 (称为自底向上方法) 开始开发 JAX-WS Web Service 时,必须使用 @WebService 或 @WebService提供者注释对类进行注释,以最初将类定义为 Web Service。
使用 Provider 接口是定义 JAX-WS 服务的动态方法。 类必须实现 javax.xml.ws.Provider 接口且包含 @WebServiceProvider 注释,才能使用 Provider 接口。 Provider 接口有一个方法,即 invoke 方法,它使用 Java 编程语言中的泛型来控制处理各种消息或消息有效内容时的输入和输出类型。
相反,您可以使用 Java 注释通过服务端点接口 (SEI) 方法来描述 Web Service。
有关此任务
要初始定义 Web Service ,请使用 @WebService 注释对 Java 类进行注释。 您还可以选择性地使用 @WebMethod 注释来对各种方法进行注释,从而控制公开为 Web Service 操作这一过程。
由于多个 Web Service 规范之间在如何将方法公开为操作方面存在不确定性,因此请使用下列准则来帮助确保不论使用何种 JAX-WS 实现,行为都是一致的。
- 要定义基本的 Web Service,请使用 @WebService 注释来对实现类进行注释。
- 要使用显式 SEI 定义 Web Service ,请使用 @WebService 注释的 endpointInterface 属性显式引用 Java 接口类。
- 在 @WebService 注释的 wsdlLocation 属性中,提供对 WSDL 文件的引用。 通过指定预定义的 WSDL 文件,可以提高性能。 此外,运行时环境会向您报告 WSDL 文件和注释之间的差异。避免麻烦: 根据 JAX-WS 2.2 规范,如果将 SOAP 1.2 声明为绑定类型,并且 wsdlLocation 属性为空字符串 (缺省值) ,那么容器无法自动生成 WSDL。 因此,如果您使用
?wsdl来请求 WSDL 文件,那么将显示以下异常消息:CWWKW0037E: 无法生成符合 JAX-WS 2.2 规范的 WSDL。
如果您要显示 WSDL 文件,那么必须手动生成 WSDL 文件,将其放置在应用程序中并指定具有正确位置的 wsdlLocation 属性。 - 使用显式 SEI 时,总是会公开 SEI 与继承类中的所有公用方法。 仅当您想要进一步定制已公开的方法时,才需要添加 @WebMethod 注释。
- 在 @WebService 注释中提供对显式 SEI 或现有 WSDL 文件的引用,有助于消除公开方法时可能存在的不确定性。
- 如果未使用显式 SEI,请遵循下列规则来确保对方法进行一致公开:
- 将 @WebService 注释添加至实现类及其所有包含您想要公开的方法的超类。 将 @WebService 注释添加至类时,会公开那个类中不是 static 或 final 的所有公用方法。
- 如果您想要更细粒度的控制,以便仅公开某些方法,请在所选方法上使用 @WebMethod 注释。 要确保公开方法,请使用 @WebMethod 注释来对方法进行注释。 如果要确保不公开方法,请使用 @WebMethod(exclude=true) 注释对方法进行注释。
- 用于公开未附注释的方法的行为更改:
有关将方法公开为 Web Service 操作的 JAX-WS 行为已更改。 这符合最近的 JAX-WS 规范说明。
从先前版本迁移且不含显式 SEI 或 WSDL 的应用程序可能会表现如下所示的其他操作。 可以设置属性以便 JAX-WS 运行时环境使用旧行为。 如果迁移不含 WSDL 或 SEI 的应用程序,那么可能需要这样做,以免公开其他方法。
@WebService public class Foo { @WebMethod public void a() {} // exposed now, exposed before public void b() {} // exposed now, not exposed before }使用新解释时,实现类及其超类中的公用方法只有在下列情况下才公开:- 包含类具有 @WebService 注释。
- 方法没有 @WebMethod(exclude=true) 注释。
使用旧解释时,实现类及其超类中的方法只有在下列情况下才公开:- 包含类具有 @WebService 注释。
- 方法没有 @WebMethod 注释,并且任何其他方法都没有 @WebMethod 注释。
- 方法具有 @WebMethod 或 @WebMethod(exclude=false) 注释。
要指定 JAX-WS 运行时环境使用旧 @WebMethod 行为,请配置
jaxws.runtime.legacyWebMethod=true属性。 可以将此属性配置为 Java 虚拟机 (JVM) 系统属性或配置为 Web 应用程序归档 (WAR) 文件的 META-INF/MANIFEST.MF 文件中的属性。 缺省情况下,此属性设置为false,并且应用程序服务器使用新行为。如果下列所有条件都成立,那么您可能会遇到 WSWS7054E 错误消息:- Web Service 应用程序由未附注释的方法组成。
- 这些方法并不会映射到 Web Service 操作。
- 应用程序没有引用 SEI,也没有将 WSDL 文件打包。
javax.xml.ws.WebServiceException: WSWS7054E: The Web Services Description Language (WSDL) file could not be generated for the XXXX Web Service implementation class because of the following error: javax.xml.ws.WebServiceException: Unable to create JAXBContext
JAX-WS 工具在 @WebMethod 映射原理方面符合 JAX-WS 规范。 此更改可能会影响依赖于先前不符合缺省行为的应用程序。 如果应用程序对 WSDL 或 SEI 进行打包和引用,并且在 SEI 实现中使用 @WebMethod exclude 标志来对所有方法进行了正确的注释,那么此更改对您没有影响。 但是,如果您受到影响,请在方法中添加显式注释以确保将方法排除在 WSDL 生成之外。 例如:@WebMethod(exclude=true)。此外,您还可以将 WSDL 与应用程序一起打包,这样就不需要运行时代表您生成 WSDL。
- 用于公开 static 和 final 方法的行为更改:
服务中没有显式 SEI 的 static 或 final 方法不再公开为 Web Service 操作。 要将这些方法公开,请将 WSDL 与应用程序一起打包,并设置
jaxws.runtime.legacyWebMethod=true。
过程
- 确定要公开为 Web Service 操作的方法。
- 查看将方法公开为类(使用 @WebService 注释进行注释)上的操作的规则。
- 使用在没有 SEI 的应用程序中应用 @WebMethod 和 @WebService 注释的最佳实践,将方法相应地公开为 Web Service 中的操作。
结果
已使用 @WebMethod 注释来指定要公开为 Web Service 操作的方法。
如果已升级应用程序服务器环境,但遇到问题,请复审下列故障诊断信息。
- 使用 JAX-WS 工具 V2.1.6 或更高版本环境时客户机错误指示 WSDL 文件和 portType 不匹配
- 可能会收到类似如下消息的客户端错误消息:
javax.xml.ws.WebServiceException: The Endpoint validation failed to validate due to the following errors: :: Invalid Endpoint Interface :: :: The number of operations in the WSDL portType does not match the number of methods in the SEI or web service implementation class. wsdl operations = [...] dispatch operations = [....]
要更正此问题,必须重新生成客户机工件以匹配 WSDL 文件。
最佳实践: 确保在每次收到更新的 WSDL 文件时都重新生成客户机端工件。 - 执行以下操作的客户?Web Service 上的 WSDL 操作具有不可分派的操作
- 表演完?WSDL 操作,您可能会接收到包含比 JAX-WS 运行时环境可分派的操作更多的 WSDL 文件。 如果客户机尝试调用任何不可分派的操作,那么客户机会收到类似如下消息的错误:
找不到操作的端点引用 (EPR) 为 http://localhost:9086/example/BeanImpl2Service 和 WSA Action = <WSA_action_from_server>. If this EPR was previously reachable, contact the server administrator.
客户机只能访问 Web Service 要公开的操作。 可以通过下列其中一种方法来更正此问题:- 修改 Web Service 应用程序中的 @WebMethod 注释,以便产生的 WSDL 文件公开正确的操作集。
- 将
jaxws.runtime.legacyWebMethod属性设置为false以确保会分派 WSDL 中的所有操作。
下一步做什么?
从 JavaBeans为 JAX-WS 应用程序开发 Java 工件。