您的位置:首页 > 其它

【转载】WebService —— JAX-WS 与 CXF

2014-07-23 03:00 453 查看
WebService是SOA的一种较好的实现方式,它将应用程序的不同功能单元通过中立的契约(独立于硬件平台、操作系统和编程语言)联系起来,使得各种形式的功能单元更好的集成。
简单的说,WebService是一种独立于特定语言、特定平台,基于网络的、分布式的模块化组件。是一个能够使用xml消息通过网络来访问的Interface,这个Interface描述了一组可访问的操作。
WebService一般分为两种: REST式 WebService,基于HTTP协议; RPC式 WebService,基于SOAP协议,不过SOAP也是基于HTTP传输的。 狭义上的WebService是指第二种RPC式的WebService,也就是我们常说的那种。WebService是由哪几部分组成的? WebService框架核心是基于简单对象访问协议(Simple Object Access Protocol,SOAP)、Web 服务描述语言(Web Service Description Language,WSDL)以及通用描述、发现和集成(Universal Description Discovery and Integration,UDDI)。                

各部分详细介绍 soap:简单对象访问协议,是一个基于xml访问的协议。它包含有四部分:SOAP封装(envelop),封装定义了一个描述消息中的内容是什么,是谁发送的,谁应当接受并处理它以及如何处理它们的框架;SOAP编码规则(encoding rules),用于表示应用程序需要使用的数据类型的实例; SOAP RPC表示(RPC representation),表示远程过程调用和应答的协定;SOAP绑定(binding),使用底层协议交换信息。SOAP是以HTTP作为底层通信协议,以RPC作为一致性的调用途径,以XML做为数据传输格式。可以简单理解为SOAP=HTTP+RPC+XML wsdl:用来描述WEB服务,他将Web服务描述定义为一组服务访问点,客户端可以通过这些服务访问点对包含面向文档信息或面向过程调用的服务进行访问(类似远程过程调用)。WSDL首先对访问的操作和访问时使用的请求/响应消息进行抽象描述,然后将其绑定到具体的传输协议和消息格式上以最终定义具体部署的服务访问点。 uddi: UDDI是一个分布式的互联网服务注册机制,它集描述(Universal Description)、检索(Discovery)与集成(Integration)为一体,其核心是注册机制。UDDI实现了一组可公开访问的接 口,通过这些接口,网络服务可以向服务信息库注册其服务信息、服务需求者可以找到分散在世界各地的网络服务。
本文总结java中webservice的 jax-ws实现与 cxf实现JAX-WS[/b]实[/b]现webservice步骤:发布服务:[/b]
创建java项目编写实体类
package cn.xm.weather.entity;

import java.util.Date;
// 天气实体类 用于模拟天气预报服务
public class Weather {

//天气
private String weather;
//风力
private String wind;
//温度 max min avg
private Integer max;
private Integer min;
private Integer avg;
//pm2.5
private Integer pm;
//city
private City city;
//date
private Date date;
//des
private String des;
//################################

public Weather(){}

public Weather(String weather, String wind, Integer max, Integer min,
Integer avg, Integer pm, City city, Date date, String des) {
super();
this.weather = weather;
this.wind = wind;
this.max = max;
this.min = min;
this.avg = avg;
this.pm = pm;
this.city = city;
this.date = date;
this.des = des;
}

//################################
public String getWeather() {
return weather;
}
public void setWeather(String weather) {
this.weather = weather;
}
public String getWind() {
return wind;
}
public void setWind(String wind) {
this.wind = wind;
}
public Integer getMax() {
return max;
}
public void setMax(Integer max) {
this.max = max;
}
public Integer getMin() {
return min;
}
public void setMin(Integer min) {
this.min = min;
}
public Integer getAvg() {
return avg;
}
public void setAvg(Integer avg) {
this.avg = avg;
}
public Integer getPm() {
return pm;
}
public void setPm(Integer pm) {
this.pm = pm;
}
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}

}package cn.xm.weather.entity;

public class City {

private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}

编写想要发布成web服务的类上加 注解@webService
package cn.xm.weather.service;

import java.util.Date;
import java.util.List;

import cn.xm.weather.entity.City;
import cn.xm.weather.entity.Weather;

public interface WeatherService {

public List<Weather> getWether(City city, List<Date> dates);

}

package cn.xm.weather.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.jws.WebMethod;
import javax.jws.WebService;

import cn.xm.weather.entity.City;
import cn.xm.weather.entity.Weather;
import cn.xm.weather.service.WeatherService;
/**
* 具体要发布成web服务的业务类
*/
@WebService(name="weather", serviceName="serviceweather" , portName="weatherport" )
public class WeatherServiceImpl implements WeatherService {
/**
* 具体的服务方法
*/
@WebMethod
@Override
public List<Weather> getWether(City city, List<Date> dates) {

List<Weather> weathers=new ArrayList<Weather>();
for (Date date : dates) {
weathers.add(getWether(city, date));
}

return weathers;
}
/**
* 模拟根据成市与日期查寻 天气
* exclude=true 注解:不是web方法
*/
@WebMethod(exclude=true)
public Weather getWether(City city, Date date){

return new Weather("下雨", "7级", 23, 16, 18, 300, city, date, "宜居");
}
}

使用Endpoint的publish方法发布服务
package test;

import javax.xml.ws.Endpoint;

import cn.xm.weather.service.impl.WeatherServiceImpl;

public class T1 {

public static void main(String[] args) {
//发布后的web服务地址
String address="http://localhost:8080/weather";
//发布
Endpoint.publish(address, new WeatherServiceImpl());

}

}

至此,一个web服务就发送成功了,这是就用浏览器访问获取该web服务的wsdl了,在浏览器的地址栏访问
 ,出现如下结果页:
该 XML 文件并未包含任何关联的样式信息。文档树显示如下。
<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is
JAX-WS RI 2.2.4-b01. --><!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is
JAX-WS RI 2.2.4-b01. -->
<definitions targetNamespace="http://impl.service.weather.xm.cn/"
name="serviceweather">
<types>
<xsd:schema>
<xsd:import namespace="http://impl.service.weather.xm.cn/"
schemaLocation="http://localhost:8080/weather?xsd=1" />
</xsd:schema>
</types>
<message name="getWether">
<part name="parameters" element="tns:getWether" />
</message>
<message name="getWetherResponse">
<part name="parameters" element="tns:getWetherResponse" />
</message>
<portType name="weather">
<operation name="getWether">
<input wsam:Action="http://impl.service.weather.xm.cn/weather/getWetherRequest"
message="tns:getWether" />
<output wsam:Action="http://impl.service.weather.xm.cn/weather/getWetherResponse"
message="tns:getWetherResponse" />
</operation>
</portType>
<binding name="weatherportBinding" type="tns:weather">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document" />
<operation name="getWether">
<soap:operation soapAction="" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
</operation>
</binding>
<service name="serviceweather">
<port name="weatherport" binding="tns:weatherportBinding">
<soap:address location="http://localhost:8080/weather" />
</port>
</service>
</definitions>

客户端调用服务 :在命令行输入: wsimport -s . -keep http://localhost:8080/weather?wsdl ,出现如下结果(前提是要配有java环境变量)


执行完上面的步骤这时会在 命令行当前目录下生成与包结构类似的一些文件夹及文件,将在C:\下生成的文件夹复制到客户端src下
创建测试类,调用web服务
package test;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import cn.xm.weather.service.City;
import cn.xm.weather.service.Weather;
import cn.xm.weather.service.Weather_Type;
/**
* 此处是用的比交原始的方式访问(因为它自动生成的文件中已有一定封装)
* @author Administrator
*
*/
public class ClientTest {

public static void main(String[] args) throws MalformedURLException {
//命名空间 url
String tns="http://impl.service.weather.xm.cn/";
// wsdl url
String wsdl="http://localhost:8080/weather?wsdl";
//服务名
QName serviceName= new QName(tns, "serviceweather");
//端口名
QName portName=new QName(tns, "weatherport");
//创建服务对象
Service service=Service.create(new URL(wsdl), serviceName);
//用服务对象创建 服务的代理对象 ( 接口类名 , 服务提代的接口类名 )
Weather weather=service.getPort(portName, Weather.class);
//创建城市 参数
City city=new City();
city.setName("东莞");
//创建 日期集合参数
List<Date> dates=new ArrayList<Date>();
dates.add(new Date(System.currentTimeMillis()-(24*60*60*1000)));
dates.add(new Date());
dates.add(new Date(System.currentTimeMillis()+(24*60*60*1000)));

//调用 webservice 获取天气数据
List<Weather_Type> wethers = weather.getWether(city, dates);
//输出返回数据
for (Weather_Type weather_Type : wethers) {
System.out.println(weather_Type);
}

}

}

package test;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.junit.Test;

import cn.xm.weather.service.impl.City;
import cn.xm.weather.service.impl.Weather;
import cn.xm.weather.service.impl.Weather_Service;
import cn.xm.weather.service.impl.Weather_Type;
/**
* 此处用它自动生成的带有一定封装的类来调用
* @author Administrator
*
*/
public class WeatherTest {

@Test
public void test() {
// 取封装后的服务代理对象
Weather_Service weather = new Weather_Service();
Weather weatherport = weather.getWeatherport();

//创建城市 参数
City city=new City();
city.setName("东莞");
//创建 日期集合参数
List<Date> dates=new ArrayList<Date>();
dates.add(new Date(System.currentTimeMillis()-(24*60*60*1000)));
dates.add(new Date());
dates.add(new Date(System.currentTimeMillis()+(24*60*60*1000)));

// 调 用webservice 获取数据
List<Weather_Type> wethers = weatherport.getWether(city, dates);
//输出返回数据
for (Weather_Type weather_Type : wethers) {
System.out.println(weather_Type);
}

}
}

使用cxf实现的步骤:发布web服务创建java项目编写实体类[/b]
添加cxf架包( 因为 cxf 架包中包括了spring相关jar包,可以直接用cxf相应的架包,也可以常试手动挑架包 )
编写想要发布成web服务的类上加 注解(同上面用jax-ws相同)[/b]
配置spring配置文件,(对比上面用 jax-ws时的步骤)[/b]
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:soap="http://cxf.apache.org/bindings/soap"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd"> <!-- 第一步:引入cxf配置文件 -->
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>

<!-- 第二步: 要发布成webservice的业务对象 -->
<bean id="weatherService" class="cn.xm.weather.service.impl.WeatherServiceImpl" />
<!-- 第三步: 配置endpoint -->
<jaxws:endpoint id="endpoint" implementor="#weatherService" address="/getWeather" publish="true" />

</beans>

用 CXFservlet初始化CXF环境(在 web.xml中)
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- spring 初始参数 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 配置spring 监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- CXFservlet初始化CXF环境 -->

<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>/service/*</url-pattern>
</servlet-mapping>

</web-app>


完成以步骤,布署web应用,启动web容器,就可以访问  http://localhost:8080/cxf/service/getWeather?wsdl 取wsdl文件了调用web服务创建java项目编写实体类,添加cxf的lib下的架包与struts2架包[/b]
运行命令行,去到 cxf解压目录下的bin目录下,执行  wsdl2java wsdl的url .如下图

 
将执行完上一步生成的文件copy到项目中[/b]
创建action与页面调用webservice[/b]
package cn.xm.weather.action;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import cn.xm.weather.service.impl.City;
import cn.xm.weather.service.impl.Weather;
import cn.xm.weather.service.impl.Weather_Type;

public class WetherAction {
/**
* webservice代理对象
*/
private Weather service;
/**
* 天气集合
*/
private List<Weather_Type> wethers;

/**
* 获取天气的Action
* @return
*/
public String getWeather(){

List<Date> dates=new ArrayList<Date>();
dates.add(new Date(System.currentTimeMillis()-24*60*60*100));
dates.add(new Date());
dates.add(new Date(System.currentTimeMillis()+24*60*60*100));

City city=new City();
city.setName("北京");

setWethers(service.getWether(city, dates));
return "success";
}

public List<Weather_Type> getWethers() {
return wethers;
}

public void setWethers(List<Weather_Type> wethers) {
this.wethers = wethers;
}

public void setService(Weather service) {
this.service = service;
}

}

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>

<body>
<table>
<tr>
<td>城市 </td>
<td>日期</td>
<td>天气</td>
<td>风力</td>
<td>最高气温</td>
<td>最低气温</td>
<td>平均气温</td>
<td>pm2.5</td>
</tr>
<s:iterator value="wethers" >
<tr>
<td><s:property value="city.name" /></td>
<td><s:property value="date" /></td>
<td><s:property value="weather" /></td>
<td><s:property value="wind" /></td>
<td><s:property value="max" /></td>
<td><s:property value="min" /></td>
<td><s:property value="avg" /></td>
<td><s:property value="pm2.5" /></td>
</tr>

</s:iterator>
</table>
</body>
</html>

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<package name="de" extends="struts-default" namespace="/" >
<action name="getWeather" class="cn.xm.weather.action.WetherAction" method="getWeather" >
<result>weather.jsp</result>
</action>
</package>
</struts>

配置spring配置文件[/b]
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<!-- web服务代理工厂 -->
<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean" >
<property name="serviceClass" value="cn.xm.weather.service.impl.Weather" />
<property name="address" value="http://localhost:8080/SpringCXF/service/getWeather?wsdl" />
</bean>

<!-- action中使用的业务对象 -->
<bean id="service" class="cn.xm.weather.service.impl.Weather" factory-bean="clientFactory" factory-method="create" />

</beans>

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- spring 初始化参数 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
<!-- spring 监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- struts2 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- CXFservlet -->
<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>/service/*</url-pattern>
</servlet-mapping>
</web-app>


至此,cxf发布与调用 webservice就完成了

ss
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: