CXF - JAX-WS入门
相关dependency,我使用的版本是2.7.11:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${cxf.version}</version>
</dependency>
以一个简单的Service为例:
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public interface MyCxfService {
@WebMethod
String saySth(String content);
}
以及其实现:
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
import pac.testcase.ws.MyCxfService;
public class MyCxfServiceImpl implements MyCxfService {
public String saySth(String content) {
return "I say "+content;
}
}
启动服务:
JaxWsServerFactoryBean server = new JaxWsServerFactoryBean();
server.setServiceClass(MyCxfServiceImpl.class);
server.setAddress("http://localhost:8686/ws/service");
server.create();
调用服务:
JaxWsProxyFactoryBean client = new JaxWsProxyFactoryBean();
client.setServiceClass(MyCxfService.class);
client.setAddress("http://localhost:8686/ws/service");
MyCxfService service = (MyCxfService)client.create();
System.out.println(service.saySth("nothing but performance!!"));
CXF是通过Spring为service提供XML配置的。
需要用Servlet Listener装载Spring后加入CXF相关的Servlet。
也就是说:
<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
在spring的配置文件中加入:
xmlns:jaxws="http://cxf.apache.org/jaxws" http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
继续用上一个例子中的Service接口,简单做一下配置:
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> <jaxws:endpoint implementor="pac.king.webservice.impl.MyCxfServiceImpl" address="/MyCxfService" />
访问:http://localhost:8080/runtrain/services/,会出现下面的效果
客户端方面,可以使用jaxws:client配置让他调用本地bean那样简单:
<jaxws:client id="MyCxfClient" address="http://localhost:8080/runtrain/services/MyCxfService" serviceClass="pac.king.webservice.MyCxfService" />
如果不使用则相当于:
<bean id="MyCxfClient" factory-bean="clientFactory" factory-method="create"/>
<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean"
p:serviceClass="pac.king.webservice.MyCxfService"
p:address="http://localhost:8080/runtrain/services/MyCxfService"
/>
远程调用变得透明:
ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:applicationContext*.xml");
MyCxfService client = (MyCxfService)context.getBean("MyCxfClient");
System.out.println(client.saySth("nothing but show!!"));
曾经想过一个问题,为什么我自己定义个User类什么的都可以传输,而Map却不可以?
天天堆砌API导致很多人把这个Map想得太简单了,换个立场想想,XSD如何去表示Map这种东西?
JAXB(Java Architecture for XML Binding)可以解决这个问题!
简单说来就是:
Java Architecture for XML Binding (JAXB) allows Java developers to map Java classes to XML representations. JAXB provides two main features: the ability to marshal Java objects into XML and the inverse, i.e. to unmarshal XML back into Java objects.
这里引用一下wiki中XSD与JAXB对对照:
XML Schema Type | Java Data Type |
---|---|
xsd:string |
java.lang.String |
xsd:integer |
java.math.BigInteger |
xsd:positiveInteger |
java.math.BigInteger |
xsd:int |
int |
xsd:long |
long |
xsd:short |
short |
xsd:decimal |
java.math.BigDecimal |
xsd:float |
float |
xsd:double |
double |
xsd:boolean |
boolean |
xsd:byte |
byte |
xsd:QName |
javax.xml.namespace.QName |
xsd:dateTime |
javax.xml.datatype.XMLGregorianCalendar |
xsd:base64Binary |
byte[] |
xsd:hexBinary |
byte[] |
xsd:unsignedInt |
long |
xsd:unsignedShort |
int |
xsd:unsignedByte |
short |
xsd:unsignedLong |
java.math.BigDecimal |
xsd:time |
javax.xml.datatype.XMLGregorianCalendar |
xsd:date |
javax.xml.datatype.XMLGregorianCalendar |
xsd:g |
javax.xml.datatype.XMLGregorianCalendar |
xsd:anySimpleType |
java.lang.Object |
xsd:anySimpleType |
java.lang.String |
xsd:duration |
javax.xml.datatype.Duration |
xsd:NOTATION |
javax.xml.namespace.QName |
简单记录一下操作步骤。
首先我需要写一个Adapter来进行marsal/unmarshal。
可以使用javax.xml.bind.annotation.adapters.XmlAdapter<ValueType,BoundType>
简单说来就是用前者解释后者,引用一下javaDoc中对ValueType与BoundType的说明:
* @param <BoundType>
* The type that JAXB doesn't know how to handle. An adapter is written
* to allow this type to be used as an in-memory representation through
* the <tt>ValueType</tt>.
* @param <ValueType>
* The type that JAXB knows how to handle out of the box.
我现在试着写一个返回Map的方法,但是我不能用java.util.Map,因为JAXB无法处理interface。
于是我这样定义我的服务:
import java.util.HashMap;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import pac.king.pojo.User;
import pac.king.webservice.utils.MyMapAdapter;
@WebService
public interface MyCxfService {
@WebMethod
@XmlJavaTypeAdapter(MyMapAdapter.class)
public @WebResult HashMap<String,String> convertUserInfoToMap(@WebParam User user);
}
以及实现:
import java.util.HashMap;
import pac.king.pojo.User;
import pac.king.webservice.MyCxfService;
public class MyCxfServiceImpl implements MyCxfService {
public HashMap<String, String> convertUserInfoToMap(User user) {
HashMap<String,String> result = new HashMap<String, String>();
result.put("name", user.getName());
result.put("id", user.getId());
result.put("password", user.getPassword());
return result;
}
}
写User时需要提供一个没有参数的constructor:
package pac.king.pojo;
public class User { private String id;
private String name;
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User() {}
public User(String id, String name, String password) {
super();
this.id = id;
this.name = name;
this.password = password;
}
}
注意服务方法上的注解@XmlJavaTypeAdapter(MyMapAdapter.class)。
这是继承XmlAdapter写的一个Adapter:
import java.util.HashMap;
import java.util.Map.Entry;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class MyMapAdapter extends XmlAdapter<MyGeneralBean[], HashMap<String,String>>{
@Override
public HashMap<String, String> unmarshal(MyGeneralBean[] v)
throws Exception {
HashMap<String,String> resultMap = new HashMap<String, String>();
for (MyGeneralBean e : v) {
resultMap.put(e.getKey(), e.getValue());
}
return resultMap;
}
@Override
public MyGeneralBean[] marshal(HashMap<String, String> v) throws Exception {
MyGeneralBean[] m = new MyGeneralBean[10];
int i=0;
for (Entry<String, String> entry : v.entrySet()) {
m[++i] = new MyGeneralBean(entry.getKey(), entry.getValue());
}
return m;
} }
MyGeneralBean是用来解释Map结构的一个简单类型,这个也需要提供一个无参数的constructor:
public class MyGeneralBean {
private String key;
private String value;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public MyGeneralBean() {}
public MyGeneralBean(String key, String value) {
super();
this.key = key;
this.value = value;
} }
这样就可以调用了,继续使用上一个例子中的jaxws:client配置,直接使用服务。
ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:applicationContext*.xml");
MyCxfService client = (MyCxfService) context.getBean("MyCxfClient");
Map<String,String> map = client.convertUserInfoToMap(new User("100001","King.","t;stmdtkg"));
System.out.println(map.get("id"));
System.out.println(map.get("name"));
System.out.println(map.get("password"));
CXF - JAX-WS入门的更多相关文章
- 转载 WebService 的CXF框架 WS方式Spring开发
WebService 的CXF框架 WS方式Spring开发 1.建项目,导包. 1 <project xmlns="http://maven.apache.org/POM/4.0 ...
- WebService 的CXF框架 WS方式Spring开发
1.建项目,导包. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www ...
- Cxf + Spring3.0 入门开发WebService
转自原文地址:http://sunny.blog.51cto.com/182601/625540/ 由于公司业务需求, 需要使用WebService技术对外提供服务,以前没有做过类似的项目,在网上搜寻 ...
- Apache CXF实现WebService入门教程(附完整源码)
Apache CXF实现WebService非常简单实用,只需要几步就可以实现一个简单的web service. 首先我们需要新建一个maven项目,在pom中添加依赖和jetty作为测试的web s ...
- So easy Webservice 8.spring整合CXF 发布WS
1.添加jar包(cxf的jar包中包含了spring的jar包),添加spring配置文件 2.web.xml中配置CXFServlet,过滤WS服务的地址 <!-- 配置CXFServlet ...
- WebService 的CXF框架 WS独立服务之HelloWorld
WebService:不同系统不同语言的数据交互, CXF主要分为两种服务方式: 1 )JAX-WS:传输数据, xml格式,基于SOAP协议(规范:规定了xml传递数据的编码规范) ; 2 )JAX ...
- Webservice与CXF框架快速入门
1. Webservice Webservice是一套远程调用技术规范 远程调用RPC, 实现了系统与系统进程间的远程通信.java领域有很多可实现远程通讯的技术,如:RMI(Socket + 序列化 ...
- CXF发布webservice入门
1.设置CXF的bin目录进环境变量 2.CXF导入相关的jar包. 3.建立接口 @WebService public interface HelloWorld { public void say( ...
- WebService基础入门 CXF(WS + RS)
一.基本介绍 Web Services是一个软件接口,它描述了一组可以在网络上通过标准化的 XML 消息传递访问的操作.它使用基于 XML 语言的协议来描述要执行的操作或者要与另一个 Web 服务交换 ...
- Apache CXF入门
CXF简介 Apache CXF = Celtix + XFire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了.CXF 继承了 Celtix 和 XFire 两大 ...
随机推荐
- 一键生成ssl自签名证书脚本
#!/bin/bash -e # * 为必改项 # * 更换为你自己的域名 CN='' # 例如: demo.rancher.com # 扩展信任IP或域名 ## 一般ssl证书只信任域名的访问请求, ...
- [Swift]队列Queue的两种版本:(1)用类包装Queue (2)用泛型包装Queue
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表.进行插入操作的端称为队尾,进行删除操作的 ...
- Nodejs连接数据库为何使用连接池
问题一.nodejs既然是单线程运行,在连接数据库时为何要使用连接池呢? 问题二,redis服务端是单线程运行的,使用连接池到redis,服务端还是串行处理,有什么意义么? 这两个问题都涉及到单线程与 ...
- [原创]Heroku简单部署指南
目录 1. 设置 1.1 环境依赖 1.2 Heroku 客户端安装 1.3 登录 2. 应用 2.1 创建 2.2 查看日志 2.3 附加组件 2.4 交互式 Shell 2.5 定义 配置变量 2 ...
- [JSOI2018]机器人
[Luogu4558] [LOJ2550] \(19.3.25\) JSOI2018简要题解 - FallDream 规律就是 对于\(n=m\)我们每一条左下到右上的对角线上的点的走法都是一样的且每 ...
- 【Python】端口扫描脚本
0x00 使用模块简介 1.optparse模块 选项分析器,可用来生成脚本使用说明文档,基本使用如下: import optparse #程序使用说明 usage="%prog -H ...
- 论文阅读 | FoveaBox: Beyond Anchor-based Object Detector
论文阅读——FoveaBox: Beyond Anchor-based Object Detector 概述 这是一篇ArXiv 2019的文章,作者提出了一种新的anchor-free的目标检测框架 ...
- SMB共享
[root@samba1 ~]# yum install samba samba-client samba-common -y 因为只有真实存在的用户才能在samba中建立,所以我们新建两个测试用户 ...
- jsp基础知识总结
1.了解jsp,jsp有什么有利的,有什么弊端. jsp是serlet的扩展,在web应用中,每个jsp页面都会有servlet容器生产对应的servlet. jsp通过在标准的html页面中插入ja ...
- 一分钟看懂Docker的网络模式和跨主机通信
文章转载自:http://www.a-site.cn/article/169899.html Docker的四种网络模式Bridge模式 当Docker进程启动时,会在主机上创建一个名为docke ...