分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 网页技术

Webservice与CXF框架快速入门

发布时间:2023-09-06 01:54责任编辑:白小东关键词:Web

1. Webservice

Webservice是一套远程调用技术规范

远程调用RPC, 实现了系统与系统进程间的远程通信.
java领域有很多可实现远程通讯的技术,如:RMI(Socket + 序列化)、Binary-RPC(Http+二进制, 代表Hessian)、XML-RPC(Http+XML, 代表Burlap, WebService用的SOAP)、JMS(使用消息机制)、Mina(使用NIO)等, 底层都是基于http/socket和网络IO来实现的.
从效率上来讲, RMI > Hessian >> Burlap >> web service.

构成webservice的几个要素:

1.WSDL:web服务描述语言. 即webservice服务的使用说明书, 自动生成,无需编写

通过访问类似http://127.0.0.1:12345/weather?wsdl的地址可以查看
它长如下这样子, 阅读顺序从下往上


2.SOAP:简单对象访问协议   http post + xml
必有 envelope 标签,将XML文档标识为一条 SOAP 消息
必有 body 标签,传输的信息 
可选 header 标签,包含头部信息
可选 fault 标签,提供有关在处理此消息所发生错误的信息


SOAP常用有1.1, 1.2两个版本. jdk的Jaxws只支持发布SOAP1.1服务.

如要SOAP1.2服务, 需要引入jaxws-ri, 并在实现类上加入注解@BindingType(SOAPBinding.SOAP12HTTP_BINDING)

3.UDDI:提供webservice服务的注册和搜索功能, 不实用

服务端

public interface WeatherInterface { ???public String queryWeather(String cityName);}
// 实现类前加WebService注解
//@BindingType(SOAPBinding.SOAP12HTTP_BINDING)@WebServicepublic class WeatherImpl implements WeatherInterface { ???@Override ???public String queryWeather(String cityName) { ???????String weather = "晴"; ???????return weather; ???}}
public class WeatherServer { ???public static void main(String[] args) { ???????//Endpoint发布服务, 参数1: 服务地址, 参数2: 服务实现类 ???????Endpoint.publish("http://127.0.0.1:12345/weather", new WeatherImpl()); ???}}

对于定义的服务实现类, 可以用注解进行修饰

@WebService 定义服务,在类上边

targetNamespace:指定命名空间

name:portType的名称

portName:port的名称

serviceName:服务名称

endpointInterface:如果一个服务类实现了多个服务接口,但只需要发布一个接口的方法,可通过此注解指定要发布服务的接口

@WebMethod 定义方法,在方法上边

operationName:方法名

exclude:设置为true表示此方法不是webservice方法,不会发布,默认是false

@WebResult 定义返回值,在方法返回值前边

name:返回结果值的名称

@WebParam 定义参数,在方法参数前边

name:指定参数的名称

客户端

首先, 用命令wsimport -s . http://127.0.0.1:12345/weather?wsdl生成支持类, 导入工程中

第一种使用方式 使用相关类

public class Client1 { ???public static void main(String[] args) throws IOException { ???????// WSDL的地址, 非服务地址 ???????URL url = new URL("http://127.0.0.1:12345/weather?wsdl"); ???????//创建服务名称 ???????//参数一: namespaceURI – WSDL文档中 ?types/targetNamespace ???????//参数二: localPart - 服务视图名, WSDL文档中 service-name ???????QName qname = new QName("http://WebXml.com.cn/", "WeatherWS"); ???????//创建服务视图 ???????//参数1: wsdlDocumentLocation ?WSDL地址 ???????//参数2: serviceName ?服务名称 ???????Service service = Service.create(url, qname); ???????//获取服务类 ?getPort(WSDL文档中portType-name) ???????WeatherWSSoap weatherWSSoap = service.getPort(WeatherWSSoap.class); ???????//调用方法 ??WSDL文档中portType-operation-name ???????String result = weatherWSSoap.queryWeather("北京"); ???????System.out.println(result); ???}}

第二种使用方式  http工具访问

public class Client2 { ???public static void main(String[] args) throws IOException { ???????// 服务地址 ???????URL url = new URL("http://127.0.0.1:12345/weather"); ???????// 创建连接对象 ???????HttpURLConnection connection = (HttpURLConnection) url.openConnection(); ???????// 设置参数 ???????// Http发送方式:POST必须大写 ???????connection.setRequestMethod("POST"); ???????// content-type ???????connection.setRequestProperty("content-type", "text/xml;charset=utf-8"); ???????// 设置输入输出,默认connection没有读写权限, ???????connection.setDoInput(true); ???????connection.setDoOutput(true); ???????// 发送请求 ???????String soapXML = getXML("北京"); ???????OutputStream os = connection.getOutputStream(); ???????os.write(soapXML.getBytes()); ???????// 接收响应 ???????int responseCode = connection.getResponseCode(); ???????if(200 == responseCode){ ???????????InputStream is = connection.getInputStream(); ???????????InputStreamReader isr = new InputStreamReader(is); ???????????BufferedReader br = new BufferedReader(isr); ???????????????????????StringBuilder sb = new StringBuilder(); ???????????String temp = null; ???????????while(null != (temp = br.readLine())){ ???????????????sb.append(temp); ???????????} ???????????System.out.println(sb.toString()); ???????????????????????is.close(); ???????????isr.close(); ???????????br.close(); ???????} ???????os.close(); ???} ???????// 组织SOAP数据 ???public static String getXML(String cityName){ ???????String soapXML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" ???????+"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" ???????????+"<soap:Body>" ???????????+"<getWeatherInfo xmlns=\"http://WebXml.com.cn/\">" ???????????????+"<cityName>"+cityName+"</cityName>" ?????????????+"<userID></userID>" ???????????+"</getWeatherInfo>" ?????????+"</soap:Body>" ???????+"</soap:Envelope>"; ???????return soapXML; ???}}

第三种使用方式  浏览器访问

<!doctype html><html lang="en"> <head> ?<meta charset="UTF-8"> ?<title>Document</title> ?<script type="text/javascript"> ???function queryWeather() { ???????var xhr = new XMLHttpRequest(); ???????xhr.open("post", "http://127.0.0.1:12345/weather", true); ???????xhr.setRequestHeader("content-type","text/xml;charset=utf-8"); ???????//设置回调函数 ???????xhr.onreadystatechange=function(){ ???????????if(4 == xhr.readyState && 200 == xhr.status){ ???????????????alert(xhr.responseText); ???????????} ???????} ???????//组织SOAP协议数据 ???????var soapXML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" ???????+"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" ???????????+"<soap:Body>" ???????????+"<getWeatherInfo xmlns=\"http://WebXml.com.cn/\">" ???????????????+"<cityName>"+document.getElementById("cityName").value+"</cityName>" ?????????????+"<userID></userID>" ???????????+"</getWeatherInfo>" ?????????+"</soap:Body>" ???????+"</soap:Envelope>"; ???????//发送数据 ???????xhr.send(soapXML); ???} ?</script> </head> <body> ??????天气查询:<input type="text" id="cityName"/> <input type="button" value="查询" onclick="javascript:queryWeather();"/> </body></html>

2. CXF框架

CXF是一个开源的webservice框架
CXF支持SOAP1.1/1.2,REST 协议
CXF支持XML,JSON(仅REST下) 的数据格式

服务端  JAX-WS方式(SOAP)

//@BindingType(SOAPBinding.SOAP12HTTP_BINDING) ?默认发布SOAP1.1, 该注解发布SOAP1.2@WebServicepublic interface WeatherInterface { ???public String queryWeather(String cityName);}
public class WeatherImpl implements WeatherInterface { ???@Override ???public String queryWeather(String cityName) { ???????String weather = "晴"; ???????return weather; ???}}
//与spring整合后可不要该类public class WeatherServer { ???public static void main(String[] args) { ???????JaxWsServerFactoryBean jaxWsServerFactoryBean = new JaxWsServerFactoryBean(); ???????//设置服务接口 ???????jaxWsServerFactoryBean.setServiceClass(WeatherInterface.class); ???????//设置服务实现类 ???????jaxWsServerFactoryBean.setServiceBean(new WeatherImpl()); ???????//设置服务地址 ???????jaxWsServerFactoryBean.setAddress("http://127.0.0.1:12345/ws/weather"); ???????//发布 ???????jaxWsServerFactoryBean.create(); ???}}

与web整合, spring+CXFservlet替代WeatherServer类

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" ???xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" ???xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core" ???xsi:schemaLocation="http://www.springframework.org/schema/beans ????????????????????????????http://www.springframework.org/schema/beans/spring-beans.xsd ???????????????????????????http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd ???????????????????????????http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd ???????????????????????????http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd"> ???????<!-- 服务实现类 --> ???<bean id ="weatherImpl" class="com.zx.server.WeatherImpl"/> ????????<!-- 拦截器 ?-- ???<bean id ="inIntercepter" class="org.apache.cxf.interceptor.LoggingInInterceptor"/> ???<bean id ="outIntercepter" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/> ???--> ???????<!-- 方式1 用JaxWsServerFactoryBean发布SOAP协议的服务 --> ???<jaxws:server address="/weather" serviceClass="com.zx.server.WeatherInterface"> ???????<jaxws:serviceBean> ???????????<ref bean="weatherImpl"/> ?<!-- 实现类 --> ???????</jaxws:serviceBean> ???????<!-- 配置拦截器 -- ???????<jaxws:inInterceptors> ???????????<ref bean="inIntercepter"/> ???????</jaxws:inInterceptors> ???????<jaxws:outInterceptors> ???????????<ref bean="outIntercepter"/> ???????</jaxws:outInterceptors> ???????--> ???</jaxws:server> ???<!-- 方式2 用Endpoint发布SOAP协议的服务 --> ???????<jaxws:endpoint address="/weather" implementor="com.zx.server.WeatherImpl"/> ???????</beans>

endPoint 只支持发布实现类
JaxWsServerFactoryBean还可以发布接口

web.xml

 ?<!-- 配置CXF的Servlet --> ?<servlet> ?????<servlet-name>CXF</servlet-name> ?????<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> ?</servlet> ?<servlet-mapping> ?????<servlet-name>CXF</servlet-name> ?????<url-pattern>/ws/*</url-pattern> ?</servlet-mapping>

客户端

首先, 类似wsimport, 使用CXF下的Wsdl2java生成支持类, 导入工程中

public class WeatherClient { ???public static void main(String[] args) { ???????JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean(); ???????//设置服务接口 ???????jaxWsProxyFactoryBean.setServiceClass(WeatherInterface.class); ???????//设置服务地址 ???????jaxWsProxyFactoryBean.setAddress("http://127.0.0.1:12345/ws/weather"); ???????//获取服务接口, 可与spring整合替代 ???????WeatherInterface weatherInterface = jaxWsProxyFactoryBean.create(WeatherInterface.class); ???????//调用查询方法 ???????String weather = weatherInterface.queryWeather("保定"); ???????System.out.println(weather); ???}}

与spring整合后由spring生成weatherInterface实例

  <!-- 用JaxWsProxyFactoryBean建立客户端 --> ???????<jaxws:client id="weatherClient" address="http://127.0.0.1:12345/ws/weather" serviceClass="com.zx.WeatherInterface"/>

服务端  JAX-RS方式(REST风格)

基础bean

@XmlRootElement(name="student") ?//能被格式化为XMLpublic class Student { ???private long id; ???private String name; ???private Date birthday; ???public getXXX(), setXXX(); ?// get set方法}

服务接口

@WebService@Path("/student") //将请求路径“/student”映射到接口上public interface StudentInterface { ???@POST // 指定请求方式 GET / POST ???@Produces(MediaType.APPLICATION_XML) //指定服务数据类型 XML / JSON ???@Path("/query/{id}") ?//将请求路径/query映射到方法上, 参数注入配合@PathParam注解 ???public Student query(@PathParam("id")long id); ???????@GET ???@Produces({"application/json;charset=utf-8",MediaType.APPLICATION_XML}) ?//同时指定json和xml, 添加访问参数?_type=json返回json; 添加?_type=xml返回XML ???@Path("/queryList/{name}") ???public List<Student> queryList(@PathParam("name")String name);}

服务实现, 仅举例

public class StudentImpl implements StudentInterface { ???@Override ???public Student query(long id) { ???????Student st = new Student(); ???????st.setId(110); ???????st.setName("张三"); ???????st.setBirthday(new Date()); ???????return st; ???} ???@Override ???public List<Student> queryList(String name) { ???????Student st = new Student(); ???????st.setId(110); ???????st.setName("张三"); ???????st.setBirthday(new Date()); ???????List<Student> list = new ArrayList<Student>(); ???????list.add(st); ???????return list; ???}}

发布

public class StudentServer { ???public static void main(String[] args) { ???????//JAXRSServerFactoryBean 发布REST的服务 ???????JAXRSServerFactoryBean jaxRSServerFactoryBean = new JAXRSServerFactoryBean(); ???????jaxRSServerFactoryBean.setServiceBean(new StudentImpl()); ???????jaxRSServerFactoryBean.setResourceClasses(StudentImpl.class); ???????jaxRSServerFactoryBean.setAddress("http://127.0.0.1:12345/ws/user"); ???????jaxRSServerFactoryBean.create(); ???}}

与web整合, spring+CXFservlet替代StudentServer类

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" ???xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" ???xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core" ???xsi:schemaLocation="http://www.springframework.org/schema/beans ????????????????????????????http://www.springframework.org/schema/beans/spring-beans.xsd ???????????????????????????http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd ???????????????????????????http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd ???????????????????????????http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd"> ???<!-- 配置服务实现类 --> ???<bean id = "studentImpl" class="com.zx.StudentImpl"/> ???????<!-- 使用JAXRSServerFactoryBean发布REST的服务 --> ???????<jaxrs:server address="/user"> ???????<jaxrs:serviceBeans> ???????????<ref bean="studentImpl"/> ???????</jaxrs:serviceBeans> ???</jaxrs:server></beans>

web.xml

 ?<!-- 配置CXF的Servlet --> ?<servlet> ?????<servlet-name>CXF</servlet-name> ?????<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> ?</servlet> ?<servlet-mapping> ?????<servlet-name>CXF</servlet-name> ?????<url-pattern>/ws/*</url-pattern> ?</servlet-mapping>

REST风格下WSDL访问网址为http://127.0.0.1:12345/ws/user?_wadl

Webservice与CXF框架快速入门

原文地址:https://www.cnblogs.com/jswang/p/9054788.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved