Pass attribute
As we mentioned earlier, RMI can pass attributes and briefly introduce a situation about the expense reporting program. Below we will discuss how to design such systems. The purpose of this is to enable you to use RMI's function to pass attributes from one system to another, and arrange the current calculation location as you want, and facilitate future changes. The following example does not involve all issues that may occur in the real world, but can help readers understand how to handle problems.
Server definition policy
1 is a schematic diagram of an expense reporting system that can be dynamically configured. The client displays a graphical user interface (GUI) to the user, and the user fills in the spending report. The client program communicates with the server using RMI. The server uses JDBC (Java Relational Database Connection Pack) to store the expense report in the database. At this point, this seems to be similar to other multi-level systems, but there is a major difference - RMI can download properties.
Assuming the company's policy changes on expense reports. For example, the company is currently required to issue an invoice for expenditure of more than $ 20. But tomorrow, the company believes that this is too loose, and it will decide whether any expenditure needs to issue an invoice except for meals for $ 20. If you cannot download the properties, you can choose one of the following methods when you design the system designed to be modified:
Use the client to install the program related to the policy. When policy changes, you must update all client programs that contain this policy. You can install the client on several servers and require all users to run the client from one of these servers, thereby reducing problems. But this still can't completely solve the problem - users who make the program run for several days will not make the program to update, and there will always be some users to copy the software to the local disk for the convenience.
You can ask the server to check the policy at each time to add a project to the expense report. But this will generate a lot of data flow between the client and the server, and increase the workload of the server. This will also make the system more vulnerable - network faults immediately impede users, not just affecting them only in its submit spending or starting new reports. At the same time, the speed of adding items will also be slow because it needs to pass through the entire network to and from a circle to reach (overwhelmed) servers.
You can ask the server to check the policy when you submit a report. This will enable the user to create a lot of error items that must be approved, not immediately capturing the first error, so that users have the opportunity to stop manufacturing errors. To avoid waste, users need to get feedback on errors.
With RMI, you can get the property from the server from the server with a simple method call, providing a flexible way to uninstall the computing task from the server to the client while providing users with faster feedback. When the user is ready to write a new spending report, the client will require an object to the server, which is embedded in the current policy for the spending report, just like the policy interface written in Java. This object can achieve current policies in any way. If this is the first time that the client RMI sees this specially implemented policy, the server will ask the server to provide a copy of the execution process. If the execution process changes, a new policy object will be returned to the client, while the RMI is running, the new execution process is required.
This shows that policy is always dynamic. You want to modify the policy, just simply write a new executive program of the general policy interface, install it on the server, and configure the server to return this new type of object. In this way, each client will check the new spending report according to the new policy.
This is a better way than any static method, which is as follows:
All clients do not have to suspend or use new software to upgrade - the software can be updated when not working as needed. The server does not have to participate in the project inspection work, which can be done locally. Allow dynamic limits because the object execution program (not just data) is passed between the client and the server. User users can immediately see errors.
The remote interface to make the client can call on the server is as follows:
Import java.rmi. *;
Public interface ex accountserver extends remote {policy getpolicy () throws remoteexception;
Void SubmitReport (ExpenseReport Report)
Throws RemoteException, INVALIDREPORTEXCEPTION;
}
IMPORT statement Enter Java RMI package. All RMI types are defined in the package java.rmi or its sub-pack. Interface Expenseserver is a general Java interface with two interesting features:
It expands the RMI interface called Remote, which makes the interface as available for remote calls.
All of its methods throws RemoteException, the latter used to represent a network or information failure.
The remote approach can also throw any other exception you need, but at least the RemoteException must be thrown so that you can handle the error status that only occurs in the distributed system. The interface itself supports two methods: getPolicy (returning an object to implement policy interface), and SubmitReport (submit a completed expense request, and throw an exception when the report is erroneous, if the report is wrong, throw an exception).
The policy interface itself can declare a method that enables the client to know if it can add a project in an expense report:
Public interface policy {
Void Checkvalid (Expensentry Entry)
Throws PolicyViolationException;
}
If the project is valid - that is, it meets the current policy, the method will return normally. Otherwise, an exception to describe the error will be thrown. The policy interface is local (rather than remote), so it will be performed on the client through the local object - on the client's virtual machine, not the object running on the network. The client may run the following programs:
Policy Curpolicy = Server.getPolicy ();
START A New Expense Report
SHOW the gui to the user
While (user keeps adding entries) {
Try {
Curpolicy.checkvalid (entry); // throws Exception if not OK
Add The entry to the expense report
} catch (policyviolationext e) {
Show the Error to the User
}
}
Server.SubmitReport (Report);
When the user requests the client software to start a new spending report, the client calls Server.getPolicy and requires the server to return an object that contains the current expense policy. Each project added is first submitted to the policy object to obtain approval. If the policy object reports have no error, the project is added to the report; otherwise the error is displayed to the user, and the latter can take corrective measures. The entire report is submitted when the user completes it to add an item to the report. The service program is as follows:
Import java.rmi. *;
Import java.rmi.server. *;
Class ExpenseServerImpl
Extends UnicastRemoteObject
Implements ExpenseServer
{
ExpenseserverImpl () throws remoteException {
//.. SET UP server state..
}
Public policy getPolicy () {
Return New TodaySpolicy ();
}
Public void submitReport (ExpenseReport Report) {//... Write The Report Into the DB..
}
}
In addition to the basic package, we also enter the RMI service package. Type UnicastRemoteObject defines the type of this service program remote object, in this case, should be a single service program instead of copying service (hereinafter also described in detail below). Java class ExpensseverIMPL implements remote Extribserver methods. Remote host's clients can send information to the ExpenseServerImpl object using RMI.
The important way to discuss in this article is GetPolicy, which simply returns the object of defining the current policy. Look at an example of an executive policy:
Public class todayspolicy ustements policy {
Public void Checkvalid (Expensentry Entry)
Throws PolicyViolationException
{
IF (entry.dollars () <20) {
Return; // no receipt request
Else IF (entry.haveReceipt () == false) {
Throw New PolicyViolationException;
}
}
}
The purpose of TodaySpolicy check is to ensure that no receipt is less than $ 20. If future policies have changed, only less than $ 20 mens may not be limited by the "need receipt" policy, you can provide new policy implementations:
Public Class TomorrowSPolicy Implements Policy {
Public void Checkvalid (Expensentry Entry)
Throws PolicyViolationException
{
IF (entry.ismeal () && entry.dollars () <20) {
Return; // no receipt request
} else if (entry.haveReceipt () == false) {
Throw New PolicyViolationException;
}
}
}
Write this class and install it on the server, then tell the server to start providing TomorrowSPolicy objects, not a dayspolicy object, so your entire system will start using new policies. When the client calls the server's getPolicy method, the client's RMI checks if the returned object is a known type. Each client encounters TomorrowSPolicy for the first time, RMI will return the implementation of the previous download policy in getPolicy. The client can easily start to enhance this new policy.
RMI transmits an object using a standard Java object serial mechanism. Quote Remote object parameters are passed as remote references. If the parameters provided to a method are original types or native (non-remote) objects, pass a deep copy to the server. The return value is also handled in the same way, but it is only along other directions. RMI allows the user to pass and return a full object map to the local object and passes and returns a reference for remote objects.