- 浏览: 3506892 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
wanglf1207:
EJB的确是个不错的产品,只是因为用起来有点门槛,招来太多人吐 ...
weblogic-ejb-jar.xml的元素解析 -
qwfys200:
总结的不错。
Spring Web Flow 2.0 入门 -
u011577913:
u011577913 写道也能给我发一份翻译文档? 邮件437 ...
Hazelcast 参考文档-4 -
u011577913:
也能给我发一份翻译文档?
Hazelcast 参考文档-4 -
songzj001:
DbUnit入门实战
his document describes how to successfuly use WSDL faults in webservices implemented in C using gSOAP or in Java using Apache Axis for reporting unusual return values. It assumes that you know how to use gSOAP and Axis.
Content
- What are WSDL faults ?
- WSDL faults in gSOAP and Axis
- Generating WSDL
- Writing a client in gSOAP
- Writing a server in gSOAP
- Writing a client in Axis
- Deploying a server in Axis
What are WSDL faults ?
Exceptions in programming languages
In some programming languages, like Java and C++, a method (function)
can throw so called "exception", which is basicaly an object
returned instead of the normal return value if something
unusual (exceptional) happens. For example when dividing two integers,
the return value is normally an integer. But if the second one
is zero, no value is returned and an instance of java.lang.ArithmeticException
class is "thrown".
The type of the object indicates the problem
which just occured (ArithmeticException
) so that it can be handled programaticaly,
and in Java each exception has a human-understandable
text associated with it, which can be used by humans to resolve the problem,
in this example the text is "/ by zero
".
The exception can be "catched" and processed using special language
constructs (try{ ... } catch (Exception ex) { ... }
) or
left propagating up from the current method to its calling method.
This greatly simplifies processing errors.
Checked and unchecked exceptions
There are two types of exceptions, checked
and unchecked
ones.
Checked exceptions must be declared in method signatures together with
parameters and return value, while unchecked exception don't have to be declared.
Typicaly checked exceptions are used when a method needs to make
its users aware of the known exceptional states which can happen.
For example most of methods in the java.io
package can throw
checked IOException
when some Input/Output problem happens.
Unchecked exceptions are used for errors which are too common to be declared,
like NullPointerException
thrown when an object variable
is empty and thus a method cannot be called on it.
SOAP Faults
Webservices have similar concept of faults . As with checked and unchecked exceptions, there are two types of them. Some are user-defined and declared in WSDL (like checked exceptions), and some can happen anytime on the SOAP layer during communication, so they are not declared (like unchecked exceptions). The declared ones are called WSDL faults.
WSDL Faults
Interface of a webservice is described independently of any programming language
using WSDL language.
The WSDL language allows to have three types of messages - input
, output
and fault
.
The fault message can have only one part, which can be a XML Schema complex type,
thus containing several values. Let's see an example of a service called
MyService
which has one operation called myOperation
with one input parameter myInput
, one return value of type string
and two possible faults named MyFirstException
and MySecondException
. The faults carry values in them, the first one has some text and the second one has a number.
<?xml version="1.0" encoding="UTF-8"?> <definitions name="MyService" targetNamespace="urn:myuri:1.0" xmlns:tns="urn:myuri:1.0" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="urn:myuri:1.0" xmlns:SOAP="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:MIME="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:DIME="http://schemas.xmlsoap.org/ws/2002/04/dime/wsdl/" xmlns:WSDL="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"> <types> <schema targetNamespace="urn:myuri:1.0" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="urn:myuri:1.0" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified" attributeFormDefault="unqualified"> <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/> <!-- fault element --> <element name="MyFirstException"> <complexType> <sequence> <element name="text" type="xsd:string" minOccurs="1" maxOccurs="1" nillable="false"/> </sequence> </complexType> </element> <!-- fault element --> <element name="MySecondException"> <complexType> <sequence> <element name="number" type="xsd:int" minOccurs="1" maxOccurs="1"/> </sequence> </complexType> </element> <!-- operation request element --> <element name="myOperation"> <complexType> <sequence> <element name="myInput" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/> </sequence> </complexType> </element> <!-- operation response element --> <element name="myOperationResponse"> <complexType> <sequence> <element name="myOutput" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/> </sequence> </complexType> </element> </schema> </types> <message name="myOperationRequest"> <part name="parameters" element="ns1:myOperation"/> </message> <message name="myOperationResponse"> <part name="parameters" element="ns1:myOperationResponse"/> </message> <message name="MySecondExceptionFault"> <part name="fault" element="ns1:MySecondException"/> </message> <message name="MyFirstExceptionFault"> <part name="fault" element="ns1:MyFirstException"/> </message> <portType name="MyType"> <operation name="myOperation"> <documentation>Service definition of function ns1__myOperation</documentation> <input message="tns:myOperationRequest"/> <output message="tns:myOperationResponse"/> <fault name="MySecondException" message="tns:MySecondExceptionFault"/> <fault name="MyFirstException" message="tns:MyFirstExceptionFault"/> </operation> </portType> <binding name="MyService" type="tns:MyType"> <SOAP:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="myOperation"> <SOAP:operation soapAction=""/> <input> <SOAP:body use="literal"/> </input> <output> <SOAP:body use="literal"/> </output> <fault name="MySecondException"> <SOAP:fault name="MySecondException" use="literal"/> </fault> <fault name="MyFirstException"> <SOAP:fault name="MyFirstException" use="literal"/> </fault> </operation> </binding> <service name="MyService"> <documentation>gSOAP 2.7.1 generated service definition</documentation> <port name="MyService" binding="tns:MyService"> <SOAP:address location="http://localhost:10000"/> </port> </service> </definitions>
This webservice can be implemented in any language, even in C, and still it will have the option to return a fault instead of the usual string return value. Because the WSDL is independent of any language, it does not provide a place to store a stack trace associated with Java exceptions for example, because a client implemented in C would not know what to do with the stacktrace.
A SOAP message with the first fault looks like this:
HTTP/1.1 500 Internal Server Error Server: gSOAP/2.7 Content-Type: text/xml; charset=utf-8 Content-Length: 577 Connection: close <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:myuri:1.0"> <SOAP-ENV:Body> <SOAP-ENV:Fault> <faultcode>SOAP-ENV:Client</faultcode> <faultstring>Deliberately thrown exception.</faultstring> <detail> <ns1:MyFirstException> <text>Input values are wrong.</text> </ns1:MyFirstException> </detail> </SOAP-ENV:Fault> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
So, in short, WSDL faults are alternative return messages declared in WSDL. They can be used to return structured information when an error occurs.
WSDL faults in gSOAP and Axis
WSDL faults are working among gSOAP and Axis clients and servers only when using latest versions of the tools (in the moment of this writing), gSOAP 2.7.1 and Axis 1.2RC3. And you should use "document/literal wrapped" style for WSDL which is default now in gSOAP and can be used in Axis too. Older versions and other WSDL styles are known to have problems.
Generating WSDL
The WSDL example above was generated using gSOAP. I have found that nowadays gSOAP produces much better WSDL files than Axis, even if several years ago it was the other way round.
The following file was used to generate it. Please note that the names of exception structures begin with underscores. That's a requirement which is not mentioned in the gSOAP user guide as of time of this writing.
//gsoap ns1 service name: MyService //gsoap ns1 service type: MyType //gsoap ns1 service port: http://localhost:10000 //gsoap ns1 service namespace: urn:myuri:1.0 struct _ns1__MyFirstException { char* text 1; }; struct _ns1__MySecondException { int number 1; }; //gsoap ns1 service method-fault: myOperation _ns1__MyFirstException //gsoap ns1 service method-fault: myOperation _ns1__MySecondException int ns1__myOperation( char * myInput, struct ns1__myOperationResponse { char *myOutput; } * );
Writing a client in gSOAP
Now it is the time to write a client in gSOAP. Creat an empty directory and create there a Makefile with following content. It assumes that GSOAPDIR is set to the location of gSOAP:
Makefile
SOAPCPP2=$(GSOAPDIR)/soapcpp2 WSDL2H=$(GSOAPDIR)/wsdl2h all: client server soapC.c: faultdemo.h "$(SOAPCPP2)" -c faultdemo.h client: client.c soapC.c gcc -g -I. -DDEBUG -o client client.c soapClient.c soapC.c stdsoap2.c server: server.c soapC.c gcc -g -I. -o server server.c soapServer.c soapC.c stdsoap2.c clean: rm -rf *.xml *.nsmap soap* *.xsd *.log client server MyService.wsdl core
You also need a file with source code for the client:
client.c
#include "soapH.h" #include "MyService.nsmap" void processFault(struct soap *soap); int main(int argc,char** argv) { struct soap *soap = soap_new(); struct ns1__myOperationResponse out; char * url = "http://localhost:10000/"; //char * url = "http://localhost:8080/axis/services/MyService" ; if(argc==2) { url = argv[1]; } printf("calling first ...\n"); if(soap_call_ns1__myOperation(soap,url,"","first",&out) == SOAP_OK) { printf("OK\n"); } else { processFault(soap); } printf("\ncalling second ...\n"); if(soap_call_ns1__myOperation(soap,url,"","second",&out) == SOAP_OK) { printf("OK\n"); } else { processFault(soap); } } void processFault(struct soap *soap) { soap_print_fault(soap, stderr); if((soap->fault != NULL) && (soap->fault->detail != NULL)) { switch (soap->fault->detail->__type) { case SOAP_TYPE__ns1__MyFirstException: { struct _ns1__MyFirstException * ex = (struct _ns1__MyFirstException *) soap->fault->detail->fault; if(ex!=NULL) { printf("MyFirstException.text=%s\n",ex->text); } }; break; case SOAP_TYPE__ns1__MySecondException: { struct _ns1__MySecondException * ex = (struct _ns1__MySecondException *) soap->fault->detail->fault; if(ex!=NULL) { printf("MySecondException.number=%d\n",ex->number); } }; break; } } }
And finaly you need to copy files stdsoap2.c
and stdsoap2.h
from
your gSOAP installation and type "make client". That will generate WSDL, communication stubs
and compile the client.
Writing a server in gSOAP
In the same directory create a file with source of gSOAP server.
server.c
#include "soapH.h" #include "MyService.nsmap" int ns1__myOperation(struct soap* soap,char * myInput,struct ns1__myOperationResponse *out) { soap_sender_fault(soap,"Deliberately thrown exception.",NULL); soap->fault->detail = (struct SOAP_ENV__Detail*)soap_malloc(soap, sizeof(struct SOAP_ENV__Detail)); soap->fault->detail->__any = NULL; if(strncmp(myInput,"first",5)==0) { struct _ns1__MyFirstException *ex = (struct _ns1__MyFirstException *) soap_malloc(soap,sizeof(*ex)); ex->text = "Input values are wrong."; soap->fault->detail->__type = SOAP_TYPE__ns1__MyFirstException; soap->fault->detail->fault = ex; } else { struct _ns1__MySecondException *ex = (struct _ns1__MySecondException *) soap_malloc(soap,sizeof(*ex)); ex->number = 1111; soap->fault->detail->__type = SOAP_TYPE__ns1__MySecondException; soap->fault->detail->fault = ex; } return SOAP_FAULT; } int port = 10000; int main() { struct soap soap; int i, m, s; soap_init(&soap); m = soap_bind(&soap, NULL, port, 100); if (m < 0) soap_print_fault(&soap, stderr); else { fprintf(stderr, "Running on port %d\n",port); for (i = 1; ; i++) { s = soap_accept(&soap); fprintf(stderr, "%d: accepted connection from IP=%d.%d.%d.%d\n", i, (soap.ip >> 24)&0xFF, (soap.ip >> 16)&0xFF, (soap.ip >> 8)&0xFF, soap.ip&0xFF); if (s < 0) { soap_print_fault(&soap, stderr); break; } if (soap_serve(&soap) != SOAP_OK) { // process RPC request soap_print_fault(&soap, stderr); // print error } fprintf(stderr, "request served\n"); soap_destroy(&soap); // clean up class instances soap_end(&soap); // clean up everything and close socket } } soap_done(&soap); // close master socket }
Type "make server". That will compile the server. Now run the gSOAP client against the gSOAP server. The client makes two calls, each ends with different fault.
$ ./server & $ ./client calling first ... SOAP FAULT: SOAP-ENV:Client "Deliberately thrown exception." MyFirstException.text=Input values are wrong. calling second ... SOAP FAULT: SOAP-ENV:Client "Deliberately thrown exception." MySecondException.number=1111
Creating a client in Axis
For creating client and server using Axis, you need Axis installation location set in variable AXIS_HOME and TomCat installation in CATALINA_BASE.
First we must generate stub classes from the WSDL and write a client.
CallMyService.java
import faultdemo.*; import java.rmi.RemoteException; import java.net.URL; public class CallMyService { public static void main(String [] args) throws Exception { String url = "http://localhost:10000/"; //String url = "http://localhost:8080/axis/services/MyService"; MyType myType = new MyServiceLocator().getMyService(new URL(url)); String[] inputs = new String[] { "first", "second" }; for(int i=0;i<2;i++) { try { myType.myOperation(inputs[i]); } catch (MyFirstException ex) { System.out.println("MyFirstException"); System.out.println("ex.faultstring="+ex.getFaultString()); System.out.println("ex.text="+ex.getText()); } catch (MySecondException ex) { System.out.println("MySecondException"); System.out.println("ex.faultstring="+ex.getFaultString()); System.out.println("ex.number="+ex.getNumber()); } } } }
export CLASSPATH=. for i in "$AXIS_HOME"/lib/*.jar; do CLASSPATH="$i:$CLASSPATH"; done for i in "$CATALINA_BASE/common/lib"/*.jar; do CLASSPATH="$i:$CLASSPATH"; done echo $CLASSPATH java org.apache.axis.wsdl.WSDL2Java -v \ --server-side \ --deployScope Application \ --NStoPkg urn:myuri:1.0=faultdemo \ --output . \ MyService.wsdl javac -source 1.4 faultdemo/*.java CallMyService.java
Now we have an Axis client for that service. Run it against the gSOAP server.
$ java CallMyService MyFirstException ex.faultstring=Deliberately thrown exception. ex.text=Input values are wrong. MySecondException ex.faultstring=Deliberately thrown exception. ex.number=1111
You can see that the faults thrown from C were correctly converted to Java Exceptions.
Deploying a server in Axis
The WSDL2Java command used in the last section produced even
server-side stubs and a deployment descriptor for them.
You just need to edit faultdemo/MyServiceImpl.java
and provide implementation for the server side of the service:
faultdemo/MyServiceImpl.java
/** * MyServiceImpl.java * * This file was auto-generated from WSDL * by the Apache Axis 1.2RC3 Feb 28, 2005 (10:15:14 EST) WSDL2Java emitter. */ package faultdemo; public class MyServiceImpl implements faultdemo.MyType{ public java.lang.String myOperation(java.lang.String myInput) throws java.rmi.RemoteException, faultdemo.MyFirstException, faultdemo.MySecondException { if("first".equals(myInput)) { MyFirstException ex = new MyFirstException(); ex.setFaultString("Deliberately thrown"); ex.setText("Problem"); throw ex; } else { MySecondException ex = new MySecondException(); ex.setFaultString("Deliberately thrown"); ex.setNumber(2222); throw ex; } } }
Now you have to compile it and deploy it into Axis webservice inside TomCat.
javac -source 1.4 faultdemo/MyServiceImpl.java cp -r faultdemo/ $CATALINA_BASE/webapps/axis/WEB-INF/classes/
Now you have to restart TomCat, or at least the Axis webapp, because it needs to be able to find the new classes. Then do:
java org.apache.axis.client.AdminClient faultdemo/deploy.wsdd
The service is now deployed, but I found that the WSDL generated by Axis on-the-fly is not correct to namespaces, so you need to provide the original WSDL file to Axis. Copy it to classes dir and edit the deployment configuration:
cp MyService.wsdl $CATALINA_BASE/webapps/axis/WEB-INF/classes/ vi $CATALINA_BASE/webapps/axis/WEB-INF/server-config.wsdd
You need to add a line to the service config:
<service name="MyService" provider="java:RPC" style="wrapped" use="literal">
<wsdlFile>/MyService.wsdl</wsdlFile>
<operation name="myOperation" ...
Now restart the TomCat again and
check that the service is deployed by seeing http://localhost:8080/axis/servlet/AxisServlet
.
Change both clients so that they connect to the Axis server and run them:
$ java CallMyService MyFirstException ex.faultstring=Deliberately thrown ex.text=Problem MySecondException ex.faultstring=Deliberately thrown ex.number=2222 $ ./client calling first ... SOAP FAULT: SOAP-ENV:Server.generalException "Deliberately thrown" Detail: faultdemo.MyFirstException MyFirstException.text=Problem calling second ... SOAP FAULT: SOAP-ENV:Server.generalException "Deliberately thrown" Detail: faultdemo.MySecondException MySecondException.number=2222
It works ! Amazing :-)
Send any comments to Martin Kuba
.
Last updated: $Date: 2005/05/06 10:11:21 $
发表评论
-
说明SOA监管(SOA Governance)实例(收录备查)
2012-12-19 11:35 1756SOA 已经不是单纯技术问 ... -
Injecting Spring Beans into Java Servlets
2012-11-01 10:21 1942If you are working in a Java ... -
用 HttpServletResponseWrapper 实现 Etag 过滤器
2012-07-09 16:58 3764原文出处:http://blog.chenlb.com/200 ... -
Eclipse Indigo - Cannot install Android ADT Plugin
2012-02-29 01:17 3888When I try to install the And ... -
Eclipse Indigo - Cannot install Android ADT Plugin
2012-02-29 01:13 1994When I try to install the And ... -
[转]mybatis下的分页,支持所有的数据库
2011-07-21 13:21 14844大 家都知道,mybatis的自带分页方法只是逻 ... -
Java framework for text- & console-based forms?
2011-07-21 01:06 1714charva jcurses JNA , ... -
JNA(Java Native Access)学习入门
2011-07-21 01:04 22656Java Native Access 项目 在 ... -
使用IntrospectorCleanupListener 解决quartz引起的内存泄漏
2011-04-20 11:59 13378"在服务器运行过程中,Spring不停的运行的计划任 ... -
DBCP代码研读以及就数据库连接失效的解决
2011-03-31 11:03 3772问题 网上很多评论说DBCP有很多BUG,但是都没有指明是什 ... -
ContextLoaderListener
2010-12-06 15:58 8473(1) org.springframework.web.c ... -
Servlet3.0新功能: 异步处理
2010-12-06 15:22 3188J2EE 6和Glassfish 3V正式发 ... -
Servlet3.0引入的新特性
2010-12-06 15:20 3063Servlet3.0规范的新特性主要是为了3个目的: ... -
100個節點上運行群集亞馬遜EC2上Hazelcast
2010-12-03 23:59 3322本文的目的,適是给妳湮示的細節集群的100個節點。此湮示記錄, ... -
Spring Properties Reloaded
2010-12-02 14:54 4378Spring Properties Reloaded Som ... -
为spring2.5中的jpetstore增加perf4j监控
2010-09-02 13:51 2654perf4j是一款类似于log4j的性能检测工具. 它 ... -
语义网的学习资源大汇集(备忘)
2010-06-23 22:48 1761网上资源 http:/ ... -
使用 JOLAP 实现复杂分析查询
2010-06-06 13:42 1972Shashank Tiwari 在本文中对 ... -
HTML5 Canvas for Internet Explorer
2010-06-04 21:16 1859Canvascape http://www.benjoff ... -
大型网站架构演变和知识体系
2010-06-01 23:47 1982架构演变第一步:物 ...
相关推荐
Interoperable Python ZSI WSDL SOAP Web Services tutorial
Learn how to make Web-based solutions secure and interoperable Extend integration patterns for event-driven computing with the Atom Syndication Format and implement multi-party interactions in AtomPub...
Today, for almost all the sectors in the world, cloud computing is synonym to on-demand provisioning and delivery of IT services in a pay-as-you-go model. The success story of cloud computing as a ...
- **Web Services**: Creating interoperable web services that can be accessed and used by a wide range of clients. - **Cloud Computing**: Designing scalable and flexible cloud-based applications and ...
the conformance tests in this document provide the assurance that the set of PIV middleware and PIV card applications that have passed these tests are interoperable. This in turn facilitates ...
the conformance tests in this document provide the assurance that the set of PIV Middleware and PIV Card Applications that have passed these tests are interoperable. This in turn facilitates ...
虽然文档的详细内容没有完全提供,但可以推断,PIFF标准的文档会包含以下部分:作用范围和正当性(Scope and Justification),参考文献(References),其中可能包括标准参考(Normative References)和信息性参考...
Axis是一个开源的Web服务开发工具,它允许开发者创建、部署和管理基于SOAP(Simple Object Access Protocol)的Web服务。在本例中,Axis被用来作为客户端绑定 stub(SendSmsBindingStub),这是一个自动生成的Java类...
The only enterprise Linux recommended by Microsoft and SAP, SUSE Linux Enterprise Server is optimized to deliver high-performance mission-critical services, as well as edge of network, and web ...
The only enterprise Linux recommended by Microsoft and SAP, SUSE Linux Enterprise Server is optimized to deliver high-performance mission-critical services, as well as edge of network, and web ...
Through real-world examples and practical exercises, you’ll explore topics such as scientific datasets, hierarchically organized groups, user-defined metadata, and interoperable files. Examples are ...
the United States and Vodafone in Europe. Here,the throughput of LTE physical layer in downlink transmissions is carried out. The various steps like CRC,turbo coding, code block segmentation,...
### 基本可互操作加密系统(BISS-E)技术规范详解 #### 一、概述与背景 《基本可互操作加密系统(BISS-E)》是一份由欧洲广播联盟(European Broadcasting Union, EBU)发布的技术规范文档,旨在为数字贡献线路...
Overview: ...bodies to develop interoperable security standards and guidelines. In addition, CTG worked with industry partners to promote the use of NIST-approved cryptographic methods.
Find out how the new PHP has become a more mature language with community standards, a growing affinity for interoperable components, and a passionate community committed to improving performance.
S/MIME is based upon the widely used MIME standard [MIME] and describes a protocol for adding cryptographic security services through MIME encapsulation of digitally signed and encrypted objects....
Eclipse MicroProfile has gained momentum in the industry as a multi-vendor, interoperable, community-driven specification. It is a major disruptor that allows organizations with large investments in ...
Learn the capabilities and differences between popular protocols and communication patterns and how they can be used, and should not be used, to create secure and interoperable services and things ...