jax-ws开发深入

JAX-WS注解

注解说明

WebService的注解都位于javax.jws包下:

@WebService-定义服务,在public class上边

targetNamespace:指定命名空间

name:portType的名称

portName:port的名称

serviceName:服务名称

@WebMethod-定义方法,在公开方法上边

operationName:方法名

exclude:设置为true表示此方法不是webservice方法,反之则表示webservice方法

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

name:返回结果值的名称

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

name:指定参数的名称

作用:

通过注解,可以更加形像的描述Web服务。对自动生成的wsdl文档进行修改,为使用者提供一个更加清晰的wsdl文档。

当修改了WebService注解之后,会影响客户端生成的代码。调用的方法名和参数名也发生了变化

注解示例:

/**
* 天气查询服务接口实现类
* @author SMN
* @version V1.0
*/
@WebService(targetNamespace="http:// webservice.itcast.cn",
serviceName="weatherService",
portName="weatherServicePort",
name="weatherServiceInterface"
)
public class WeatherInterfaceImpl implements WeatherInterface { @WebMethod(operationName="queryWeather")
public @WebResult(name="weatherResult")String queryWeather(
@WebParam(name="cityName")String cityName) {
System.out.println("from client.."+cityName);
String result = "晴朗";
System.out.println("to client..."+result);
return result;
} public static void main(String[] args) {
//发送webservice服务
Endpoint.publish("http://192.168.1.100:1234/weather", new WeatherInterfaceImpl());
} }

使用注解注意

@WebMethod对所有非静态的公共方法对外暴露为服务.

对于静态方法或非public方法是不可以使用@WebMethod注解的.

对public方法可以使用@WebMethod(exclude=true)定义为非对外暴露的服务。

jax-ws发布为web工程

将webservice发布在web工程可以使用webservice接口和web应用的其它链接共存。

Jax-ws开发的webservice 发布至web容器需要使用jax-wsRI(扩展实现), https://jax-ws.java.net/下载jax-wsRI最新版本,本次使用jaxws-ri-2.2.8版本。

第一步:下载jaxws-ri-2.2.8的扩展包

第二步:创建web工程

第三步:将扩展包中的jar拷贝至web工程下

第四步:编写服务端代码,编写方法与之前我们学习的jax-ws方法一致

如果需要生成soap1.2在@WebServer下添加:

@BindingType(value="http://www.w3.org/2003/05/soap/bindings/HTTP/")

package cn.itcast.weather.server;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.jws.WebService;
import javax.xml.ws.BindingType;
import javax.xml.ws.Endpoint;
/**
* 使用jax-ws开发webservice
* 数据类型采用自定义对象类型,list等
*
*/
@WebService(name="WeatherServer",serviceName="WeatherServerService",portName="WeatherServerPort")
public class ServerJws {
/**
* 通过城市查询天气信息,返回未来两天的天气信息
*/
public List<WeatherModule> queryWeatherByCity(String city){
System.out.println("正在查询"+city+"的天气...");
//未来三天的天气信息
List<WeatherModule> weathers = new ArrayList<WeatherModule>();
//今天的天气
WeatherModule weatherModule1 = new WeatherModule();
//城市
weatherModule1.setCityName(city);
//日期
Date date1 = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy年MM月dd日");
String datesString1 = simpleDateFormat.format(date1);
weatherModule1.setDate(datesString1);
//天气
weatherModule1.setWeather("晴");
//温度
weatherModule1.setTemperature("最高温度11度,最低温度1度");
weathers.add(weatherModule1);
//明天的天气
WeatherModule weatherModule2 = new WeatherModule();
//城市
weatherModule2.setCityName(city);
//日期
//创建日历对象
Calendar calendar = Calendar.getInstance();
int day = calendar.get(Calendar.DATE);
//明天的日期
calendar.set(Calendar.DATE, day+1);
Date date2 = calendar.getTime();
String datesString2 = simpleDateFormat.format(date2);
weatherModule2.setDate(datesString2);
//天气
weatherModule2.setWeather("阴");
//温度
weatherModule2.setTemperature("最高温度10度,最低温度-1度");
weathers.add(weatherModule2);
return weathers;
}
public static void main(String[] args) {
}
}

第五步:使用wsgen生成wsdl

在WEB-INF下创建wsdl目录,此目录存放生成的wsdl文件。

1、Cmd进入命令行

2、cd 工程目录

3、执行wsgen

格式为:

wsgn [–wsdl] –cp <服务接口或类> [-r]

-cp classpath(注意都是相对与当前目录)

-r wsdl路径(注意都是相对与当前目录)

注意:如果要发布soap1.2协议,必须这里使用方法-wsdl:Xsoap1.2生成wsdl,

另外,服务类添加

@BindingType(value="http://www.w3.org/2003/05/soap/bindings/HTTP/")

Soap1.1方式

wsgen -wsdl:soap1.1  -cp WebRoot\WEB-INF\classes cn.itcast.weather.server.ServerJws -r WebRoot\WEB-INF\wsdl

soap1.2方式

wsgen -wsdl:Xsoap1.2 -extension -cp WebRoot\WEB-INF\classes cn.itcast.weather.server.ServerJws -r WebRoot\WEB-INF\wsdl

第六步:在web工程的WEB-INF下创建sun-jaxws.xml文件

如果生成soap1.1内容下:

<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime'
version='2.0'>
<endpoint name='ServerJws' implementation='cn.itcast.weather.server.ServerJws'
wsdl='WEB-INF/wsdl/WeatherServerService.wsdl'
url-pattern='/ webservice /weather' />
</endpoints>

url-pattern:为webservice服务地址

如果生成soap1.2的方式:

<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime'
version='2.0'>
<endpoint name='WeatherServer'
implementation='cn.itcast.ws.server.WeatherServer'
wsdl='WEB-INF/wsdl/WeatherServerService.wsdl'
binding="http://www.w3.org/2003/05/soap/bindings/HTTP/"
url-pattern='/ webservice /weather '/>
</endpoints>

url-pattern:为webservice服务地址

第七步:在web工程的web.xml中添加监听及servlet

<listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet>
<servlet-name> webservice </servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name> webservice </servlet-name>
<url-pattern>/webservice/*</url-pattern>
</servlet-mapping>

Web.xml中/ webservice /必须和sun-jaxws.xml中的url-pattern="/ webservice / "相匹配。

通常将<url-pattern>定义为/ws/*,以/ws/匹配url,匹配到了则按webservice解析, sun-jaxws.xml的url-pattern也必须配置成/ws/XXXX

第八步:启动tomcat

访问tomcat下的web工程即可(http://ip:端口/工程目录/webservice/weather)

注意:web.xml中servlet解析的路径要和sun-jaxws.xml中的一致

什么是CXF

Apache CXF = Celtix + Xfire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了,以下简称为 CXF。Apache CXF 是一个开源的 web Services 框架,CXF 帮助您构建和开发 web Services ,它支持多种协议,比如:SOAP1.1,1,2、XML/HTTPRESTful HTTP 或者 CORBA

CORBA(Common Object Request Broker Architecture公共对象请求代理体系结构,早期语言使用的WS。C,c++,C#)

Cxf是基于SOA总线结构,依靠spring完成模块的集成,最终SOA方式。

灵活的部署:可以运行有Tomcat,Jboss,Jetty(内置),weblogic上面。

CXF的安装及配置

从官网下载2.7.11

环境变量配置:

JAVA_HOME,

CXF_HOME=cxf的目录

Path = %JAVA_HOME%\bin;%CXF_HOME%\bin;

CLASSPATH=.;%CXF_HOME%\lib\cxf-manifest.jar

CXF例子

第一步:创建java工程

第二步:将cxf的jar 包加入工程

第三步:创建服务接口和服务实现类

创建服务接口和服务类的方法同上边章节描述,编写SEI及SEI的实现。

注意:与jaxws编程不同的是将@WebService注解加在接口上边。

服务接口:

使用cxf开发webservice这里只需要在接口上加@webservice注解即可,和jaxws开发不同。

@WebService(targetNamespace="http://service.itcast.cn/",
name="WeatherInterface",//porttype的名称
portName="WeatherInterfacePort",
serviceName="WeatherInterfaceService"
)
@BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
public interface WeatherInterface {
//根据城市名称查询未来三天的天气
public List<WeatherModel> queryWeather(String cityName) throws Exception;
}

服务接口实现类:

使用cxf开发不用在接口实现类上加@webservice注解,因为cxf发布服务时可以指定接口。

public class WeatherInterfaceImpl implements WeatherInterface {

    @Override
public List<WeatherModel> queryWeather(String cityName) throws Exception { //构造三天的天气结果
Calendar calendar = Calendar.getInstance();
int day = calendar.get(Calendar.DATE); WeatherModel weatherModel_1 = new WeatherModel();
weatherModel_1.setDate(new Date());
weatherModel_1.setDetail("晴朗");
weatherModel_1.setTemperature_max(30);
weatherModel_1.setTemperature_min(23); WeatherModel weatherModel_2 = new WeatherModel();
calendar.set(Calendar.DATE, day+1);
weatherModel_2.setDate(calendar.getTime());
weatherModel_2.setDetail("晴转多云");
weatherModel_2.setTemperature_max(28);
weatherModel_2.setTemperature_min(21); WeatherModel weatherModel_3 = new WeatherModel();
calendar.set(Calendar.DATE, day+2);
weatherModel_3.setDate(calendar.getTime());
weatherModel_3.setDetail("多云转小雨");
weatherModel_3.setTemperature_max(25);
weatherModel_3.setTemperature_min(18); List<WeatherModel> list = new ArrayList<WeatherModel>();
list.add(weatherModel_1);
list.add(weatherModel_2);
list.add(weatherModel_3); return list;
}
}

发布服务类:

package cn.itcast.ws.jaxws.server;

import org.apache.cxf.jaxws.JaxWsServerFactoryBean;

/**
* CXF发布jaxws服务类
* @author Thinkpad
*
*/
public class Server { /**
* @param args
*/
public static void main(String[] args) {
//创建服务工厂bean
JaxWsServerFactoryBean jaxWsServerFactoryBean = new JaxWsServerFactoryBean();
//指定服务接口
jaxWsServerFactoryBean.setServiceClass(WeatherServerInterface.class);
//指定服务实现对象
jaxWsServerFactoryBean.setServiceBean(new WeatherInterfaceImpl());
     //指定webservice的地址
jaxWsServerFactoryBean.setAddress("http://192.168.1.100:1234/weather");
//创建webservice服务
jaxWsServerFactoryBean.create();
} }

第四步:根据wsdl地址生成客户端代码

我们分别使用wsimport和wsdl2java生成客户端代码,都可以正常使用。

**wsdl2java可以生成soap1.1和soap1.2

wsdl2java生成客户代码

先让我们了解一下cxf的wsdl2java工具,它的功能就如同wsimport一样,可以生成一堆客户端调用的代码。

在命令行执行:

wsdl2java –d . http://192.168.1.100:1234/weather?wsdl

注意:

生成后WeatherService报错:

原因是cxf需要JAX-WS API 2.2而jdk6的jax-ws是2.1 版本,需要

wsdl2java 使用“-frontend jaxws21“

即如下:

wsdl2java –d . –frontend jaxws21 http://localhost:1234/weather?wsdl

第五步:编写客户端:

方式1、使用javax.xml.ws.Service调用客户端

package cn.itcast.ws.jaxws.client;

import java.net.MalformedURLException;
import java.net.URL; import javax.xml.namespace.QName;
import javax.xml.ws.Service; import cn.itcast.ws.jaxws.server.WeatherServerInterface; public class Client3 { public static void main(String[] args) throws MalformedURLException { //创建URL,资源定位
URL url = new URL("http://192.168.1.100:1234/weather?wsdl");
//Qname,确定命名空间地址,和服务视图名称
QName qName = new QName("http://service.itcast.cn/", "WeatherInterfaceService");
//创建service
Service service = Service.create(url, qName);
//创建porttype(服务端点)
WeatherInterface weatherInterface = service.getPort(WeatherInterface.class); //通过服务端点调用服务方法
weatherServerInterface.queryWather("郑州");
} }

方式2、JaxwsProxyFactoryBean调用服务端:

     //创建代码工厂bean
JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
//设置接口类型(portType) jaxWsProxyFactoryBean.setServiceClass(WeatherInterface.class);
//设置webservice地址 jaxWsProxyFactoryBean.setAddress("http://192.168.1.100:1234/weather");
//创建portType调用实例
WeatherInterface weatherInterface =(WeatherInterface) jaxWsProxyFactoryBean.create();
//调用webservice
weatherServerInterface.queryWather("郑州");

SOAP1.2生成

在服务接口和服务类的上面都添加

@BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)

如下:

@WebService

@BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)

public interface WeatherServerInterface

@WebService(endpointInterface = "cn.itcast.ws.jaxws.server.WeatherServerInterface")

@BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)

public class WeatherServer implements WeatherServerInterface

Cxf与spring集成

第一步:建立一个web项目

第二步:填充CXF JAR包。

第三步:创建服务接口及服务类

服务接口:

@WebService(targetNamespace="http://service.itcast.cn/",
name="WeatherInterface",//porttype的名称
portName="WeatherInterfacePort",
serviceName="WeatherInterfaceService"
)
@BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
public interface WeatherInterface {
//根据城市名称查询公网天气服务接口
public List<String> queryWeather(String cityName) throws Exception;
}

服务实现类:

需求:服务类需要调用公网天气查询客户端。

public class WeatherInterfaceImpl implements WeatherInterface {

    //此为公网查询客户端需要通过spring配置并注入
   private WeatherWebServiceSoap weatherWebServiceSoap; @Override
public List<String> queryWeather(String cityName) throws Exception { ArrayOfString arrayOfString = weatherWebServiceSoap.getWeatherbyCityName("郑州");
List<String> results = arrayOfString.getString();
for(String result:results){
System.out.println(result);
} return results;
} public WeatherWebServiceSoap getWeatherWebServiceSoap() {
return weatherWebServiceSoap;
} public void setWeatherWebServiceSoap(WeatherWebServiceSoap weatherWebServiceSoap) {
this.weatherWebServiceSoap = weatherWebServiceSoap;
} }

公网天气查询代码生成

将上边章节生成的公网天气查询客户端调用代码考入本工程。

生成方法在此不再赘述。

第四步:创建applicationContext.xml

将applicationContext.xml放在WEB-INF下

内容如下:

<?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">
<!-- 配置发布webservice服务 -->
<jaxws:server address="/weather" serviceClass="cn.itcast.webservice.jaxws.server.WeatherInterface">
<jaxws:serviceBean>
<ref bean="weatherInterface"/>
</jaxws:serviceBean>
</jaxws:server> <!-- 公网天气查询客户端 -->
<jaxws:client id="weatherClient" serviceClass="cn.com.webxml.WeatherWebServiceSoap" address="http://www.webxml.com.cn/WebServices/WeatherWebService.asmx" /> <!-- 本系统对外服务的天气查询service -->
<bean id="weatherInterface" class="cn.itcast.webservice.jaxws.server.WeatherInterfaceImpl" >
<property name="weatherWebServiceSoap" ref="weatherClient" />
</bean> </beans>

第五步:在web.xml配置Spring环境

    <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class> org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

第六步:在web.xml配置CXFservlet

    <servlet>
<servlet-name>cxf</servlet-name>
     <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>

第七步:启动web容器

访问:http://192.168.1.100:8080/.../ws/weather?wsdl

第八步:编写客户端工程

客户端创建同前边章节,此处不再赘述。

WebService使用介绍(三)的更多相关文章

  1. WebService的介绍概念 收藏

    WebService学习总结(二)——WebService相关概念介绍 一.WebService是什么? 1. 基于Web的服务:服务器端整出一些资源让客户端应用访问(获取数据) 2. 一个跨语言.跨 ...

  2. 浅淡Webservice、WSDL三种服务访问的方式(附案例)

    Webservice Webservice是使应用程序以与平台和编程语言无关的方式进行相互通信技术. eg:站点提供访问的数据接口:新浪微博.淘宝. 官方解释:它是一种构建应用程序的普遍模型,可以在任 ...

  3. Lucene.Net 2.3.1开发介绍 —— 三、索引(七)

    原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(七) 5.IndexWriter 索引这部分最后讲的是IndexWriter.如果说前面提到的都是数据的结构,那么IndexWriter ...

  4. Lucene.Net 2.3.1开发介绍 —— 三、索引(六)

    原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(六) 2.2 Field的Boost 如果说Document的Boost是一条线,那么Field的Boost则是一个点.怎么理解这个点呢 ...

  5. Lucene.Net 2.3.1开发介绍 —— 三、索引(五)

    原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(五) 话接上篇,继续来说权重对排序的影响.从上面的4个测试,只能说是有个直观的理解了.“哦,是!调整权重是能影响排序了,但是好像没办法来 ...

  6. Lucene.Net 2.3.1开发介绍 —— 三、索引(四)

    原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(四) 4.索引对搜索排序的影响 搜索的时候,同一个搜索关键字和同一份索引,决定了一个结果,不但决定了结果的集合,也确定了结果的顺序.那个 ...

  7. Lucene.Net 2.3.1开发介绍 —— 三、索引(三)

    原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(三) 3.Field配置所产生的效果 索引数据,简单的代码,只要两个方法就搞定了,而在索引过程中用到的一些类里最简单,作用也不小的就是F ...

  8. Lucene.Net 2.3.1开发介绍 —— 三、索引(二)

    原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(二) 2.索引中用到的核心类 在Lucene.Net索引开发中,用到的类不多,这些类是索引过程的核心类.其中Analyzer是索引建立的 ...

  9. Lucene.Net 2.3.1开发介绍 —— 三、索引(一)

    原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(一) 在说索引之前,先说说索引是什么?为什么要索引?怎么索引? 先想想看,假如现在有一个文本,我们会怎么去搜索.比如,有一个string ...

随机推荐

  1. 使用SimpleDateFormat解析日期得到年份不正确的结果

    今天写项目的时候发现日期解析结果不对,很纳闷,从控制台中看传过来的数据是对的,但解析得到数据就是错的,如下图 最终查资料发现是格式上的错误,年份的YYYY应该改成yyyy,之后就正常了. 以下是正确格 ...

  2. ubuntu系统下的docker

    官网:https://www.docker.com/ 相关资料:1.Docker入门教程 http://dockone.io/article/1112.Docker_百度百科 http://baike ...

  3. PHP将二位数组按照第二维的某个元素的值进行排序

    例如: //原始数组是这样的,希望能够按照第二维中的run_date升序或者降序进行排序: $arr=array( 0=>array( 'run_date'=>'2017-11-21', ...

  4. java简单web爬虫(网页图片)

    java简单web爬虫(网页图片)效果,执行main()方法后图片就下载道C盘的res文件夹中.没有的话创建一个文件夹代码里的常量根据自己的需求修改,代码附到下面. package com.sinit ...

  5. js 节点

    var chils= s.childNodes; //得到s的全部子节点 var par=s.parentNode;  //得到s的父节点 var ns=s.nextSbiling;  //获得s的下 ...

  6. Overview of the High Efficiency Video Coding (HEVC) Standard阅读笔记

    1.INTRODUCTION High Efficiency Video Coding(HEVC) <-> H.265 MPEG-4 Advanced Video Coding(AVC) ...

  7. xampps 不能配置非安装目录虚拟主机解决方案

    今天将前几天安装好的xampps配置下,准备开始php开发之旅,在我信心满满的将工作目录定在非安装目录上(安装目录在:D:\Program Files\xampps\apache\htdocs  我将 ...

  8. C#基础--之数据类型【转】

    在第一章我们了解了C#的输入.输出语句后,我这一节主要是介绍C#的基础知识,本节的内容也是后续章节的基础,好的开端等于成功的一半.在你阅读完本章后,你就有足够的C#知识编写简单的程序了.但还不能使用继 ...

  9. EF报错“EntityValidationErrors”

          在使用EF更新实体的时候报错,显示界面如下:       点击查看详情:        在查看详细的窗体中,EntityValidationErrors里面的也看不到具体的错误原因.在网上 ...

  10. 关于Vue脚手架写法的问题

    问题描述: main.js import Vue from 'vue' import App from './App' /* eslint-disable no-new */ new Vue({ el ...