JAVA6开发WebService (四)——SAAJ调用WebService
转载自http://wuhongyu.iteye.com/blog/810571
前面写了个JAX-WS的小例子,看到用JAVA6开发WebService确实很简单,也很方便,不过前面也说了,JAVA有三种WebService规范,JAX-WS是其中一种,现在来看看JAXM&SAAJ。
最近在做一个接口平台的项目,接口嘛,当然得涉及到对WebService的接口了,我们计划做成一个通用的平台,通过配置文件进行配置后就可以动态对某一个接口进行调用,但像前面的例子那样,每次都要生成一堆客户端代码,这可受不了。如果调用的接口唯一,生成一次客户端代码当然没问题,但如果要调用的接口是动态的,这就不好办了。因此,我需要了解SOAP更多底层的细节,由我自己来组织SOAP中的内容而不是完全由代码生成器生成。
仍使用前面例子中的服务器端:
接口:
实现类:
Customer类:
发布:
这次不生成客户端类,而是通过自己组织SOAP消息,向服务器发送请求。首先,我们需要一个到WebService服务的连接(就像Connection之于JDBC),通过javax.xml.soap.SOAPConnectionFactory的createConnection()可以获得一个WebService连接。获得连接之后,我们就可以组织我们的SOAP消息了。通过javax.xml.soap.MessageFactory的createMessage()方法,获得一个javax.xml.soap.SOAPMessage,SOAPMessage就是我们SOAP消息的入口。我们知道,SOAP其实就是一个XML,有了SOAPMessage这个入口,剩下的就是对XML的组织和解析了。对于SOAP消息的各个部分,SOAPMessage都有对应的接口:
// 获取SOAP连接工厂
SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
// 从SOAP连接工厂创建SOAP连接对象
SOAPConnection connection = factory.createConnection();
// 获取消息工厂
MessageFactory mFactory = MessageFactory.newInstance();
// 从消息工厂创建SOAP消息对象
SOAPMessage message = mFactory.createMessage();
// 创建SOAPPart对象
SOAPPart part = message.getSOAPPart();
// 创建SOAP信封对象
SOAPEnvelope envelope = part.getEnvelope();
// 创建SOAPHeader对象
SOAPHeader header = message.getSOAPHeader();
// 创建SOAPBody对
SOAPBody body = envelope.getBody();
把我们需要传递的参数组织好,通过connection.call方法进行对WebService的调用,他仍然会给我们返回一个SOAPMessage对象,对应服务器端的三个函数,我分别写了对应的三个方法对其进行调用,以下是我的客户端类:
package com.why.client;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Iterator;
import java.util.UUID;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.xml.namespace.QName;
import javax.xml.soap.AttachmentPart;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart; /**
*
* @author why
*
*/
public class SoapClient {
public static void main(String[] args) throws Exception{ printContext(); selectCustomerByName(); selectMaxAgeCustomer();
} /**
* 调用一个无参函数
* @throws Exception
*/
public static void printContext() throws Exception{
// 获取SOAP连接工厂
SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
// 从SOAP连接工厂创建SOAP连接对象
SOAPConnection connection = factory.createConnection();
// 获取消息工厂
MessageFactory mFactory = MessageFactory.newInstance();
// 从消息工厂创建SOAP消息对象
SOAPMessage message = mFactory.createMessage();
// 创建SOAPPart对象
SOAPPart part = message.getSOAPPart();
// 创建SOAP信封对象
SOAPEnvelope envelope = part.getEnvelope();
// 创建SOAPHeader对象
SOAPHeader header = message.getSOAPHeader();
// 创建SOAPBody对象
SOAPBody body = envelope.getBody(); // 创建XML的根元素
SOAPBodyElement bodyElementRoot = body.addBodyElement(new QName("http://server.why.com/", "printContext", "ns1")); // 访问Web服务地址
SOAPMessage reMessage = connection.call(message, new URL("http://127.0.0.1:8080/helloService"));
// 控制台输出返回的SOAP消息
OutputStream os = System.out;
reMessage.writeTo(os); connection.close();
} /**
* 调用一个在soap:HEADER中传递参数的函数
* @throws Exception
*/
public static void selectCustomerByName() throws Exception{
// 获取SOAP连接工厂
SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
// 从SOAP连接工厂创建SOAP连接对象
SOAPConnection connection = factory.createConnection();
// 获取消息工厂
MessageFactory mFactory = MessageFactory.newInstance();
// 从消息工厂创建SOAP消息对象
SOAPMessage message = mFactory.createMessage();
// 创建SOAPPart对象
SOAPPart part = message.getSOAPPart();
// 创建SOAP信封对象
SOAPEnvelope envelope = part.getEnvelope();
// 创建SOAPHeader对象
SOAPHeader header = message.getSOAPHeader();
// 创建SOAPBody对象
SOAPBody body = envelope.getBody(); // 创建XML的根元素
SOAPHeaderElement headerElementRoot = header.addHeaderElement(new QName("http://server.why.com/", "c", "ns1"));
SOAPBodyElement bodyElementRoot = body.addBodyElement(new QName("http://server.why.com/", "selectCustomerByName", "ns1"));
headerElementRoot.addChildElement(new QName("name")).addTextNode("why"); // 访问Web服务地址
SOAPMessage reMessage = connection.call(message, new URL("http://127.0.0.1:8080/helloService"));
// 控制台输出返回的SOAP消息
OutputStream os = System.out;
reMessage.writeTo(os); // 输出SOAP消息中的附件
Iterator<AttachmentPart> it = reMessage.getAttachments();
while (it.hasNext()) {
InputStream ins = it.next().getDataHandler().getInputStream();
byte[] b = new byte[ins.available()];
OutputStream ous = new FileOutputStream("c:\\aaa.jpg");
while (ins.read(b) != -1) {
ous.write(b);
}
ous.close();
}
connection.close();
} /**
* 调用一个在soap:Body中传递参数的函数
* @throws Exception
*/
public static void selectMaxAgeCustomer() throws Exception{
// 获取SOAP连接工厂
SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
// 从SOAP连接工厂创建SOAP连接对象
SOAPConnection connection = factory.createConnection();
// 获取消息工厂
MessageFactory mFactory = MessageFactory.newInstance();
// 从消息工厂创建SOAP消息对象
SOAPMessage message = mFactory.createMessage();
// 创建SOAPPart对象
SOAPPart part = message.getSOAPPart();
// 创建SOAP信封对象
SOAPEnvelope envelope = part.getEnvelope();
// 创建SOAPHeader对象
SOAPHeader header = message.getSOAPHeader();
// 创建SOAPBody对象
SOAPBody body = envelope.getBody(); // 设置Content-Type
MimeHeaders hd = message.getMimeHeaders();
hd.setHeader("Content-Type", "application/xop+xml; charset=utf-8; type=\"text/xml\""); // 创建XML的根元素
SOAPBodyElement bodyElementRoot = body.addBodyElement(new QName("http://server.why.com/", "selectMaxAgeCustomer", "ns1")); // 创建Customer实例1
SOAPElement elementC1 = bodyElementRoot.addChildElement(new QName("arg0"));
elementC1.addChildElement(new QName("id")).addTextNode("1");
elementC1.addChildElement(new QName("name")).addTextNode("A");
elementC1.addChildElement(new QName("birthday")).addTextNode("1989-01-28T00:00:00.000+08:00");
// 创建附件对象
AttachmentPart attachment = message.createAttachmentPart(new DataHandler(new FileDataSource("c:\\c1.jpg")));
// 设置Content-ID
attachment.setContentId("<" + UUID.randomUUID().toString() + ">");
attachment.setMimeHeader("Content-Transfer-Encoding", "binary");
message.addAttachmentPart(attachment);
SOAPElement elementData = elementC1.addChildElement(new QName("imageData")); // 添加XOP支持
elementData.addChildElement(
new QName("http://www.w3.org/2004/08/xop/include", "Include","xop"))
.addAttribute(new QName("href"),"cid:" + attachment.getContentId().replaceAll("<", "").replaceAll(">", "")); // 创建Customer实例2
SOAPElement elementC2 = bodyElementRoot.addChildElement(new QName("arg1"));
elementC2.addChildElement(new QName("id")).addTextNode("2");
elementC2.addChildElement(new QName("name")).addTextNode("B");
elementC2.addChildElement(new QName("birthday")).addTextNode("1990-01-28T00:00:00.000+08:00");
AttachmentPart attachment2 = message.createAttachmentPart(new DataHandler(new FileDataSource("c:\\c2.jpg")));
attachment2.setContentId("<" + UUID.randomUUID().toString() + ">");
message.addAttachmentPart(attachment2);
SOAPElement elementData2 = elementC2.addChildElement(new QName("imageData")); elementData2.addChildElement(
new QName("http://www.w3.org/2004/08/xop/include", "Include","xop"))
.addAttribute(new QName("href"),"cid:" + attachment2.getContentId().replaceAll("<", "").replaceAll(">", "")); // 控制台输出发送的SOAP消息
OutputStream os = new ByteArrayOutputStream();
message.writeTo(os);
String soapStr = os.toString();
System.out.println("\n@@@@@@@@@@@@@@@@@@\n"+soapStr+"\n@@@@@@@@@@@@@@@@@@"); // 访问Web服务地址
SOAPMessage reMessage = connection.call(message, new URL("http://127.0.0.1:8080/helloService"));
// 控制台输出返回的SOAP消息
OutputStream baos = new ByteArrayOutputStream();
reMessage.writeTo(baos);
String soapStr2 = baos.toString();
System.out.println("\n#############\n"+soapStr2+"\n################"); // // 输出SOAP消息中的第一个子元素的元素名称
System.out.println("\n<<<<<<<<<<<<<<<<<<<" + reMessage.getSOAPBody().getFirstChild().getLocalName());
// 输出SOAP消息中的附件
Iterator<AttachmentPart> it = reMessage.getAttachments();
while (it.hasNext()) {
InputStream ins = it.next().getDataHandler().getInputStream();
byte[] b = new byte[ins.available()];
OutputStream ous = new FileOutputStream("c:\\bbb.jpg");
while (ins.read(b) != -1) {
ous.write(b);
}
ous.close();
} connection.close(); }
}
使用SAAJ创建附件时,需设置Content-Type=application/xop+xml; charset=utf-8; type="text/xml",否则服务器端获取不到这个附件,查看发送给服务器端的SOAP消息可以看到,默认Content-Type被置为text/xml; charset=utf-8,因此,需在代码中加入:
MimeHeaders hd = message.getMimeHeaders(); hd.setHeader("Content-Type", "application/xop+xml; charset=utf-8; type=\"text/xml\"");
SOAPMessage有一个writeTo(OutputStream os)方法,可以将整个SOAP消息的内容写入一个输出流中,我们可以截获这个输出流的内容进行分析或再次整理。
JAVA6开发WebService (四)——SAAJ调用WebService的更多相关文章
- 浅谈WebService开发三(动态调用WebService)转
		
在前两讲里,我已经向大家演示了如何使用WebService.同步, 异步调用WebService,而在实际开发过程中,可能会有多个WebService接口供你选择,而在程序执行过程中才决定使用哪一个 ...
 - WebService – 2.动态调用WebService
		
在本节课程中,将演示如何通过程序动态添加.调用.编译.执行WebService并返回结果. WebService动态调用示意图 WebService相关知识 代码文档对象模型CodeDom的使用 编程 ...
 - C# 不用添加WebService引用,调用WebService方法
		
// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行. [System.Web.Script.Services.ScriptService] 使用HttpWeb ...
 - IOS开发笔记 - 基于wsdl2objc调用webservice
		
为了方便在ios下调用webserivce,找来了wsdl2objc这样一个开源的框架来解析webservice方便在ios下引用. 下面做个小例子. 1.首先是用Asp.net搭建一个测试的webs ...
 - WebService – 3.后台调用WebService,根级别上的数据无效
		
1.因为我的webservice返回的是json, 2.ajax传递跨域不安全, 3.contentType: "application/json; charset=utf-8", ...
 - nginx开发(四)调用ffmpeg,搭建rtmp直播流。
		
1: 修改conf文件,配置rtmp直播 打开usr/local/nginx/conf/nginx.conf,添加红色内容: rtmp {#rtmp点播配置 server { li ...
 - 搭建调用 WebService 的 ASP.NET 网站 (VS2010, C#)
		
[系统环境]Windows 7 / 2008r2 [软件环境]Visual Studio 2010 [开发语言]C# [感谢]本文是在 <C#开发和调用Web Service> 一文的基础 ...
 - 异步调用webservice
		
一.异步调用 asynchronous call(异步调用):一个可以无需等待被调用函数的返回值就让操作继续进行的方法 举例: 异步调用就是你 喊 你朋友吃饭 ,你朋友说知道了 ,待会忙完去找你 ,你 ...
 - 【学习篇:他山之石,把玉攻】jquery实现调用webservice
		
1.webservice端 using System; using System.Collections.Generic; using System.Web; using System.Web.Ser ...
 
随机推荐
- 2016.8.16  HTML5重要标签及其属性学习
			
1.运用BootStrap的基本布局: 2.基本布局第二步: ] 3.BootStrap提供了一个class=”well“”类,可以给你种深度的感觉: 4.不是每一个类都是为了CSS,有些类创建出来只 ...
 - DSP using MATLAB 示例Example3.17
 - CSS总结1
			
新增:修改placeholder样式 ::-moz-placeholder{color:red;} //ff19+ :-moz-placeholder{color:red} //ff18- ::-we ...
 - jQuery跨域
			
其实jQuery跨域很简单很简单,你记住格式就好,跨域的原理请参考 <jsonp跨域> jQuery跨域代码: $.ajax({ url:'https://suggest.taobao.c ...
 - Eclipse中使用maven构建web项目中遇到的问题
			
构建过程参考: http://blog.csdn.net/smilevt/article/details/8215558/ http://www.cnblogs.com/dcba1112/archiv ...
 - Shell 编程基础之 While 练习
			
一.语法 while [ condition ] # 当 condition 条件成立时,就进行循环,直到条件不成立停止 do #执行内容 done 二.练习 输入用户输入的参数,直到用户输入 &qu ...
 - c#如何使用正则表达式ZZ
			
什么是正则表达式 正则表达式是用来检验和操作字符串的强大工具.简单的理解正则表达式可以认为是一种特殊的验证字符串.正则表达式常见运用是验证用户输入信息格式,比如上面的那组"\w{1 ...
 - iOS之05-三大特性之封装
			
本次主要学习面向对象的三大特性:封装.继承和多态中的封装 封装 1. 好处 降低耦合率 可重复调用类中的属性 提高安全性,外部不能随便修改变量的值,保证了数据的安全性 2. set方法 1.作用:提供 ...
 - ccc tiledmap
			
//移动方向枚举类 var MoveDirection = cc.Enum({ NONE: 0, UP: 1, DOWN: 2, LEFT: 3, RIGHT: 4 }); var minTilesC ...
 - (转)yarn 集群部署,遇到的问题小结
			
link:http://blog.csdn.net/uniquechao/article/details/26449761 版本信息: hadoop 2.3.0 hive 0.11.0 1. ...