JAVA calls webservice. When you first get in touch, you will think it is a nightmare, especially without a unified standard implementation. Compared to the webservice implementation that can be completed in a few steps of .net, it is really sad to see the implementation of JAVA. But even if we are sad, we still have to complete it. JAVA has also many good implementations, such as xfire, jersey, CXF. Here we will take a look at the implementation of xfire together.
1) First of all, of course I have to get off the bag, and this ordinary person knows it. http://xfire.codehaus.org/Download you can go here, you can go all or distribution. But it’s better to give it a whole lot of strange problems to lose confidence.
What should I do if I get the bag off? Put it in the project. It seems nonsense, but many people just don’t know what to do.
To build a new project, I compare it to xfireWebservice, which is of course a web project here.
I have put all its packages here. After all, when we write examples, there is no need to be picky. Click it casually. If you want to see the exception information, you can add them slowly. It is easy to eliminate errors in the future, but we won’t do that here. After all, there is nothing ugly about the lack of any kind of exceptions, and you can eliminate them yourself.
2) Let’s first understand the difference between xfire and other webservice frameworks. The biggest difference is that it requires an interface, and if you need to use xfire to call the corresponding webservice, you must know the definition of the interface. I feel that there is a bit of a limitation here. But apart from this, it is quite convenient to call webservice, just like calling local methods. Let's take a look at the example directly:
First of all, the most important interface:
public interface IReaderService { public Reader getReader(String name,String password); public List<Reader> getReaders(); } There is an interface, of course there must be an implementation class, otherwise the interface will have no meaning. public class ReaderService implements IReaderService{ public Reader getReader(String name,String password) { return new Reader(name,password); } public List<Reader> getReaders(){ List<Reader> readerList = new ArrayList<Reader>(); readerList.add(new Reader("shun1","123")); readerList.add(new Reader("shun2","123")); return readerList; } } Also take a look at JAVABEAN and Reader classes:
public class Reader{ private static final long serialVersionUID = 1L; private String name; private String password; public Reader(){} public Reader(String name,String password) { this.name = name; this.password = password; } //Get/Set method omits public String toString(){ return "Name:"+name+",Password:"+password; } }Note that our Reader class here implements the Serializable interface, why? Here, first of all, we need to understand the principle of webservice. For JAVA, if we need to upload objects on the Internet, many people will of course think of serialization. By the way, this is serialization, because we need to pass the reader as a parameter. This needs to be implemented forcibly in the previous version, otherwise an error will be reported. However, the latest version (in fact, the latest one is also from 2007, because xfire has stopped developing and has been merged into a CXF project by apache. We will talk about this later) is no longer needed. As for how to implement it, we will not investigate it in depth here for the time being, because it has been merged into CXF. If we want to learn in depth, it should be better to learn CXF.
3) After we complete the above interface and JAVABEAN writing, many people will ask, I see that many webservices will have WSDL files, so how did you get it? Before talking about this, let’s discuss what WSDL is. Perhaps many companies provide interfaces that are just HTTP addresses, returning XML formats, and so are ours. This has one advantage and one disadvantage. The advantage is that our development is less difficult, while the disadvantage is that we need to provide users with a bunch of explanation files. What does each returned XML tag mean? This is nothing, but it is just annoying. As for webservice, the disadvantage is that we have developed a little more things, and the advantage is that we don’t have to write so many explanation files, because there is a unified explanation called WSDL. This is the explanation document of webservice, which is unified and the same no matter what language, so there is no problem that no one can understand.
And here, when we deploy xfire, it can help us generate WSDL files.
The problem is how to deploy it, this is actually simple. We create a new folder META-INF in the src directory, and then create a folder xfire in it, and create the file services.xml. The subsequent structure is as follows:
Some people may ask why we need to build it into the src directory. In fact, it is not a prescribed build here, but because we need to ask the development tools to help us deploy these files ourselves, so if we put it here, eclipse can help us deploy it to tomcat or other containers ourselves. Note that the folder level where this file is located is fixed and cannot be modified.
Let's take a look at services.xml directly:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://xfire.codehaus.org/config/1.0"> <service> <!-- The name of the webserviceq, you need to specify this when calling --> <name>readerService</name> <!-- This is usually the website address of your own company, and it doesn't make much sense --> <namespace>http://test/HelloService</namespace> <!-- Interface class--> <serviceClass>com.xfire.servlet.IReaderService</serviceClass> <!-- Implementation class--> <implementationClass>com.xfire.servlet.ReaderService</implementationClass> </service> </beans>
It's generally OK to look at the comments.
4) Many people think that this is enough. No, it hasn't worked yet. If you specify this, how can others visit it? How to forward the corresponding request to xfire and let it process it. We need to modify the web.xml again.
After modification, the following is:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <servlet> <servlet-name>XFireServlet</servlet-name> <servlet-class>org.codehaus.xfire.transport.http.XFireConfigurableServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>XFireServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> </web-app>
In fact, it is just adding a servlet and the corresponding mapping. Next, we directly enter it in the browser:
http://localhost:8080/xfireWebService/services/readerService?wsdl
We can see:
What is displayed here is wsdl, which will display the method we define and the type returned. There is an explanation of WSDL later.
5) After completing the above four steps, we have completed the deployment of the webservice. Others can call the corresponding webservice to access our methods. Let’s use the client provided by xfire to access the website service we just published:
public class ReaderClient { public static void main(String[] args) { // Here is to create a service, and an interface class needs to be passed in, because we must call the corresponding interface method Service srcModel = new ObjectServiceFactory().create(IReaderService.class); // Agent factory, here is to create the corresponding interface class later XFireProxyFactory factory = new XFireProxyFactory(XFireFactory.newInstance().getXFire()); //Webservice address, no wsdl need to be added String readerServiceUrl = "http://localhost:8080/xfireWebService/services/readerService"; try { //Use the factory to return the corresponding interface class IReaderService readerService = (IReaderService)factory.create(srcModel,readerServiceUrl); Reader reader = readerService.getReader("shun","123"); System.out.println(reader); } catch (MalformedURLException e) { e.printStackTrace(); } } } In this way, we see that the output is:
Analysis of wsdl file structure
WSDL (Web Services Description Language, Web Service Description Language) is an XML Application that defines a Web service description as a set of service access points through which clients can access services containing document information or procedure calls (similar to remote procedure calls). WSDL first abstracts the access operation and the request/response message used during access, and then binds it to a specific transport protocol and message format to ultimately define the specific deployed service access point. The service access points for related specific deployments become abstract web services through combination. This article will explain the structure of the WSDL document in detail and analyze the role of each element.
1: WSDL definition
WSDL is a document used to accurately describe web services, and a WSDL document is an XML document that follows the WSDL XML pattern. The WSDL document defines a web service as a collection of service access points or ports. In WSDL, since the abstract definition of service access points and messages has been separated from the specific service deployment or data format binding, the abstract definition can be used again: the message refers to an abstract description of the exchanged data; and the port type refers to an abstract collection of operations. Specific protocols and data format specifications for specific port types constitute a binding that can be reused. Associating a web access address with a reusable binding, a port can be defined, and a collection of ports is defined as a service.
A WSDL document usually contains 7 important elements, namely types, import, message, portType, operation, binding, and service elements. These elements are nested in the definitions element, which is the root element of the WSDL document. The next part of the article will introduce the basic structure of WSDL in detail.
2: Basic structure of WSDL--Overview
As described at the end of the first part, a basic WSDL document contains 7 important elements. The following will introduce these elements and their functions.
The WSDL document uses the following elements in the definition of a Web service:
・ Types - A container defined by a data type, which uses a certain type system (usually the type system in XML Schema).
・Message - Abstract type definition of data structures for communication messages. Use the types defined by Types to define the data structure of the entire message.
・ Operation - An abstract description of the operations supported in the service. Generally, a single Operation describes a request/response message pair that accesses the entry.
・ PortType - An abstract collection of operations supported by a certain access entry point type, which can be supported by one or more service access points.
・Binding - Binding of specific protocols and data format specifications for specific port types.
・ Port - Defined as a single service access point that combines protocol/data format binding with specific web access addresses.
・ Service- A collection of related service access points.
The xml schema of WSDL can be referred to as the following URL: http://schemas.xmlsoap.org/wsdl/
Three: Basic structure of WSDL--detailed description
This section will describe in detail the role of each element of the WSDL document through an example. The following example is the content of a simple WSDL document. For the generation of this document, please refer to my other article: xfire development example--HelloWorld.
A simple Web Service WSDL document that supports a unique operation called sayHello, which is implemented by running the SOAP protocol on http. The request accepts a string name and returns a simple string after processing. The documentation is as follows:
<?xml version="1.0" encoding="UTF-8" ?> <wsdl:definitions targetNamespace="http://com.liuxiang.xfireDemo/HelloService" xmlns:tns="http://com.liuxiang.xfireDemo/HelloService" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc11="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenc12="http://www.w3.org/2003/05/soap-encoding" xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> <wsdl:types> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://com.liuxiang.xfireDemo/HelloService"> <xsd:element name="sayHello"> <xsd:complexType> <xsd:sequence> <xsd:element maxOccurs="1" minOccurs="1" name="name" nillable="true" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="sayHelloResponse"> <xsd:complexType> <xsd:sequence> <xsd:element maxOccurs="1" minOccurs="1" name="out" nillable="true" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> </wsdl:types> <wsdl:message name="sayHelloResponse"> <wsdl:part name="parameters" element="tns:sayHelloResponse" /> </wsdl:message> <wsdl:message name="sayHelloRequest"> <wsdl:part name="parameters" element="tns:sayHello" /> </wsdl:message> <wsdl:portType name="HelloServicePortType"> <wsdl:operation name="sayHello"> <wsdl:input name="sayHelloRequest" message="tns:sayHelloRequest" /> <wsdl:output name="sayHelloResponse" message="tns:sayHelloResponse" /> </wsdl:operation> </wsdl:portType> <wsdl:binding name="HelloServiceHttpBinding" type="tns:HelloServicePortType"> <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <wsdlsoap:operation name="sayHello"> <wsdlsoap:operation soapAction="" /> <wsdlsoap:operation soapAction="" /> <wsdlsoap:body use="literal" /> </wsdl:input> <wsdlsoap:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="HelloService"> <wsdl:port name="HelloServiceHttpPort" binding="tns:HelloServiceHttpBinding"> <wsdlsoap:address location="http://localhost:8080/xfire/services/HelloService" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
The types element uses the XML schema language to declare complex data types and elements used elsewhere in the WSDL document;
The import element is similar to the import element in an XML schema document and is used to import WSDL definitions from other WSDL documents;
The message element describes the payload of a message using the built-in type, complex type, or element of the XML schema defined in the type element of the WSDL document or defined in the external WSDL document referenced by the import element;
The portType element and operation element describe the interface of the web service and define its methods. The portType element and operation element are similar to the method declaration defined in the java interface. The operation element uses one or more message types to define the payload of its input and output;
The Binding element assigns the portType element and the operation element to a special protocol and encoding style;
The service element is responsible for assigning the Internet address to a specific binding;
1. Definitions elements
The root element of all WSDL documents is a definitions element. This element encapsulates the entire document while providing a WSDL document through its name. This element has no other function except providing a namespace, so it will not be described in detail.
The following code is the structure of a definitions element:
<wsdl:definitions targetNamespace="http://com.liuxiang.xfireDemo/HelloService" xmlns:tns="http://com.liuxiang.xfireDemo/HelloService" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc11="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenc12="http://www.w3.org/2003/05/soap-encoding" xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> </wsdl:definitions>
2. Types elements
WSDL adopts the W3C XML schema built-in types as its basic type system. The types element is used as a container to define various data types not described in the XML schema built-in types. When declaring the payload of the message part, the message definition uses the data types and elements defined in the type element. Types definitions in this WSDL document:
<wsd:types> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://com.liuxiang.xfireDemo/HelloService"> <xsd:element name="sayHello"> <xsd:complexType> <xsd:sequence> <xsd:element maxOccurs="1" minOccurs="1" name="name" nillable="true" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="sayHelloResponse"> <xsd:complexType> <xsd:sequence> <xsd:element maxOccurs="1" minOccurs="1" name="out" nillable="true" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> </wsdl:types>
The above is the data definition part, which defines two elements, one is sayHello and the other is sayHelloResponse:
saysHello: defines a complex type that only contains a simple string, which is used to describe the incoming part of the operation in the future;
saysHelloResponse: defines a complex type that only contains a simple string, and the return value used to describe the operation in the future;
3. Import elements
The import element enables the use of the definition elements in the namespace specified in other WSDL documents in the current WSDL document. The import element is not used in this example. This function is usually very effective when users want to modularize WSDL documents.
The format of import is as follows:
<wsdl:import namespace="http://xxx.xxx.xxx/xxx/xxx" location="http://xxx.xxx.xxx/xxx/xxx.wsdl"/>
There must be a namespace attribute and a location attribute:
namespace attribute: The value must match the targetNamespace declared in the WSDL document being imported;
location attribute: Must point to an actual WSDL document, and the document cannot be empty.
4. Message elements
The message element describes the payload of a web service using messages. The message element can describe the payload of the output or accepting message; it can also describe the contents of the SOAP file header and the error detail element. The way the message element is defined depends on the use of RPC style or document style messaging. In the definition of the message element in this article, this document uses document-style messaging:
<wsdl:message name="sayHelloResponse"> <wsdl:part name="parameters" element="tns:sayHelloResponse" /> </wsdl:message> <wsdl:message name="sayHelloRequest"> <wsdl:part name="parameters" element="tns:sayHello" /> </wsdl:message>
This part is an abstract definition of the message format: two messages sayHelloResponse and sayHelloRequest are defined:
saysHelloRequest: The request message format of the sayHello operation, consisting of a message fragment, named parameters, and the element is the element in the type we defined earlier;
saysHelloResponse: The response message format of the sayHello operation is composed of a message fragment, named parameters, and the element is the element in the types we defined earlier;
If you use RPC-style messaging, you only need to modify the element element in the document to type.
5. PortType element
The portType element defines the abstract interface of the web service. This interface is a bit similar to Java interfaces, both of which define an abstract type and method, and no implementation is defined. In WSDL, the portType element is implemented by binding and service elements, which are used to illustrate the Internet protocol, encoding scheme and Internet address used by the Web service implementation.
Multiple operations can be defined in a portType, and one operation can be regarded as a method. The definition of the WSDL document in this article:
<wsdl:portType name="HelloServicePortType"> <wsdl:operation name="sayHello"> <wsdl:input name="sayHelloRequest" message="tns:sayHelloRequest" /> <wsdl:output name="sayHelloResponse" message="tns:sayHelloResponse" /> </wsdl:operation> </wsdl:portType>
portType defines the type of the service's call mode. It contains an operation saysHello method, which contains both input and output to indicate that the operation is a request/response mode. The request message is the sayHelloRequest defined earlier, and the response message is the sayHelloResponse defined earlier. input represents the payload delivered to the web service, and output message represents the payload delivered to the client.
6. binding
The binding element maps an abstract portType to a set of specific protocols (SOAO and HTTP), messaging styles, and encoding styles. Usually binding elements are used together with the proprietary elements of the protocol. Examples in this article:
<wsdl:binding name="HelloServiceHttpBinding" type="tns:HelloServicePortType"> <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="sayHello"> <wsdlsoap:operation soapAction="" /> <wsdl:input name="sayHelloRequest"> <wsdlsoap:body use="literal" /> </wsdl:input> <wsdl:output name="sayHelloResponse"> <wsdlsoap:body use="literal" /> </wsdl:output>