Author: Jiangnan Baiyi
This article is from springside wiki. Pay attention to the latest version on Wiki. (Wiki was updated in 11.27 ).
Please read: xfire fire Guide (I) first)
1. jsr181
Jsr181 adopts the annotated pojo and Zero Configuration File Export web service, which is advocated by BEA. xfire is well supported by the formal method in javaee5.
However, xfire's documentation on the jsr181 method is not clear enough. Please read this section to avoid several traps.
1.1 References
- Spring, Hibernate and xfire
- WebServices with spring, xfire and jsr181
- Basic spring web services with xfire and JSR 181
- Xfire jsr181 references
1.2 applicationcontext. xml
Because the configuration is written in annotation, the content of the applicationcontext. xml file is relatively fixed. Note that jsr181webannotations and handlermapping cannot be lazy init.
<Beans default-autowire = "byname" default-Lazy-init = "true">
<! -- Introduce the xfire pre-configuration file -->
<Import resource = "classpath: ORG/codehaus/xfire/spring/xfire. xml"/>
<! -- Obtain the jsr181 annotation of all beans in applicationcontext -->
<Bean id = "webannotations" class = "org. codehaus. xfire. Annotations. jsr181.jsr181webannotations" lazy-init = "false"/>
<! -- Define handler mapping and export all jsr181 beans as Web Services -->
<Bean id = "jsr181handlermapping" class = "org. codehaus. xfire. Spring. remoting. jsr181handlermapping" lazy-init = "false">
<Property name = "xfire" ref = "xfire"/>
<Property name = "webannotations" ref = "webannotations"/>
</Bean>
</Beans>
1.3 interface + impl Mode
Different from the traditional xfire mode, narrow interfaces are not necessary. They only take into account that when the client uses xfire, there is an interface to generate the client.
If the interface is used, the interface serves as the main configuration work.
Define @ WebService first to define your own namespace. If not defined, the default Generation Algorithm of namespace will be used.
All functions in the interface are exported by default. You do not need to use @ webmethod annotations. You can perform further configuration as follows:
@ WebService (targetnamespace = "http://www.springside.org.cn ")
Public interface bookservice {
@ Webresult (name = "searchresult ")
List <book> findbooksbycategory (@ webparam (name = "category", header = true) string cateoryid );
}
The manager is not a pure pojo and requires @ WebService annotation to specify the interface.
@ WebService (servicename = "bookservice ",
Endpointinterface = "org. springside. Bookstore. components. xfire. server. jsr181.bookservice ")
Public class bookmanager implements bookservice {...}
Trap 1: In the xfire jsr181 reference document, @ WebService (name = "bookservice") is used in the interface to define servicename, which seems reasonable, however, it is really odd to define @ WebService (servicename = "bookservice") in the Manager.
1.4 pure pojo Mode
For example in the document, you must configure @ webmethod to specify the service to be exported.
@ WebService (name = "echoservice", targetnamespace = "http://www.openuri.org/2004/04/HelloWorld ")
Public class jsr181echoservice
{
@ Webmethod (operationname = "echostring", Action = "urn: echostring ")
@ Webresult (name = "echoresult ")
Public String echo (@ webparam (name = "echoparam", header = true) string input)
{
Return input;
}
}
1.5 client considerations
Trap 2: The biggest difference with the traditional mode client is that the 3rd parameters need to be the actual manager class rather than the interface class:
Service servicemodel = new annotationservicefactory (). Create (bookmanager. Class); 2. Client
Xfire's client is not a strong model. There are three modes:
2.1 The client developer owns the class of the Web Server
The client and server are the same development team, or the server team provides the development kit in the form of jar. If you can obtain the server interface class, entity class, and Aegis configuration file.
Traditional mode:
Service servicemodel = new objectservicefactory (). Create (bookservice. Class );
Bookservice service = (bookservice) New xfireproxyfactory (). Create (servicemodel, serviceurl );
Service. findbooksbycategory (cateoryid );
In jsr181 mode, note that the server development team must provide the bookservice implementation class bookmanager to the client, not just the interface class, which is dangerous:
Service servicemodel = new annotationservicefactory (). Create (bookmanager. Class );
Bookservice = (bookservice) New xfireproxyfactory (). Create (servicemodel, serviceurl );
Service. findbooksbycategory (cateoryid );
Springside encapsulates an xfireclientfactory with generics. The call code is as follows:
Bookservice service = xfireclientfactory. getclient (serviceurl, bookservice. Class );
Bookservice service = xfireclientfactory. getjsr181client (serviceurl, bookservice. Class, bookmanager. Class); 2.2 dynamic mode
The dynamic mode does not require the server class, but the performance and complex object ing estimation is not very good.
Client client = new Client(new URL("http://www.webservicex.net/CurrencyConvertor.asmx?WSDL"));
Object[] results = client.invoke("ConversionRate", new Object[] {"BRL", "UGX"});
2.3 generate client stub Based on WSDL
This is the king of the web service client. You can access any web service you have written. It will be demonstrated in the next version.
3. Test
An important feature of xfiire is the ability to perform unit tests without starting a Web container.
The principle is to use the xfire JVM mode to access services through xfire. Local: // bookservice channel instead of http: // localhost/service/bookservice.
There are two testing methods:
One is server-only. Requests are sent in the form of soap xml without writing client code, and the returned soap xml string is used to directly test the XML.
One is to write the client code in 2.1 for testing.
The former test has a high degree of isolation, and the latter is relatively simple.
3.1 Test base class
XfireAbstractxfirespringtestBase class to implement the createcontext () callback function.
protected ApplicationContext createContext() {
return ClassPathXmlApplicationContext(new String[]{"classpath*:applicationContext*.xml"});
}
In addition, a very important task to test the base class is to solve the lazyload problem of Hibernate and implement opensession in test. Therefore, springside encapsulates a base class of xfiretestcase.
3.2 use client code for Direct Test
The following code calls the findbooksbycategory method directly using the client code to obtain the returned value and then judge various assert operations.
Note the difference between servericeurl and common client code: If servericeurl is changed to local, the factory must add getxfire () as the parameter.
Service servicemodel = new objectservicefactory (). Create (bookservice. Class );
Xfireproxyfactory factory = new xfireproxyfactory (getxfire ());
Bookservice service = (bookservice) Factory. Create (servicemodel, "xfire. Local: // bookservice ");
List list = service. findbooksbycategory ("0 ");
Assertnotnull (list );
...
3.3 server-only test
Write a piece of soap XML and save it in any name. The findbooksbyname method is called as a parameter in the following example using "Java.
<Env: envelope xmlns: ENV = "http://schemas.xmlsoap.org/soap/envelope/">
<Env: Header/>
<Env: Body>
<Findbooksbyname xmlns = "http://www.springside.org.cn">
<In1> JAVA </in1>
</Findbooksbyname>
</ENV: Body>
</ENV: envelope>
The test code calls the preceding XML, returns the XML document object, and checks the result using some assert methods provided by the base class:
Document Doc = invokeservice ("bookservice", "/org/springside/xfire/bookservice. findbooksbyname. xml ");
Assertnofault (DOC );
Addnamespace ("SS", "http://domain.commons.bookstore.springside.org ");
Assertvalid ("// SS: Book/SS: category/SS: descn =" Java book "", DOC );