Mainly refer to the http://cxf.apache.org related content:
1. The basic method for creating a service using cxf (UseCxfBuilt-in JettyContainer)
Reference: http://cxf.apache.org/docs/a-simple-jax-ws-service.html
In four steps:
① Set the Build Environment
② Write Service
③ Publish a service
④ Access Service
1) set the Build Environment
Create a new project and add the following files in the lib directory of apache-cxf-2.2.4.zip to build path:
Commons-logging-1.1.1.jar
Geronimo-activation_1.1_spec-1.0.2.jar (or Sun's activation jar)
Geronimo-annotation_1.0_spec-1.1.1.jar (jsr250)
Geronimo-javamail_1.4_spec-1.6.jar (or Sun's javamail jar)
Geronimo-servlet_2.5_spec-1.2.jar (or Sun's servlet jar)
Geronimo-ws-metadata_2.0_spec-1.1.2.jar (jsr181)
Geronimo-jaxws_2.1_spec-1.0.jar (or Sun's jaxws-api-2.1.jar)
Geronimo-stax-api_1.0_spec-1.0.1.jar (or other Stax-API jar)
Jaxb-api-2.1.jar
Jaxb-impl-2.1.12.jar
Jetty-6.1.21.jar
Jetty-util-6.1.21.jar
Neethi-2.0.4.jar
Saaj-api-1.3.jar
Saaj-impl-1.3.2.jar
Wsdl4j-1.6.2.jar
Wstx-asl-3.2.8.jar
XmlSchema-1.4.5.jar
Xml-resolver-1.2.jar
Cxf-2.2.4.jar
Optional. Add spring jars to add spring support for xml configuration. The added jars are as follows:
Aopalliance-1.0.jar
Spring-core-2.5.5.jar
Spring-beans-2.5.5.jar
Spring-context-2.5.5.jar
Spring-web-2.5.5.jar
2) Write Service
A) Write Interface
@ WebService
Public interface helloworld {
String sayhi (string text );
// JAX-WS/jaxb cannot directly support advanced use cases to handle the special xmladapter they need to write
String sayhitouser (User user );
/* Map Transmission
* Jaxb does not support maps. It can handle lists well, but maps cannot support them directly.
* They also need to use an xmladapter to map maps to beans that can be used by jaxb.
*/
@ Xmljavatypeadapter (integerusermapadapter. Class)
Map <integer, user> getusers ();
}
Note:: WSDL will rename the parameter name. If you do not want this, you should write it as follows:
@ WebService
Public interface helloworld {
String sayhi (@ Webparam(Name = "text") string text );
}
B) Write implementation:
Package demo. HW. server;
Import java. util. linkedhashmap;
Import java. util. Map;
Import javax. JWS. WebService;
@ WebService (endpointinterface = "demo. HW. server. helloworld ",
Servicename = "helloworld") // tells cxf which interface is used to create the WSDL
Public class helloworldimpl implements helloworld {
Map <integer, user> Users = new linkedhashmap <integer, user> ();
Public String sayhi (string text ){
System. Out. println ("sayhi called ");
Return "hello" + text;
}
Public String sayhitouser (User user ){
System. Out. println ("sayhitouser called ");
Users. Put (users. Size () + 1, user );
Return "hello" + User. getname ();
}
Public Map <integer, user> getusers (){
System. Out. println ("getusers called ");
Return users;
}
}
3) Release Service (cxf comes with jetty server, so it can be released without Tomcat)
A) use the JWS high-level encapsulation:
System. Out. println ("Starting server ");
Helloworldimpl implementor = new helloworldimpl ();
String address = "http: // localhost: 9000/helloworld ";
Endpoint. Publish (address, implementor );
B) use the following code to precisely control service behavior:
Helloworldimpl implementor = new helloworldimpl ();
Jaxwsserverfactorybean svrfactory = new jaxwsserverfactorybean ();
Svrfactory. setserviceclass (helloworld. Class); // save, but it is not recommended because it may cause minor problems.
Svrfactory. setaddress ("http: // localhost: 9000/helloworld ");
Svrfactory. setservicebean (implementor );
Svrfactory. getininterceptors (). Add (New loggingininterceptor ());
Svrfactory. getoutinterceptors (). Add (New loggingoutinterceptor ());
Svrfactory. Create ();
Since then, you can use http: // localhost: 9000/helloworld? To display the WSDL of the service.
Loggingininterceptor and loggingoutinterceptor are log interceptors used to display logs during input and output.
4) Access Services
A) use the JWS high-level encapsulation:
// The first parameter is the unfix of class package name implemented by the interface
Private Static final QNAME SERVICE_NAME = new QNAME ("http://server.hw.demo/", "helloworld ");
Private Static final QNAME port_name = new QNAME ("http://server.hw.demo/", "helloworldport ");
......
Service = service. Create (SERVICE_NAME );
// Endpoint address
String endpointaddress = "http: // localhost: 9000/helloworld ";
// Add a port to the service
Service. addport (port_name, soapbinding. soap11http_binding, endpointaddress );
Helloworld hW = service. getport (helloworld. Class );
System. Out. println (HW. sayhi ("world "));
B) or use the following code to control the service more accurately:
Jaxwsproxyfactorybean factory = new jaxwsproxyfactorybean ();
Factory. getininterceptors (). Add (New loggingininterceptor ());
Factory. getoutinterceptors (). Add (New loggingoutinterceptor ());
Factory. setserviceclass (helloworld. Class );
Factory. setaddress ("http: // localhost: 9000/helloworld ");
Helloworld client = (helloworld) Factory. Create ();
String reply = client. sayhi ("hi ");
System. Out. println ("server said:" + reply );
System. Exit (0 );
2. wsdl2java: generate a Java class from the WSDL document for the client to use
Set the environment variable cxf_home = D: \ Program Files \ apache-cxf-2.2.4, add "; % cxf_home % \ bin" after path (optional), and then run the wsdl2java batch processing program, which is used as follows:
Wsdl2java-P package name-d directory name WSDL path
For example, wsdl2java-P demo. Service. Client-d e: \ SRC htt: // localhost: 8080/helloworld? WSDL
-P specifies the namespace of the WSDL, that is, the package name of the Code to be generated.
-D specifies the directory where the code to be generated is located
-The client generates the code for the client to test the web service.
-The server generates the code for the server to start the web service.
-Impl: generate the Web service implementation code
-Ant generate the build. xml file
-All: generate all the starting endpoint code: types, Service proxy, service interface, server mainline, client mainline, implementation object, and an ant build. xml file.
See http://cwiki.apache.org/CXF20DOC/wsdl-to-java.html for detailed usage
3. Define complex types (basic types such as int, String, no need to define additional), references: http://cxf.apache.org/docs/defining-contract-first-webservices-with-wsdl-generation-from-java.html
For example:
Package com. example. customerservice;
@ Xmlaccessortype (xmlaccesstype. Field)
Public Class Customer {// custom class
String name;
String \ [\] address;
Int numorders;
Double revenue;
Bigdecimal test;
Date birthdate;
CustomertypeType; // custom Enumeration type
}
Public EnumCustomertype{
Private, business
}
// Define exception
@ Webfault (name = "nosuchcustomer ")
@ Xmlaccessortype (xmlaccesstype. Field)
Public class nosuchcustomerexception extends runtimeexception {
/**
* We only define the fault details here. Additionally each fault has a message
* That shoshould not be defined separately
*/
String customername;
} // The default action for defining exceptions is to create exception_exception when the Java code is generated later. Therefore, you must use the @ webfault mark to get a name for the bean, which is different from the Exception name.
@ WebService // mark this interface as a service
Public interface customerservice {
Public customer [] getcustomersbyname (@ webparam (name = "name") string name) throws nosuchcustomerexception; // @ webparam marks the parameter name in the WSDL. If omitted, WSDL will be replaced by arg0
}
// @ WebService can also be used to customize the Interface Name and service name, which correspond to endpointinterface and servicename, for example:
@ WebService (endpointinterface = "com. example. customerservice", servicename = "helloworld ")
Generated WSDL:
<Xs: complextype name = "customer"> // complex type
<Xs: sequence>
<Xs: Element minoccurs = "0" name = "name" type = "XS: string"/>
<Xs: Element maxoccurs = "unbounded" minoccurs = "0" name = "Address" nillable = "true" type = "XS: string"/>
<Xs: element name = "numorders" type = "XS: int"/>
<Xs: element name = "revenue" type = "XS: Double"/>
<Xs: Element minoccurs = "0" name = "test" type = "XS: decimal"/>
<Xs: Element minoccurs = "0" name = "birthdate" type = "XS: datetime"/>
<Xs: Element minoccurs = "0" name = "type" type = "TNS: mermertype"/>
</Xs: sequence>
</Xs: complextype>
Minoccurs = "0" is optional, so that new elements can be added at any time to maintain compatibility. If you do not want this option, you can mark @ xmlelement (required = true)
Maxoccurs = "unbounded" is used to facilitate the subsequent XML to repeat this element to form an array.
<Xs: simpletype name = "customertype"> // Enumeration type
<Xs: Restriction base = "XS: string">
<Xs: enumeration value = "private"/>
<Xs: enumeration value = "business"/>
</Xs: Restriction>
</Xs: simpletype>
<Xs: element name = "nosuchcustomer" type = "TNS: nosuchcustomer"/> // exception class
<Xs: complextype name = "nosuchcustomer">
<Xs: sequence>
<Xs: element name = "customername" nillable = "true" type = "XS: string"/>
</Xs: sequence>
</Xs: complextype>
<WSDL: Message name = "nosuchcustomerexception">
<WSDL: part name = "nosuchcustomerexception" element = "TNS: nosuchcustomer">
</WSDL: Part>
</WSDL: Message>
//Note:: The names of element and message are different. This is achieved by marking @ webfault. They can also have the same name, but in that case, the generated Exception name will be ugly: nosuchcustomerexception_exception