WebService学习笔记

AVA 中共有三种WebService 规范,分别是
JAX-WS(JAX-RPC)、
JAXM&SAAJ、
JAX-RS。
 
1       Webservice客户端开发方法总结
 
1.1      使用客户端生成代码方法
 
第一步:使用wsimport或其它工具(比如cxfwsdl2java)生成客户端的调用
第二步:使用生成代码调用webservice服务端
         使用生成的service服务视图类创建服务视图对象
         调用service服务对象的getPortXXX方法得到portType
//创建服务视图对象
      WeatherInterfaceImplService weatherInterfaceImplService =new WeatherInterfaceImplService();
      //通过服务视图得到portType(接口类型)
      WeatherInterfaceImpl weatherInterfaceImpl = weatherInterfaceImplService.getWeatherInterfaceImplPort();
      //调用webservice方法
      String result = weatherInterfaceImpl.queryWeather("郑州");
 
1.2      使用jaxws标准方法(Service)(推荐使用)
第一步:使用wsimport或其它工具(比如cxfwsdl2java)生成客户端的调用
 
第二步:使用urlqnameservice调用服务端
//wsdl的路径
      URL wsdlDocumentLocation = new URL("http://127.0.0.1:54321/weather?wsdl");
      //wsdl中找到服务视图
      //第一个参数:wsdl的命名空间
      //第二个参数:服务视图名称
      QName serviceName = new QName("http://server.weather.jaxws.ws.itcast.cn/", "WeatherInterfaceImplService");
     
      //第一步使用Service创建服务视图
      Service service =Service.create(wsdlDocumentLocation, serviceName);
     
      //从服务视图得到portType对象
      //参数:portType
      WeatherInterfaceImpl weatherInterfaceImpl = service.getPort(WeatherInterfaceImpl.class);
 
1.3      模拟http客户端调用webservice服务(掌握)
 
使用HttpURLConnectionapacheHttpclient模拟http请求,调用webservice
 
注意:使用此方法不需要生成客户端调用代码。。
 
 
 
JAX-WS的服务端:
第一步:服务端开发
 
  1. 编写SEI(Service Endpoint Interface)SEIwebservice中称为portType,在java中称为接口。
 
代码如下:
/**
 * 天气查询服务接口
 * @author 传智播客 Java学院 苗润土
 * @version V1.0
 */
public interface WeatherInterface {
    //天气查询
    public String queryWeather(String cityName);
   
}
 
  1. 编写SEI实现类,此类作为webservice提供服务类
 
代码如下:
 
/**
 * 天气查询服务接口实现类
 * @author 传智播客 Java学院 苗润土
 * @version V1.0
 */
@WebService
public class WeatherInterfaceImpl implements WeatherInterface {
 
    @Override
    public String queryWeather(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());
    }
   
}
注意:
SEI实现类中至少要有一个非静态的公开方法需要作为webservice服务方法。
public class 上边要加上@WebService
 
  1. endpoint发布服务
 
//发送webservice服务
       Endpoint.publish("http://192.168.1.100:1234/weather", new WeatherInterfaceImpl());
 
 
第二步:查看wsdl
Webservice发布成功,通过wsdl查看webservice发布的正确性
 
  1. 在地址栏输入(注意后面的参数?wsdl)
  1. Wsdl不是webService,只是获取一个用于描述WebService的说明文件
  2. wsdl- WebServiceDescriptionLanguage,是以XML文件形式来描述WebService说明书”,有了说明书,我们才可以知道如何使用或是调用这个服务.
 
 
第三步:Wsimport生成客户端调用类
Wsimport介绍
wsimportjdk自带的webservice客户端工具,可以根据wsdl文档生成客户端调用代码(java代码).当然,无论服务器端的WebService是用什么语言写的,都可以生成调用webservice的客户端代码,服务端通过客户端代码调用webservice
wsimport.exe位于JAVA_HOMEin目录下.
常用参数为:
-d<目录>  - 将生成.class文件。默认参数。
-s<目录> - 将生成.java文件。
-p<生成的新包名> -将生成的类,放于指定的包下。
(wsdlurl) - http://server:port/service?wsdl,必须的参数。
示例:
C:/> wsimport -s . http://127.0.0.1:1234/weather?wsdl
注意:-s不能分开,-s后面有个小点
 
 
客户端生成注意事项:
 
  1. 可以通过java version检查你当前的版本号保存是jdk1.6以上。Jdk1.6.0_13以后的版本支持jaxws2.1
 
  1. Eclipse中创建一个空的java工程为wsimport,此工程作为存放客户端代码。
  2. cmd命令行进入此wsimport 工程的src目录,
输入以下命令:
参数说明:-s是指编译出源代码文件,后面的.()指將代码放到当前目录下.
   最后面的http.是指获取wsdl说明书的地址.
 
  1. 生成完成,刷新Eclipsewsimport工程,将src下生成.java文件代码Copywebservice客户端工程(见下)中。
 
 
第四步:客户端编写
 
代码如下:
/**
 * 天气查询客户端
 * @author 传智播客 Java学院 苗润土
 * @version V1.0
 */
public class WeatherClient {
    public static void main(String[] args) {
       //创建服务视图
       WeatherInterfaceImplService weatherInterfaceImplService =new WeatherInterfaceImplService();
       //通过服务视图得到服务端点
       WeatherInterfaceImpl weatherInterfaceImpl= weatherInterfaceImplService.getPort(WeatherInterfaceImpl.class);
       //调用webservice服务方法
       String result = weatherInterfaceImpl.queryWeather("郑州");
       System.out.println(result);
    }
}
 
公网天气查询:
操作步骤
第一步:找到天气查询的webservice WSDL文件拷贝到D盘根目录
第二步:根据WSDL生成客户端调用类,使用wsimport生成
第三步:将生成的代码拷贝至工程中
第四步:编写客户端调用代码
 
客户端代码如下:
 
/**
 * 互联网天气查询客户端
 * @author 传智播客 Java学院 苗润土
 * @version V1.0
 */
public class WebWeatherClient {
    public static void main(String[] args) {
       //创建服务视图
       WeatherWebService weatherWebService  = new WeatherWebService();
       //通过服务视图得到服务端点
       WeatherWebServiceSoap weatherWebServiceSoap =weatherWebService.getWeatherWebServiceSoap();
       //调用webservice服务方法
       ArrayOfString arrayOfString = weatherWebServiceSoap.getWeatherbyCityName("郑州");
       List<String> resultlist = arrayOfString.getString();
       //查询天气查询结果
       for(String result:resultlist){
           System.out.println(result);
       }
    }
}
 
使用javax.xml.ws.Service进行客户端编程
 
步骤
第一步:创建URL,指定资源地址即wsdl地址
第二步:创建Qname,指定命名空间和视图名称
第三步:创建服务视图对象service
第四步:从服务视图中得到服务端点即服务接口(这里需要服务接口类型,可使用wsimport生成后只留下porttype
第五步:通过服务端点调用服务方法
 
天气查询客户端代码
 
/**
 * 使用javax.xml.ws.Service调用webservice服务
 * @author 传智播客 Java学院 苗润土
 * @version V1.0
 */
public class WeatherClient2 {
    public static void main(String[] args) throws MalformedURLException {
       //定义url,参数为wsdl地址
       URL url = new URL("http://192.168.1.100:1234/weather?wsdl");
       //定义qname,第一个参数是命名空间,第二个参数名称是wsdl里边的服务名
       QName qName = new QName("http://impl.sei.jaxws.ws.itcast.cn/", "WeatherInterfaceImplService");
       //创建服务视图
       Service service = Service.create(url, qName);
       //通过服务视图得到服务端点
       WeatherInterfaceImpl weatherInterfaceImpl =service.getPort(WeatherInterfaceImpl.class);
       //调用webservice
       System.out.println(weatherInterfaceImpl.queryWeather("郑州"));
    }
}
 
 
公网天气查询客户端代码:
 
/**
 * 使用javax.xml.ws.Service调用公网webservice服务
 * @author 传智播客 Java学院 苗润土
 * @version V1.0
 */
public class WebWeatherClient2 {
    public static void main(String[] args) throws MalformedURLException {
       //定义url,参数为wsdl地址
       URL url = new URL("file:/D:/WeatherWebService.wsdl");
       //定义qname,第一个参数是命名空间,第二个参数名称是wsdl里边的服务名
       QName qName = new QName("http://WebXml.com.cn/", "WeatherWebService");
       //创建服务视图
       Service service = Service.create(url, qName);
       //通过服务视图得到服务端点
       WeatherWebServiceSoap weatherWebServiceSoap =service.getPort(WeatherWebServiceSoap.class);
       //调用webservice
       ArrayOfString arrayOfString = weatherWebServiceSoap.getWeatherbyCityName("郑州");
       List<String> resultlist = arrayOfString.getString();
       //查询天气查询结果
       for(String result:resultlist){
           System.out.println(result);
       }
    }
}
 
公网手机号归属地查询客户端代码:
/**
 * 使用service类调用公网手机号归属地查询服务
 */
public class MobileClient_Service {
   public static void main(String[] args) throws MalformedURLException {
      //wsdlurl
      URL url = new URL("http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx");
      //定义servicename
      QName serviceName = new QName("http://WebXml.com.cn/", "MobileCodeWS");
 
      //得到 服务视图
      Service service = Service.create(url, serviceName);
     
      //得到portType
      MobileCodeWSSoap mobileCodeWSSoap = service.getPort(MobileCodeWSSoap.class);
      //设备portType的方法
      String resultString = mobileCodeWSSoap.getMobileCodeInfo("1863819", "");
     
      //查询数据
      System.out.println(resultString);
     
   }
}
 
 
使用Service调用和Wsimport代码调用方式区别:
Wsimport生成代码调用webservice无法指定webservice的地址,使用生成的服务视图类获取服务端点(postType)实例。
Service调用Webservice可以指定webservice的地址,只需要服务端点的接口即可获取服务端点实例。
总结:
第一步:阅读wsdl,搞清楚服务视图 service 协议格式binding   服务端点porttype
第二步:创建服务视图
第三步:创建服务端点
第四步:通过服务端点调用服务方法
 
 
      @WebService注解
@WebService-定义服务,在public class上边
targetNamespace:指定命名空间
nameportType的名称
portNameport的名称
serviceName:服务名称
endpointInterfaceSEI接口地址,如果一个服务类实现了多个接口,只需要发布一个接口的方法,可通过此注解指定要发布服务的接口。
 
1.2      @WebMethod-定义方法,在公开方法上边
       operationName:方法名
       exclude:设置为true表示此方法不是webservice方法,反之则表示webservice方法
1.3      @WebResult-定义返回值,在方法返回值前边
       name:返回结果值的名称
1.4      @WebParam-定义参数,在方法参数前边
       name:指定参数的名称
 
注意
如果修改webservice的接口内容,比如namespace、portType,必须要重新生成客户端调用代码。
 
 
1       Cxf入门
 
1.1      什么是cxf
 
Cxf,apache下的webservice的开源框架。
Apache CXF = Celtix + Xfire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了,以下简称为 CXFApache CXF 是一个开源的 web Services 框架,CXF 帮助您构建和开发 web Services ,它支持多种协议,比如:SOAP1.1,1,2XML/HTTPRESTful HTTP 或者 CORBA
CORBACommon Object Request Broker Architecture公共对象请求代理体系结构,早期语言使用的WSC,c++,C#
Cxf是基于SOA总线结构,依靠spring完成模块的集成,实现SOA方式。
灵活的部署:可以运行有Tomcat,Jboss,Jetty(内置),weblogic上面。
 
 
 
1.2      环境配置
 
下载cxf2.7.11版本。
 
从官网下载2.7.11
 
 
环境变量配置:
JAVA_HOME,
新建 CXF_HOME=cxf的目录
Path = %JAVA_HOME%in;%CXF_HOME%in;
CLASSPATH=.;%CXF_HOME%libcxf-manifest.jar
 
 
1.3      Cxf第一个程序
 
1.3.1      服务端
1.3.1.1              开发SEI及SEI实现类
Cxf开发SEI需要将@webservice注解加在接口中.
 
SEI接口:
 
SEI实现类:
1.3.1.2              发布服务代码:
 
 
 
1.3.2      客户端
客户端开发技术不受webservice服务端限制,服务端使用cxf,客户端采用多种方法,比如Service类标准方法。
 
 
 
1.3.2.1              客户端工程中加jar
 
如果使用cxf提供客户端类或方法,需要加入cxf的jar包。
 
1.3.2.2              Wsdl2java工具生成客户端调用代码
 
使用cxf的wsdl2java工具生成。
生成源文件:
 
 
 
 
 
 
1.3.3      小结
 
 Cxf编程方式实现webservice
 
JaxWsServerFactoryBean:发布webservice服务
 
 
JaxWsProxyFactoryBean:调用webservice服务端
 
 
Cxf和spring整合后,可以将上边的编程方式修改为spring配置方式实现。
内部 使用JaxWsServerFactoryBean和JaxWsProxyFactoryBean
 
 
1.3.4      Cxf发布soap1.2
使用cxf发布soap1.2不需要下载jaxws-ri扩展包。
 
在服务接口的上面添加
@BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
如下:
@WebService
@BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
public interface WeatherServerInterface
 
1       Cxfspring整合
1.1      思路
Cxf框架本身依赖spring,从官方下载cxf包中有spring的jar包。
 
上边使用JaxWsServerFactoryBean和JaxWsProxyFactoryBean,改为spring配置方式。
 
发布服务:使用spring和cxf整合的标签<jaxws:server
 
客户端调用服务:使用spring和cxf整合的标签<jaxws:client
 
上边的<jaxws:server和<jaxws:client相当于spring容器的bean,发布服务和客户端调用交给spring容器管理。
 
 
 
 
 
 
1.2      服务端
1.2.1      创建web工程
 
1.2.2      加入cxf的jar
 
 
1.2.3      开发SEI和实现类
 
Cxf开发SEI需要将@webservice注解加在接口中.
SEI接口:
 
SEI实现类:
 
1.2.4      编写applicationContext.xml
 
文件中约束包括:spring的、cxf和spring整合
 
 
 
1.2.1      web.xml中配置cxfservlet
cxf的servlet用于解析cxf发布webservice
 
 
 
 
1.2.2      在web.xml中加载spring
 
 
 
1.2.3      启动tomcat
 
 
1.2.4      测试注意
 
因为通过spring和cxf整合将webservice通过tomcat发布,webservice和应用程序共用一个端口都是8080
 
测试webservice和应用程序(jsp)是否可以共存(都可以访问)。
 
正式上线使用80端口。
  
 
 
 
 
      客户端
使用<jaxws:client调用服务端,<jaxws:client需要cxf和spring整合环境。
 
1.1.1      创建一个java工程
 
加入cxf的jar包。
 
 
1.1.2      使用wsdl2java/wsimport工具生成客户端调用代码
1.1.3      编写applicationContext.xml
 
使用<jaxws:client配置客户端调用服务端。
 
1.1.4      测试
 
 
 
 
1       回顾
 
CXF是apache下开源的webservice框架,cxf依赖spring进行模块集成。支持SOAP1.1,1,2XML/HTTPRESTful HTTP 或者 CORBA
 
如何使用 cxf发布soap1.1和soap1.2
 
使用jaxws实现SOAP1.1,1,2
 
方法1
 
Cxf编程实现:
  • 使用jaxwsServerFactoryBean发布 webservice服务端。
         需要设置:
                           jaxwsServerFactoryBean.setAddress(“webservice地址”)
                            jaxwsServerFactoryBean.setServiceClass(“porttype类路径”);//由程序员编写的
                            jaxwsServerFactoryBean.setServiceBean(“porttype类对象”);
                            jaxwsServerFactoryBean.create();//发布一个服务
  • 使用jaxwsProxyFactoryBean实现客户端调用webservice服务
                        jaxwsServerFactoryBean.setAddress(“webservice的wsdl地址”)
                   jaxwsServerFactoryBean.setServiceClass(“porttype类路径”);//portType是由wsdl2java工具生成
                   jaxwsServerFactoryBean.setCreate();//创建porttype对象
                  
 
方法2
Cxf和spring整合开发服务端和客户端。
  • 使用<jaxws:Server 发布 webservice服务端
在<jaxws:Server设置  Address、serviceClass、serviceBean
 
 
  • 使用<jaxws:Client 调用webservice服务
       在<jaxws:Server设置  Address、serviceClass
 
 
 
1       CXF发布rest风格的webservice
 
1.1      什么是restFul
 
REST 是一种软件架构模式,只是一种风格,rest服务采用HTTP 做传输协议,REST 对于HTTP 的利用分为以下两种:资源定位和资源操作。
 
 
  • 资源定位
 
更加准确去定位一个互联网资源。使用url定位一个互联网资源。
 
比如:查询一个学生信息url
 
资源定位要定位一个学生信息:
 
不使用rest的urlhttp://ip:port/queryUser.action?userType=XXX&studentid=001&XXXX
 
使用 rest的urlhttp://ip:port/user/student/001   
 
 
使用rest方式表达url更加简单、可以准确表达这个url是一个学生信息查询url
 
 
  • 资源操作
 
利用HTTP GETPOSTPUTDELETE 四种操作来表示数据库操作的SELECTUPDATEINSERTDELETE 操作。
 
比如:
更新学生信息:
设置http请求的方法为post
 
Rest方式一般要求url中不要有动词。动词采用GETPOSTPUTDELETE表示。
 
 
Rest风格是对http协议很好的诠释。
 
Rest好处:
定义的url对资源定位更加准确、简单。
 
Rest缺点:
如果rest的url定义层级比较多,可读性较差。
 
 
1.2      Cxf发布rest风格的webservice
1.2.1      目标
使用rest风格表示webservice,cxf发布的webservice地址就是rest风格.
rest风格webservice,不采用soap,直接采用http传输数据。
 
需求:
Rest  Get方法:
查询学生信息,传输参数学生信息id在url中定义。
比如:http://ip:port/user/student/001  001就是参数。
 
Rest一般返回结果:
xml或json
 
 
1.2.2      实现
 
使用cxf发布rest的webservice,使用jaxrs(java开发webservice一个规范)
 
1.2.2.1              创建web工程
 
1.2.2.2              加入cxf的jar
 
 
1.2.2.3              编写pojo
学生信息的pojo
 
要使用@XmlRootElement(name="student"),将pojo转成xml
 
 
 
1.2.2.4              编写SEI
 
 
1.2.2.5              编写SEI实现类
 
实现类中不用添加rest注解。
 
 
 
1.2.2.6              发布rest服务
使用JaxRSServerFactoryBean发布rest服务。
 
 
 
 
1.2.2.7              测试 rest服务
 
http://127.0.0.1:12345/rest/student/querylist/001?_type=json  查询学生信息列表,返回json
 
 
1.1.1.1              使用spring配置方式发布rest
编写applicationContext.xml
 
 
 
 
 
 
1.1.1.1              Rest服务的客户端ajax方式
上边发布的http的get服务。
使用http的get请求,调用rest接口(http的get请求接口)
 
可以在页面使用ajax请求rest地址
可以使用httpClient方式请求rest地址。
 
 
 
原文地址:https://www.cnblogs.com/YangBinChina/p/8967261.html