Java API for XML Web Services (JAX-WS) 2.0 (JSR 224) Standard Implementation (SI) JAX-WS2.0 是 JAX-RPC 1.1 (JSR 101)的后续版本。
1. JAX-WS 仍然支持 SOAP 1.1 over HTTP 1.1,因此互操作性将不会受到影响,仍然可以在网上传递相同的消息。2. JAX-WS 仍然支持 WSDL 1.1,因此您所学到的有关该规范的知识仍然有用。WSDL 2.0 规范已经接近完成,但在 JAX-WS 2.0 相关工作结束时其工作仍在进行中。3. JAX-RPC 和 JAX-WS 都支持 SOAP 1.1。JAX-WS 还支持 SOAP 1.2。4. WSDL 1.1 规范在 HTTP 绑定中定义,这意味着利用此规范可以在不使用 SOAP 的情况下通过 HTTP 发送 XML 消息。5. JAX-RPC 忽略了 HTTP 绑定。而 JAX-WS 添加了对其的支持。6. JAX-RPC 支持 WS-I Basic Profile (BP) V1.0。JAX-WS 支持 BP 1.1。(WS-I 即 Web 服务互操作性组织。)
在 JAX-WS 时代,wscompile 已经被 wsimport 与 wsgen 代替。wsimport 用于导入 wsdl 并生成可移植性组件(artifact)wsgen 生成编译后的 SEI 并生成可移植性组件(artifact). 当前 wsgen 并不产生 wsdl.WSDL 在部署的时候产生。但通过配置项可让 wsgen 产生 wsdl。wscompile 主于用于早期的 RPC,使用 wscompile 需要编写一个 config.xml 文件,作为 wscompile 的输入。
昨天在 GF3 上部署 webservice,在 webserivce 上添加了 SOAPBinding(style=Style.RPC),[这个 annotation 最好写在类层次上,写在方面层次上容易与出现与类出现冲突],结果部署失败。后来发现写成 SOAPBinding(style=Style.RPC,use=literal)才可以。从 Google 上找到一点证据:
RPC/encoded is not a supported style/use mode with JAX-WS 2.0. JAX-WS2.0 is fully compliant with the WS-I Basic Profile 1.1 which mandates literal mode. The supported style/use modes are: rpc/literal and document/literal.
JAX-WS 中的 SoapBinding 目前支持 3 种方式:
1)Document Wrapped(默认使用方式,由下面的错误可见):
@SOAPBinding(style=SOAPBinding.Style.DOCUMENT,use=SOAPBinding.Use.LITERAL,parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)2)Document Bare:@SOAPBinding(style=SOAPBinding.Style.DOCUMENT,use=SOAPBinding.Use.LITERAL,parameterStyle=SOAPBinding.ParameterStyle.BARE)3)RPC:@SOAPBinding(style=SOAPBinding.Style.RPC,use=SOAPBinding.Use.LITERAL,parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)
复制代码
另外 The java.util.Collection
classes cannot be used with rpc/literal or document/literal BARE style due to a limitation in JAXB. However, they do work in the default document/literal WRAPPED style
为了更形象具体的解释以上三种绑定方式,作者采用示例代码的形式进行演示,并对三种绑定方式进行对比。
1)Document Wrapped:
//它是一个注解,用在类上指定将此类发布成一个ws.//修改目标空间,修改服务名,端口名.在wsdl那里的xml文件显示对应的修改信息@WebService(targetNamespace = "http://ujn.cn/",serviceName = "UserService", portName = "UserPort")public interface UserService {// 添加用户@WebMethod@ResponseWrapper(localName = "add_Status", targetNamespace = "http://ujn.cn/", className = "cn.ujn.edu.dto.User")@RequestWrapper(localName = "userInfo", targetNamespace = "http://ujn.cn/", className = "cn.ujn.edu.dto.User")@WebResult(name="add_Status")public int add(String userStr);// 查找用户@WebMethod@WebResult(name="login_Status")public int login(String userStr);}
复制代码
刚开始写注解的时候,感觉应该会很简单,其实不然。对于这三种绑定方式,我们首先应该考虑应用场景,针对不同的应用场景选择不同的绑定形式。后面会具体分析绑定方式的选择问题。
在 Document wrapped 方式中,我们设置的 @WebResult(name="add_Status")和 @WebParam(name="userInfo")其中的 name 属性值必须进行包装,相关代码
// 添加用户
<span style="font-size:18px;">@WebMethod
@ResponseWrapper(localName = "add_Status", targetNamespace = "http://ujn.cn/", className = "cn.edu.ujn.dto.User")
@RequestWrapper(localName = "userInfo", targetNamespace = "http://ujn.cn/", className = "cn.edu.ujn.dto.User")
@WebResult(name="add_Status")
public int add(@WebParam(name="userInfo")String userStr);</span>
复制代码
<span style="font-size:18px;">其中,相应包装类为className = "cn.edu.ujn.dto.User",其具体内容如下:</span>
复制代码
<span style="font-size:18px;">public class User {
private String userInfo;
private String login_Status;
public String getUserInfo() {
return userInfo;
}
public void setUserInfo(String userInfo) {
this.userInfo = userInfo;
}
public String getLogin_Status() {
return login_Status;
}
public void setLogin_Status(String login_Status) {
this.login_Status = login_Status;
}
}</span>
复制代码
<span style="font-size:18px;">在进行参数名的替换时,会将localName = "userInfo"在className = "cn.edu.ujn.dto.User"中匹配,若匹配成功,则进行替换操作,替换后的效果可以在wsdl文件中查看,如下图1-1所示,否则编译器会报如图1-2所示的错误:</span>
复制代码
图 1-1 wsdl 文档
图 1-2 错误提示
出现此错误的原因正是因为所定义的变量 userInfo1 未存在于包装类 user 中。
此种绑定形式的缺点是在进行参数初始化时需进行两次 new 操作(分别为 in 和 out 阶段),浪费内存,当然可以考虑使用工厂设计模式。
注:在进行重复部署服务的时候,应当将 Tomcat 容器中的 web 项目删除,否则会因为缓存的原因而看不到新部署的服务效果。
2)DocumentBare:
其指定形式如下:
<span style="font-size:18px;">public interface UserService {
// 添加用户
@WebMethod
@WebResult(name="add_Status")
public int add(@WebParam(name="userInfo")String userStr);
// 查找用户
@WebMethod
@WebResult(name="login_Status")
public int login(@WebParam(name="userInfo")String userStr);
}</span>
复制代码
<span style="font-size:18px;">其中,最重要的参数设置是红色部分的内容。此种方式对于数据类型简单如int、String、array类型的数据使用,对于list、map等集合复杂类型的数据不适用。此种形式的优点是节省内存。</span>
复制代码
3)RPC:
其指定形式如下:
public interface UserService {
// 添加用户
@WebMethod
@WebResult(name="add_Status")
public int add(@WebParam(name="userInfo")String userStr);
// 查找用户
@WebMethod
@WebResult(name="login_Status")
public int login(@WebParam(name="userInfo")String userStr);
}
复制代码
至此,示例代码演示到此。希望朋友们可以有所受益!
评论