webService第一个案例学习
准备工作
1.myeclipse 10.7.1
2.jdk 1.7.0_79
1.新建Server端
1.文件—>新建JavaProject,命名为WebServer1
2.新建包,给包命名为top.wilma.www.day1.service
a.新建接口HelloWService
package top.wilma.www.day1.service; import javax.jws.WebMethod; import javax.jws.WebService; /** * SEI service interface * @authorwilma * */ @WebService publicinterface HelloWService { @WebMethod public String sayHello(String name); } |
b.新建实体类HelloWServicImpl
package top.wilma.www.day1.service.impl; import javax.jws.WebService; import top.wilma.www.day1.service.HelloWService; /** * SEI service implements class * @authorwilma **/ @WebService publicclass HelloWServiceImplimplements HelloWService { @Override public String sayHello(String name) { return name+":Hello!"; } } |
c.新建服务端测试类
package top.wilma.www.day1.service.test; import javax.xml.ws.Endpoint; import top.wilma.www.day1.service.impl.HelloWServiceImpl;
publicclass HelloWSTest { /** * @param args * @autho wilma */ publicstaticvoid main(String[] args) { String address ="http://127.0.0.1:8060/WebServer1/hello"; Endpoint.publish(address,new HelloWServiceImpl()); System.out.println("webservice publish success!"); } } |
刷新WebServer1
d.测试结果
右击HelloWTest类,run as ,选择Java Application 测试WebService 打开浏览器,访问地址http://127.0.0.1:8060/WebServer1/hello?wsdl 浏览器若能展示xml树形结构,则表示接口测试成功。 |
2.生成Client端
新建JavaProject,命名为WebServer_client,生成的代码放置于src下
使用命令窗口生成客户端
格式:wsimport –s–p “生成类所在包名” –keep “wsdl发布地址”。注:“wsdl发布地址”不要漏了“?wsdl”
切换到工作空间,刷新WebServer_client。在top.wilma.www.client包下新建测试类,命名为HelloWSTest
3.最终测试
注意事项:
1.JDK版本过低问题
报类似如下异常:runtimemodele error:Wrapper class
解决方法:jdk版本调整为1.6或1.6以上
2.生成命令不完整
命令路径不完整示例:
D:\Juze\Java\demo\myeclipse\WebServer1_client\src>wsimport-p top.wilma.www.day1
-keep http://127.0.0.1:8060/WebServer1/hello
命令完整示例
D:\Juze\Java\demo\myeclipse\WebServer1_client\src>wsimport -p top.wilma.www.day1
-keep http://127.0.0.1:8060/WebServer1/hello?wsdl
小节:采用jdk开发webservce要点
1.开发服务器端
@WebService(SEI和SEI的实现类)
@WebService (SEI中所有方法)
发布Web Servcie(Endpoint 终端)
2.开发客户端
使用eclipse提供webservcie的浏览器访问
查看对应的wsdl文档 (一般是用浏览器访问 url?wsdl )
请求webservice并查看请求和响应的信息(webservice 浏览器)
创建客户端应用编码方式访问
--借助jdk/bin wsimport.exe 工具生成客户端代码
wsimport -keep url //根据请求地址生成代码,url为wsdl文件的路径 url为web地址
dos命令窗口进入要保存代码的工作空间src下 执行命令
--借助生成的代码编写请求代码 //根据本地wsdl文件生成代码
dos命令窗口进入要保存代码的工作空间src下 wsimport -keep 本地wsdl文件路径
TCP/IP代理监控请求和响应信息
正常不使用TCP/IP等代理形式访问http://127.0.0.1:12345/getWeather?wsdl能显示信息,在使用代理后,在浏览器进行访问http://127.0.0.1:54321/getWeather?wsdl 能显示出内容,表明代理设置好了,在TCP/IP窗口中就能看到请求和响应信息。若使用这个工具进行监控客户端,需要改变SEI中的端口为代理端口即可。
WebServcie 第二个案例天气预报
根据提供schema文件来生成代码
制作schema文件
打开浏览器,访问http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl,然后右击查看网页源码,将其保存为.schema文件。
建立WebService Client端
新建Java Project,命名为WeatherProject.
在dos命令窗口下,进入到WeatherProject/src,执行wsimport –ptop.wilma.www.weather –keep D:\weather.wsdl 回车。
注意:直接生成客户端代码会抛异常,无法生成客户端代码
1.将对应的wsdl文档保存到本地
2.修改wsdl文档的部分内容
将<s:elementref="s:schema"/><s:any/> 改成<s:any minOccurs="2"maxOccurs="2"/>
注:这个是Java代码调用net的webservcie的问题
再次执行上方代码会打印“generate code… compiling code…”,OK
回到工作空间,刷新工程
根据生成的wsdl文件来写测试类。可根据“<wsdl:service name=”WeatherWS”> ”标签中的name即是工厂类。
package top.wilma.www.test;
import java.util.List;
import top.wilma.www.weather.ArrayOfString;
import top.wilma.www.weather.WeatherWS;
import top.wilma.www.weather.WeatherWSSoap;
publicclassWeatherTest {
publicstaticvoid main(String[] args) {
WeatherWSweatherWs = newWeatherWS();
WeatherWSSoapweatherWSSoap = weatherWs.getWeatherWSSoap();
ArrayOfStringarrayOfString = weatherWSSoap.getWeather("黄冈",null);
List<String>list = arrayOfString.getString();
/*for(int i=0;i<list.size();i++){
System.out.println(list.get(i)+"\n-----------------");
}*/
Stringweather = list.toString();
String[]weatherString = weather.split(",");
for(int j=0;j<weatherString.length;j++){
if(j==0){
System.out.print(weatherString[j].substring(1)+" ");
}
elseif(j==7 || j==8){
System.out.print(weatherString[j]+" ");
}
}
}
}
结果输出:
最新WebService免费接口大全:http://www.webxml.com.cn/zh_cn/index.aspx
天气预报接口:http://ws.webxml.com.cn/WebServices/WeatherWS.asmx
Webservice之CXF最简案例学习
准备工作
1.myeclipse 10.7.1
2.jdk 1.7.0_79
Jar包准备
apache-cxf-2.5.9\lib\asm-3.3.1.jar
apache-cxf-2.5.9\lib\cxf-2.5.9.jar
apache-cxf-2.5.9\lib\jetty-continuation-7.5.4.v20111024.jar
apache-cxf-2.5.9\lib\jetty-http-7.5.4.v20111024.jar
apache-cxf-2.5.9\lib\jetty-io-7.5.4.v20111024.jar
apache-cxf-2.5.9\lib\jetty-security-7.5.4.v20111024.jar
apache-cxf-2.5.9\lib\jetty-server-7.5.4.v20111024.jar
apache-cxf-2.5.9\lib\jetty-util-7.5.4.v20111024.jar
apache-cxf-2.5.9\lib\neethi-3.0.2.jar
apache-cxf-2.5.9\lib\wsdl4j-1.6.2.jar
apache-cxf-2.5.9\lib\xmlschema-core-2.0.3.jar
CXF环境变量配置。配置环境变量CXF_HOME。系统变量名CXF_HOME,变量值D:\Juze\Java\jar\apache-cxf-2.5.9。然后在path中末尾;%CXF_HOME/bin%即可。
步骤如下
1.文件-->新建-Web Service Project,命名为WebServiceCXF。然后导入cxf相关jar包。
2.新建-包名为top.wilma.www.day2.service。
3.新建服务接口和接口实现类
package top.wilma.www.day2.service; import javax.jws.WebService; /** * @title:ByeI.java * @description:服务接口 * @author:amliw * @date:2018-5-13 上午12:28:45 */ @WebService public interface ByeI { public String sayBye(String name); } | package top.wilma.www.day2.service; /** * @title:ByeImpl.java * @description:服务接口实现 * @author:amliw * @date:2018-5-13 上午12:32:31 */ public class ByeImpl implements ByeI { public String sayBye(String name) { return "Bye "+ name; } } |
<?xml version="1.0" encoding="UTF-8"?> <!-- 配置spring,把webservice类托管给spring,然后再src下新建配置文件applicationContext.xml --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <bean id="byeImpl" class="top.wilma.www.day2.service.ByeImpl"></bean> <!-- 配置cxf 地址:http://localhost:9999/WebServiceCXF 组成:http://localhost:9999/WebServiceCXF(项目名)+ws(过滤路径)+/byeI(自定义部分)--> <jaxws:server address="/byeService" serviceClass="top.wilma.www.day2.service.ByeI"> <jaxws:serviceBean> <ref bean="byeImpl"/> </jaxws:serviceBean> </jaxws:server> </beans> |
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" 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_2_5.xsd"> <display-name></display-name> <welcome-file-list> <welcome-file>CXF_Servers</welcome-file> </welcome-file-list> <!-- 添加 CXF 的Servlet ,处理 webservice的请求 --> <servlet> <servlet-name>cxfServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>cxfServlet</servlet-name> <url-pattern>/ws/*</url-pattern> </servlet-mapping> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> </web-app> |
服务端测试代码
package top.wilma.www.day2.test; import java.util.List; import javax.xml.ws.Endpoint; import org.apache.cxf.interceptor.Interceptor; import org.apache.cxf.interceptor.LoggingInInterceptor; import org.apache.cxf.interceptor.LoggingOutInterceptor; import org.apache.cxf.jaxws.EndpointImpl; import org.apache.cxf.message.Message; import top.wilma.www.day2.service.ByeImpl;
public class ServerCXFTest { public static void main(String[] args) { String address ="http://127.0.0.1:9999/WebServiceCXF/ws/byeService"; Endpoint endpoint = Endpoint.publish(address, new ByeImpl()); System.out.println(endpoint); /*日志输入拦截器*/ EndpointImpl endpointImpl = (EndpointImpl)endpoint; List<Interceptor<? extends Message>> intercepters = endpointImpl.getInInterceptors(); intercepters.add(new LoggingInInterceptor()); /*日志输出拦截器*/ List<Interceptor<? extends Message>> outIntercepters = endpointImpl.getOutInterceptors(); outIntercepters.add(new LoggingOutInterceptor()); } } |
运行测试代码,控制台打印日志信息
2018-5-13 17:05:07 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass 信息: Creating Service {http://service.day2.www.wilma.top/}ByeImplService from class top.wilma.www.day2.service.ByeI 2018-5-13 17:05:38 org.apache.cxf.endpoint.ServerImpl initDestination 信息: Setting the server's publish address to be http://localhost:9999/WebServiceCXF/ws/byeService 2018-05-13 17:05:38.853:INFO:oejs.Server:jetty-7.5.4.v20111024 2018-05-13 17:05:40.648:INFO:oejs.AbstractConnector:Started SelectChannelConnector@localhost:9999 STARTING 2018-05-13 17:05:41.265:INFO:oejsh.ContextHandler:started o.e.j.s.h.ContextHandler{/WebServiceCXF/ws,null} org.apache.cxf.jaxws.EndpointImpl@2a6ff |
运行myclipse工具栏Launch SOAP Web Service Explorer,点击右侧WSDL Page,点击左侧的WSDL Main,然后在WSDl url一栏中输入http://localhost:9999/WebServiceCXF/ws/byeService?wsdl,点击go发起请求,控制台会再次打印一些日志。
2018-5-13 17:06:21 org.apache.cxf.services.ByeImplService.ByeImplPort.ByeI 信息: Inbound Message ---------------------------- ID: 1 Address: http://localhost:9999/WebServiceCXF/ws/byeService?wsdl Http-Method: GET Content-Type: Headers: {Accept=[text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2], connection=[keep-alive], Content-Type=[null], Host=[localhost:9999], User-Agent=[Java/1.6.0_13]} |
接着点击左侧的sayBye方法,传入参数amilw,控制台接着打印信息
2018-5-13 17:15:15 org.apache.cxf.services.ByeImplService.ByeImplPort.ByeI 信息: Inbound Message ---------------------------- ID: 3 Address: http://localhost:9999/WebServiceCXF/ws/byeService Encoding: UTF-8 Http-Method: POST Content-Type: text/xml; charset=UTF-8 Headers: {Accept=[application/soap+xml, application/dime, multipart/related, text/*], Cache-Control=[no-cache], connection=[close], Content-Length=[342], content-type=[text/xml; charset=UTF-8], Host=[localhost:9999], Pragma=[no-cache], SOAPAction=[""], User-Agent=[IBM Web Services Explorer]} Payload: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://service.day2.www.wilma.top/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <q0:sayBye> <arg0>amilw</arg0> </q0:sayBye> </soapenv:Body> </soapenv:Envelope>
-------------------------------------- 2018-5-13 17:15:21 org.apache.cxf.services.ByeImplService.ByeImplPort.ByeI 信息: Outbound Message --------------------------- ID: 3 Encoding: UTF-8 Content-Type: text/xml Headers: {} Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayByeResponse xmlns:ns2="http://service.day2.www.wilma.top/"><return>Bye amilw</return></ns2:sayByeResponse></soap:Body></soap:Envelope> -------------------------------------- |
生成客户端代码
打开dos命令窗口,然后执行
C:\Users\admin>wsdl2java -encoding utf-8 -d D:/Juze/Java/demo/myeclipse/WebServi
ceCXF_C/src http://localhost:9999/WebServiceCXF/ws/byeService?wsdl
C:\Users\admin>
Wsdl2java生成客户端代码语法格式:wsdl2java -encoding utf-8 -d存放客户端代码路径 url(url?wsdl)。-encoding表示生成的Java文件编码格式为utf8,-d表示代码生成路径为D:/Juze/Java/demo/myeclipse/WebServiceCXF_C/src。
右击WebServiceCXF_C,选择刷新。新建top.wilma.www.day2.test.WebServiceCXF_C.java。接下来在怎么调用?先看下生成在xml文档,分析之后在写调用类与方法。
<?xml version="1.0" ?><wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://service.day2.www.wilma.top/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="ByeImplService" targetNamespace="http://service.day2.www.wilma.top/"> <wsdl:types> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://service.day2.www.wilma.top/" elementFormDefault="unqualified" targetNamespace="http://service.day2.www.wilma.top/" version="1.0"> <xs:element name="sayBye" type="tns:sayBye"></xs:element> <xs:element name="sayByeResponse" type="tns:sayByeResponse"></xs:element> <xs:complexType name="sayBye"> <xs:sequence> <xs:element minOccurs="0" name="arg0" type="xs:string"></xs:element> </xs:sequence> </xs:complexType> <xs:complexType name="sayByeResponse"> <xs:sequence> <xs:element minOccurs="0" name="return" type="xs:string"></xs:element> </xs:sequence> </xs:complexType> </xs:schema> </wsdl:types> <wsdl:message name="sayByeResponse"> <wsdl:part element="tns:sayByeResponse" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:message name="sayBye"> <wsdl:part element="tns:sayBye" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:portType name="ByeI"><!--wsdl:operation step3 --> <wsdl:operation name="sayBye"> <wsdl:input message="tns:sayBye" name="sayBye"> </wsdl:input> <wsdl:output message="tns:sayByeResponse" name="sayByeResponse"> </wsdl:output> </wsdl:operation> </wsdl:portType> <wsdl:binding name="ByeImplServiceSoapBinding" type="tns:ByeI"><!--wsdl:port binding step2 --> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"></soap:binding> <wsdl:operation name="sayBye"> <soap:operation soapAction="" style="document"></soap:operation> <wsdl:input name="sayBye"> <soap:body use="literal"></soap:body> </wsdl:input> <wsdl:output name="sayByeResponse"> <soap:body use="literal"></soap:body> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="ByeImplService"> <!--wsdl:service这个就是调用在入口 step1--> <wsdl:port binding="tns:ByeImplServiceSoapBinding" name="ByeImplPort"> <soap:address location="http://localhost:9999/WebServiceCXF/ws/byeService"></soap:address> </wsdl:port> </wsdl:service> </wsdl:definitions> |
根据这个xml文档来写测试类。
package top.wilma.www.day2.test; import top.wilma.www.day2.service.ByeI; import top.wilma.www.day2.service.ByeImplService; public class CXF_CTest { public static void main(String[] args) { ByeImplService byeImpleService = new ByeImplService(); ByeI byeI = byeImpleService.getByeImplPort(); System.out.println(byeI.sayBye("amilw")); } } 控制台输出:Bye amilw |
客户端是从wsdl:service往后开始找端口与方法。往往在实际项目开发在过程中,我们拿到在通常是一份文档,因此拿到一份文档知道怎么去找主类与调用方法是尤为重要的。这里有个根据IP查询返回地理位置名称:http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx?wsdl回车就能得到文档,可用于练习。
在完成这个demo前遇到以下问题,特记录下
错误1:Offending class: javax/servlet/Servlet.class
描述:tomcat的lib目录下已经有Servlet.class这个类了,工程目录下的lib的的某些jar包里又有,导致加载失败。
解决方案:清楚工程lib下多余的jar包。
错误2:NoClassDefFoundError: org/apache/commons/logging/LogFactory
描述:缺少 commons-logging.jar,也可以添加commons-logging-1.0.4.jar,建议使用后者或者更新版本
错误3:用wsdl2java -help检验wsdl2java报错。报错“wsdl2java 不是内部或外部命令,也不是可运行在程序”。
描述:需要配置环境变量CXF_HOME,在path中加“%CXF_HOME%\bin;”即可。可在dos命令窗口中用wsdl2java -v若能看到cxf相应在版本信息则表示CXF环境配置好了。
错误4:用wsdl2java生成客户端代码,生成在代码里面有好几处提示,The constructor Service(URL OName WebServiceFeature[]) is undefined。这是jdk版本在原因,换成jdk 1.7.0_79就好,低于jdk1.7在就提示错误。