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实现
- 创建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()); } }
,出现如下结果页:
该 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>
- 在命令行输入: wsimp
ort -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); } } }
- 创建java项目编写实体类
- 添加cxf架包( 因为 cxf 架包中包括了spring相关jar包,可以直接用cxf相应的架包,也可以常试手动挑架包 )
- 编写想要发布成web服务的类上加 注解(同上面用jax-ws相同)
- 配置spring配置文件,(对比上面用 jax-ws时的步骤)
<?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>
- 创建java项目编写实体类,添加cxf的lib下的架包与struts2架包
- 运行命令行,去到 cxf解压目录下的bin目录下,执行 wsdl2java wsdl的url .如下图
- 将执行完上一步生成的文件copy到项目中
- 创建act
ion与页面调用webservice <pre name="code" class="java">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配置文件
<?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>