Remote Procedure Call RPC RMI(Remote Method Invocation) and Web Service

Keywords: Java xml network Programming

1. What is RPC?

The full name of RPC is Remote Procedure call, which is the way of inter-process communication.

He allows a program to call a procedure or function in another address space without paying attention to the implementation details of the procedure or function. For example, two servers A, B, an application deployed on A server, want to call the function or method provided by the application on B server, because it is not in a memory space, can not be directly invoked, at this time need to be able to apply the implementation of RPC framework to solve.

Two. Implementation of RPC

RPC has many open source framework implementations. This article mainly introduces the RMI that comes with java.

1. What is RMI

RMI is called Remote Method Invocation-Remote Method Call. Java RMI is implemented in JDK 1.1. Its power is embodied in its powerful ability to develop distributed network applications. It is one of the core solutions of pure Java network distributed application system. In fact, it can be seen as the Java version of RPC. Require both client and server to be implemented in Java

2. Simple examples of RMI

(1) Server-side code implementation:

The IHello class implementation:

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface IHello extends Remote{
	/** 
     * Simply return to "Hello World! "Character" 
     * @return Return to "Hello World! "Character" 
     * @throws java.rmi.RemoteException 
     */ 
    public String helloWorld() throws RemoteException; 

    /** 
     * A simple business method that returns greetings based on incoming names 
     * @param someBodyName  Name 
     * @return Return the appropriate greetings 
     * @throws java.rmi.RemoteException 
     */ 
    public String sayHelloToSomeBody(String someBodyName) throws RemoteException; 
}

HelloImpl implements IHello implementations:

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class HelloImpl extends UnicastRemoteObject implements IHello{

	protected HelloImpl() throws RemoteException {
		super();
	}

	@Override
	public String helloWorld() throws RemoteException {
		return "Hello Word";
	}

	@Override
	public String sayHelloToSomeBody(String someBodyName) throws RemoteException {
		return "Hello," + someBodyName + "!";
	}

}

    HelloServer:

import java.net.MalformedURLException;
import java.nio.channels.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;

/** 
* Created by IntelliJ IDEA. 
* Date: 2008-8-7 22:03:35 
* Create RMI registry, start RMI service, and register remote objects into RMI registry. 
*/ 
public class HelloServer { 
    public static void main(String args[]) throws java.rmi.AlreadyBoundException { 

        try { 
            //Create a remote object 
            IHello rhello = new HelloImpl(); 
            //An instance of a remote object Registry on a local host and specifying port 8888 is an essential step (Java default port is 1099). Without Registry creation, objects cannot be bound to the remote Registry. 
            LocateRegistry.createRegistry(8888); 

            //Register the remote object on the RMI registry server and name it RHello 
            //The standard format of the binding URL is rmi://host:port/name (where the protocol name can be omitted and the following two are correct) 
            Naming.bind("rmi://localhost:8888/RHello",rhello); 
//            Naming.bind("//localhost:8888/RHello",rhello); 

            System.out.println(">>>>>INFO:Long-range IHello Object Binding Successful!"); 
        } catch (RemoteException e) { 
            System.out.println("Exceptions occurred when creating remote objects!"); 
            e.printStackTrace(); 
        } catch (AlreadyBoundException e) { 
            System.out.println("Duplicate binding object exception occurred!"); 
            e.printStackTrace(); 
        } catch (MalformedURLException e) { 
            System.out.println("Happen URL Abnormal deformity!"); 
            e.printStackTrace(); 
        } 
    } 
}

(2) Client code implementation:

GiveMeWords, a new client project, requires the client to copy the IHello interface of the server and must have the same package name as the server. Otherwise, the following mistakes will be reported (I personally tested):

        java.lang.ClassNotFoundException: test.rmi.IHello (no security manager: RMI class loader)

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

public class HelloClient {
	  public static void main(String args[]){ 
	        try { 
	            //Find an object named RHello in the RMI service registry and invoke its methods 
	            IHello rhello =(IHello) Naming.lookup("rmi://localhost:8888/RHello"); 
	            System.out.println(rhello.helloWorld()); 
	            System.out.println(rhello.sayHelloToSomeBody("Lava")); 
	        } catch (NotBoundException e) { 
	            e.printStackTrace(); 
	        } catch (MalformedURLException e) { 
	            e.printStackTrace(); 
	        } catch (RemoteException e) { 
	            e.printStackTrace();   
	        } 
	    } 
}

Service-side engineering structure screenshot

Client engineering structure screenshot

Run the server-side code first and the client-side code. Operation results:

Three, Web Service

1. Web Service is a cross-programming language and cross-programming language operating system Remote calling technology of platform.

XML+XSD,SOAP and WSDL are the three technologies that constitute the Web Service platform. Web Service is transmitted by http protocol, and the data format is XML in a specific format.

SOAP Protocol = HTTP Protocol + XML Protocol

WSDL (Web Service Description Language) is based on XML voice and is used to describe Web Service and its functions, parameters and return values. It is a standard format that Web Service clients and servers can understand. The WSDL file is stored on the Web server and can be accessed through a url address. Before a client invokes a Web Service service, it needs to know the address of the WSDL file for that service. Web Service service providers can expose their WSDL file addresses in two ways: 1. Register to UDDI servers for searching; 2. Tell client callers directly. That is to say, we need to develop Web Service, through the WSDL file on the server side, we can write client invocation code.

Server-side code:

import javax.jws.WebService;
import javax.xml.ws.Endpoint;

@WebService
public class Function {
	public String transWords(String words){
		String res = "";
		for(char ch : words.toCharArray()){
			res += "\t" + ch + "\t";
		}
		return res;
	}
	
	public static void main(String[] args){
		Endpoint.publish("http://localhost:9001/Service/Function", new Function());
		System.out.println("publish success");
	}
}

Access after successful operation http://localhost:9001/Service/Function?wsdl . The wsdl document is as follows:

<!--
 Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.4-b01. 
-->
<!--
 Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.4-b01. 
-->
<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://webService.test/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://webService.test/" name="FunctionService">
<types>
<xsd:schema>
<xsd:import namespace="http://webService.test/" schemaLocation="http://localhost:9001/Service/Function?xsd=1"/>
</xsd:schema>
</types>
<message name="transWords">
<part name="parameters" element="tns:transWords"/>
</message>
<message name="transWordsResponse">
<part name="parameters" element="tns:transWordsResponse"/>
</message>
<portType name="Function">
<operation name="transWords">
<input wsam:Action="http://webService.test/Function/transWordsRequest" message="tns:transWords"/>
<output wsam:Action="http://webService.test/Function/transWordsResponse" message="tns:transWordsResponse"/>
</operation>
</portType>
<binding name="FunctionPortBinding" type="tns:Function">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="transWords">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="FunctionService">
<port name="FunctionPort" binding="tns:FunctionPortBinding">
<soap:address location="http://localhost:9001/Service/Function"/>
</port>
</service>
</definitions>

WSDL documents use the following elements in the definition of Web services:

  • Types - A container for data type definition that uses a type system (typesystems in XML Schema are generally used).
  • Message - An Abstract typed definition of the data structure of a communication message. Use the types defined by Types to define the data structure of the entire message.
  • Operation - An abstract description of the operations supported in a service. Generally, a single operation describes a request/response message pair that accesses an entry.
  • PortType - An Abstract collection of operations supported by an access entry point type that can be supported by one or more service access points.
  • Binding - Binding of specific protocols and data format specifications for specific port types.
  • Port - A single service access point defined as a combination of protocol/data format binding and specific Web access addresses.
  • Service - A collection of related service access points.

Then run the following command under the client project: wsimport-s Documents/workspace/GiveMeWords/src-p.com.shu.service-keep http://localhost:9001/Service/Function?

Documents/workspace/GiveMeWords/src code location

com.shu.service package name

Test code:


public class Test {
	/**
	 * Test web service as a client
	 * test Function under the web service package in the project acts as a server
	 *wsimport -s Documents/workspace/GiveMeWords/src -p com.shu.service -keep http://localhost:9001/Service/Function?wsdl
	 * @param args
	 */
	public static void main(String[] args){
			Function fu = new FunctionService().getFunctionPort();
			String str = fu.transWords("get my words");
			System.out.println(str);
	}
}

Running calls the remote method transWords() method on the server. But how does the client know that the service exposed by the server is transWords, and how does the client know about the parameter return value? Let's go back to the WSDL file above:

<portType name="Function">
<operation name="transWords">
<input wsam:Action="http://webService.test/Function/transWordsRequest" message="tns:transWords"/>
<output wsam:Action="http://webService.test/Function/transWordsResponse" message="tns:transWordsResponse"/>
</operation>
</portType>

The operation expression indicates that the method name of the method exposed service is transWords. The < input > label indicates the input parameter and the < output > function returns the value. So we get the interface we want. In short, we can program through WSDL files.

Posted by smith.james0 on Mon, 10 Dec 2018 04:48:05 -0800