Java之webService知识
1 webservice基础知识
1.1 webService请求的本质
一次webService本质请求,如下所示:
1.2 wsdl文档解析
wsdl文档元素结果,及相应关系如下:
2 JDK创建webService的方法
2.1 jdk服务端创建
2.1.1 创建一个java项目和相应的包
2.1.2 创建一个提供webservice服务的接口HelloWs,如下所示
2.1.3 创建接口的实现类HelloWsImpl,如下所示
2.1.4 创建一个java类,用于发布webservice服务
2.2 jdk客户端创建
2.2.1 创建一个客户端java工程
2.2.2 通过cmd进入到项目的src目录下,执行命令
wsimport -keep http://localhost:8090/helloWs?wsdl 如下所示
2.2.3 刷新项目,根据wsdl文档,创建客户端测试方法WsClientTest
2.2.4 执行客户端测试方法,即可获取到webservice服务端返回的数据。
3 通过wsdl文档创建客户端
3.1 远程wsdl文档创建
3.1.1 已知可用的wsdl文档为:http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl
先通过eclipse的webservice浏览器访问测试,所示如下
3.1.2 通过cmd窗口,采用
wsimport -keep http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl 生成客户端
报错如下原因:.net语言编写的webservice服务端;
解决方法:见‘3.2 本地wsdl文档创建’
3.2 本地wsdl文档创建
3.2.1 首先用浏览器解析wsdl文件,并在项目中新建一个wsdl文件,将浏览器wsdl中内容拷贝到eclipse的wsdl文件中
3.2.2 将<s:element ref="s:schema" /> <s:any />全部替换为
<s:any minOccurs="2" maxOccurs="2" />
3.2.3 在cmd中用wsimport命令生成客户端代码,
Wsimport -keep wsdl文档物理路径
这时候的wsdl路径为eclipse文件中的路径,创建的时候有些警告信息,可忽略
3.2.4 刷新项目,编写客户端代码测试
4 cxf创建webService的方法
4.1 cxf环境搭建
4.1.1 去官网下载cxf压缩文件:http://cxf.apache.org/download.html解压后,把apache-cxf-2.4.1\lib目录下的jar包引用到java项目中。添加path:D:\software\apache-cxf-3.1.8\bin信息用于生成客户端。
4.2 cxf创建服务端
4.2.1 创建一个java项目,引入必须的jar包,编写服务端(方式同“jdk服务端创建”)
4.3 cxf创建客户端
4.3.1 cmd通过命令wsdl2java http://localhost:8081/dcp/webservice/dataType?wsdl 生成客户端代码,编写客户端测试代码(方式同“jdk客户端创建”)
5 通过ajax发送请求
6 通过jquery发送请求
在传递参数的时候,需要注意的是,ajax请求的参数的名称必须和WebService中的方法的名称一致,否则调用不能成功。下面是一段WebService测试代码:
$.ajax({ url: "WebService1.asmx/WS2", contentType: "application/json; charset=utf-8", type: "POST", dataType: "json", data: "{s:‘POST有参数‘}", success: function(json) { alert(json.d); }, error: function(x, e) { alert(x.responseText); ; }, complete: function(x) { alert(x.responseText); } });
7 通过HttpUrlConnection 发送请求
7.1 get方式获取
代码示例如下:
/** * get请求方式 * @param mobile_number * @throws Exception */ public static String getHttpByGet(String mobile_number) throws Exception{ String address = "http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx/getMobileCodeInfo?mobileCode="+mobile_number+"&userID="; URL url = new URL(address); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 获取从服务器返回的数据 InputStream is = conn.getInputStream(); byte[] buffer = new byte[1024]; int len = 0; String result = ""; while( (len = is.read(buffer))!=-1 ){ String ss = new String(buffer,0,len,"UTF-8"); result += ss; } /* 返回的是拦截中的返回体,形式如下 <?xml version="1.0" encoding="utf-8"?> <string xmlns="http://WebXml.com.cn/"> 18770093059:江西 南昌 江西移动全球通卡 </string> */ // 关闭流 is.close(); conn.disconnect(); return result; };
7.2 post方式获取
示例代码如下:
/** * post请求方式 * @param mobile_number * @throws Exception */ public static String getHttpByPost(String mobile_number) throws Exception{ String address = "http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx/getMobileCodeInfo"; URL url = new URL(address); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 设置允许发送信息,默认为false conn.setDoInput(true); // 设置允许输出信息,默认为true conn.setDoOutput(true); // 设置发送请求方式,默认为GET conn.setRequestMethod("POST"); /* 设置发送内容类型 * text/xml; * application/soap+xml; * application/x-www-form-urlencoded; */ conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); //构造请求体消息 String soap = "mobileCode="+mobile_number+"&userID="; // 构造输出流 OutputStream os = conn.getOutputStream(); // 向输出流写信息 os.write(soap.getBytes("utf-8")); // 获取从服务器返回的数据 InputStream is = conn.getInputStream(); byte[] buffer = new byte[1024]; int len = 0; String result = ""; while( (len = is.read(buffer))!=-1 ){ String ss = new String(buffer,0,len,"UTF-8"); result += ss; } /* 返回的是拦截中的返回体,形式如下 <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <getMobileCodeInfoResponse xmlns="http://WebXml.com.cn/"> <getMobileCodeInfoResult>18770093059:江西 南昌 江西移动全球通卡</getMobileCodeInfoResult> </getMobileCodeInfoResponse> </soap:Body> </soap:Envelope> */ // 关闭流 os.close(); is.close(); conn.disconnect(); return result; }; /** * get请求方式 * @param mobile_number * @throws Exception */ public static String getHttpByGet(String mobile_number) throws Exception{ String address = "http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx/getMobileCodeInfo?mobileCode=" +mobile_number+"&userID="; URL url = new URL(address); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 获取从服务器返回的数据 InputStream is = conn.getInputStream(); byte[] buffer = new byte[1024]; int len = 0; String result = ""; while( (len = is.read(buffer))!=-1 ){ String ss = new String(buffer,0,len,"UTF-8"); result += ss; } /* 返回的是拦截中的返回体,形式如下 <?xml version="1.0" encoding="utf-8"?> <string xmlns="http://WebXml.com.cn/">18770093059:江西 南昌 江西移动全球通卡</string> */ // 关闭流 is.close(); conn.disconnect(); return result; };
7.3 soap方式获取
示例代码如下:
/** * soap1.2 请求方式 * @param mobile_number * @throws Exception */ public static String getHttpBySoap(String mobile_number) throws Exception{ String address = "http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx"; URL url = new URL(address); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 设置允许发送信息,默认为false conn.setDoInput(true); // 设置允许输出信息,默认为true conn.setDoOutput(true); // 设置发送请求方式,默认为GET conn.setRequestMethod("POST"); /* 设置发送内容类型 * text/xml; * application/soap+xml; */ conn.setRequestProperty("Content-Type", "application/soap+xml;charset=UTF-8"); //构造请求体消息 String soap = "<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " + "xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">" + "<soap12:Body>" + " <getMobileCodeInfo xmlns=\"http://WebXml.com.cn/\">" + " <mobileCode>"+mobile_number+"</mobileCode>" + " <userID></userID>" + " </getMobileCodeInfo>" + "</soap12:Body>" + "</soap12:Envelope>"; // 构造输出流 OutputStream os = conn.getOutputStream(); // 向输出流写信息 os.write(soap.getBytes("utf-8")); // 获取从服务器返回的数据 InputStream is = conn.getInputStream(); byte[] buffer = new byte[1024]; int len = 0; String result = ""; while( (len = is.read(buffer))!=-1 ){ String ss = new String(buffer,0,len,"UTF-8"); result += ss; } /* 返回的是拦截中的返回体,形式如下 <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <getMobileCodeInfoResponse xmlns="http://WebXml.com.cn/"> <getMobileCodeInfoResult>18770093059:江西 南昌 江西移动全球通卡</getMobileCodeInfoResult> </getMobileCodeInfoResponse> </soap:Body> </soap:Envelope> */ // 关闭流 os.close(); is.close(); conn.disconnect(); return result; };
7.4 解析xml格式字符串方式
采用jdom解析,需下载jaxen-1.1-beta-9.jar、jdom-1.0.jar
/** * 解析xml格式的字符串,获取需要的内容 * @param info * @return */ public static String parseXml(String info) { StringReader read = new StringReader(info.toString()); InputSource source = new InputSource(read); SAXBuilder sax = new SAXBuilder(); Document doc = null; try { doc = sax.build(source); Element root = doc.getRootElement(); return root.getValue(); } catch (JDOMException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return info; }
8 通过xfire创建webService的方法
8.1 服务端创建
8.1.1 创建webservice接口和webservice接口实现类,引入相应jar包
8.1.2 配置web.xml文件,增加如下配置信息
<!-- 提供webservice 服务 --> <servlet> <servlet-name>xfire</servlet-name> <servlet-class>org.codehaus.xfire.transport.http.XFireConfigurableServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>xfire</servlet-name> <url-pattern>/webservice/*</url-pattern> </servlet-mapping>
8.1.3 配置/XX/src/META-INF/xfire/services.xml文件
<?xml version="1.0" encoding="UTF-8"?> <beans> <service xmlns="http://xfire.codehaus.org/config/1.0"> <name>DcpWebService</name> <!-- <namespace>http://localhost:80/dcp/webservice/DcpWebService</namespace> --> <serviceClass>com.neusoft.education.dcp.webservice.DcpWebService</serviceClass> <implementationClass>com.neusoft.education.dcp.webservice.DcpWebServiceImpl</implementationClass> <!-- <inHandlers> <handler handlerClass="com.neusoft.education.dcp.webservice.AuthenticationHandler"></handler> </inHandlers> --> </service> </beans>
8.1.4 随着服务器启动自动发布webservice服务。
8.2 客户端创建
说明:使用xfire调用webservice主要应对返回类型为字符串或json格式。
8.2.1 方式一:使用xfire API Client类的invoke方法调用,需引入xfire-all-1.2.6.jar、XmlSchema.jar等相应jar包
示例代码如下:
Client client = new Client(new URL( "http://localhost:9999/WebServiceProject/services/IMyService?wsdl")); Object[] results = client.invoke("example", new Object[] { "hello world" }); System.out.println(results[0]);
8.2.2 方式二:使用服务端接口方式调用
Service srvcModel = new ObjectServiceFactory().create(IIMyService.class); XFireProxyFactory factory = new XFireProxyFactory(XFireFactory.newInstance().getXFire()); String helloWorldURL = "http://localhost:9999/WebServiceProject/services/MyService"; try { IIMyService srvc = (IIMyService)factory.create( srvcModel, helloWorldURL); String result = srvc.example("hello world"); System.out.print(result); } catch (MalformedURLException e) { e.printStackTrace(); }
9 通过axis 创建webService的方法
9.1 axis 服务端创建
9.1.1 创建一个web工程,引入相应jar包放入lib下
9.1.2 web.xml中增加axis配置信息,示例如下:
9.1.3 创建一个server-config.wsdd放在WEB-INF/server-config.wsdd下,内容示例如下
9.1.4 根据配置,创建相应的webservice接口和接口实现类,不需要任何注解
9.1.5 配置tomcat服务器,启动服务器,可以访问wsdl文档,代表服务端创建成功
http://localhost:8080/ws_axis_server/services/helloWs?wsdl
9.2 axis客户端创建
9.2.1 创建项目,加入相应的jar包,编写测试类,具体示例如下:
package com.neusoft.education.test; import java.net.URL; import javax.xml.rpc.ParameterMode; import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.axis.encoding.XMLType; /** * Axis 方法调用webservice服务端 */ public class AxisClientTest { public static void main(String[] args) throws Exception { sayHelloTest("Cat"); sayHelloTest("Tom"); } public static String getSortTest(){ // 1.创建一个axis service Service service = new Service(); // 2.创建url对象 String wsdlUrl = "http://oa.ecjtu.jx.cn/domcfg.nsf/OAInfo?WSDL"; URL url = null; String res = ""; try { //通过URL类的构造方法传入wsdlUrl地址创建URL url = new URL(wsdlUrl); Call call = (Call) service.createCall(); call.setTargetEndpointAddress(url);//给call对象设置请求的URL属性 call.setOperationName("GETSORT");//给call对象设置调用方法名属性 call.addParameter("LOGINID", XMLType.SOAP_STRING, ParameterMode.IN);// 给call对象设置方法的参数名、参数类型、参数模式 call.addParameter("LOGINPASS", XMLType.SOAP_STRING, ParameterMode.IN);// 给call对象设置方法的参数名、参数类型、参数模式 call.addParameter("DBKEY", XMLType.SOAP_STRING, ParameterMode.IN);// 给call对象设置方法的参数名、参数类型、参数模式 call.setReturnType(XMLType.XSD_ANYTYPE);// 设置调用方法的返回值类型 // 4.通过invoke方法调用webservice res = (String) call.invoke(new Object[] {"Portal","Portal","XXWJ"});//调用服务方法 } catch (Exception e) { e.printStackTrace(); } // 3.创建服务方法的调用者对象call,设置call对象的属性 return res; }}
10 常见webservice调用错误
10.1 服务器未能识别 HTTP 头 SOAPAction 的值
10.1.1 使用java调用.net的WebService,通过“8.2.2 方式二:使用服务端接口方式调用”如果报错,则在.NET 的 WebService 类(即 .asmx 文件下的类)添加属性 [SoapDocumentService(RoutingStyle=SoapServiceRoutingStyle.RequestElement)],可行的通。