Download Lecture 5: RMI with Servlets and JSP

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
CPAN423 Enterprise Java Programming
Lecture #5: RMI with Servlets and JSP
Remote Method Invocation is one of the Java’s object-to-object based distributed
computing technologies that allows Java objects running on separate processes
to communicate with each other as if they where running in the same process.
RMI was abased on technology called Remote Procedure Call. RPC allows a
program to call a function from another program (can be on another computer) as
if it was part of it. RPC perform all the networking and transmitting of data over
the internet. Transmitting data is called data marshalling. To work with RPC,
you need to learn an Interface Definition Language to describe the functions that
can be accessed remotely. RPC also does not support marshaling of objects.
When the object is register as a remote object, the client can obtain a remote
reference to this object, and call methods of that object as if it was local object
running in the same application.
RMI does all the marshalling of data and use object serialization mechanism to
transfer Java objects. JSDK comes with a utility called rmic that generates all
the networking code. To create a remote object, we need to perform the following
steps:
 Define a remote interface that extends the interface java.rmi.Remote.
Methods that the clients can invoke should be declared in this interface
(no implementation). Each of these methods should throw exception of
type java.rmi.RemoteException.
 Implement the remote interface by providing a class that extends
java.rmi.server.UnicastRemoteObject and implements the remote
interface. The constructor of UnicastRemoteObject class exports the
remote object it can listen to remote requests. The constructor of any
UnicastRemoteObject class must throw an exception of type
java.rmi.RemoteException. The implementation class must define also
a URI that the client can use to obtain a remote reference to the remote
object. This URI identify the hostname and the port of the computer that
the remote object will be registered. The format of this URI should be:
rmi://host:port/remoteObjectname
The default port for RMI registry is 1099.The JSDK comes with a utility
called rmiregistry used to manage the remote object registry.
The implementation class should also bind the remote object to the RMI
registry
with
the
defined
URI
using
the
static
method
java.rmi.Naming.rebind. If the remote object is already registered, the
rebind method will register a new version of this object.
1


Define the client application that will obtain a remote reference to the
remote object. The client can be any Java-based application including
Servlets, and JSP.
The client should use the static method java.rmi.Naming.lookup to
obtain a remote reference to the remote object by providing the remote
object’s URI.
Compile and run the remote object and the client. The rmic utility is used
to generate the stub class(s) that will be responsible for forwarding the
method invocation to the RMI layer, which in turn handles the
communication between the remote object and the client.
Java based application/applet runs in an environment called the sandbox where
permission must be granted to the application in order to access system
resources outside the sandbox. The permission should be declared in a file
called security policy file and checked by the Security Manager class. The
Security Manger class control what operations are permitted and it is one of the
three components of security checking in Java. The other two components are
the bytecode verifier and the class loader. The class loader is responsible for
loading all the required class files to run a program into the java virtual machine
and insure their integrity. The bytecode verifier inspect the loaded classes for
illegal instructions like bad pointers, arrays out of boundary, variables are not
initialized before they are used, and so on.
The JVM has a system wide security policy file called java.policy that grants
specific permissions that affect the entire system. This file is located under
jdk/jre/lib/security folder. JSDK comes with a utility called policytool used to
edit the security policy file. Also you can use any editor to modify the security
policy file manually. If the remote object has installed a Security Manager, the
proper security file must be provided.
Examples:
Ex1: RMI and servlet example:
In this example we will build a remote object that have a Servlet as a client. First
we will build an interface called PersonalInterface. PersonalInterface.java
should have the following content:
package ro;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface PersonalInterface extends Remote
{
boolean check(String name, String pass) throws RemoteException;
2
}
Then we will provide a class called PersonalInterfaceImlpl that provide
implementation for the method check of interface PersonalInterface. This
method will loop through two arrays of names and passwords to validate the user
login. The user login(name/password) should be passed as parameters to check
method. If a matching is found then check will return true, otherwise it will return
false. PersonalInterfaceImpl.java should have the following content:
package ro;
import java.rmi.*;
import java.rmi.server.*;
public class PersonalInterfaceImpl extends UnicastRemoteObject
implements PersonalInterface
{
/*
define two arrays for users’ names and passwords
*/
private String [] userName={"a","b","c"};
private String [] userPassword={"1","2","3"};
public PersonalInterfaceImpl () throws RemoteException
{
/*
call the super class constructor to export the remote object
*/
super();
}
/*
check for a match
*/
public boolean check(String name, String pass)
{
boolean found=false;
for (int i=0;i<userName.length;i++)
if (userName[i].equals(name) && userPassword[i].equals(pass))
found=true;
return found;
}
public static void main (String [] args)
{
if (System.getSecurityManager()==null)
{
System.setSecurityManager(new RMISecurityManager());
3
}
String serverName="rmi://localhost/PersonalInterface";
try
{
/*
bind the remote object to the URL rmi://localhost/PersonalInterface
*/
PersonalInterface pi=new PersonalInterfaceImpl();
Naming.rebind(serverName,pi);
System.out.println("Object is bounded");
}
catch(Exception e)
{
System.out.println(e.toString());
}
}
}
Since we have installed a security manager with the RMI object, we have to
provide a policy file that grants the required permission. Following is a policy file
called java.policy that contain the required permission:
grant {
permission java.net.SocketPermission "*:1024-65535",
"connect,accept";
permission java.net.SocketPermission "*:80", "connect";
};
The following is a Servlet called rimServlet that obtain a remote reference to the
PersonalInterface object, and call check method to validate the user login.
import java.rmi.*;
import java.rmi.registry.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import ro.*;
public class rmiServlet extends HttpServlet
{
public void doPost (HttpServletRequest req, HttpServletResponse res)
4
throws ServletException, IOException
{
res.setContentType("text/html");
PrintWriter out = res.getWriter();
String uName=req.getParameter("userName");
String uPassword=req.getParameter("userPassword");
try
{
/*
obtain a remote reference to the remote object PersonalInterface
*/
PersonalInterface pi=(PersonalInterface)
Naming.lookup("rmi://localhost:1099/PersonalInterface");
if (pi.check(uName,uPassword))
{
out.println("Login correct");
}
else
{
out.println("Login inccorrect <a
href='http://localhost:8080/loginUser.html'> try again </a>");
}
}
catch(Exception e)
{
out.print( e.toString());
}
}
}
And here is an HTML file called loginUser.html that will be used to invoke the
rmiServlet:
<html>
<title>Login Example</title>
</head>
<body>
<form method="post" action="http://localhost:8080/cpan423/rmiServlet">
Enter User Name: <input type="text" name="userName" size="20" /><br>
Enter User password: <input type="password" name="userPassword"
size="10" /><br>
<input type="submit" value="Login">
5
</form>
</html>
The following batch file shows the steps required to compile and run the remote
object PersonalInerface.
set path=C:\Program Files\Java\jdk1.5.0_06\bin;
set classpath=.;
javac ro/*.java
rmic -v1.2 ro.PersonalInterfaceImpl
start rmiregistry
java -Djava.security.policy=ro/java.policy ro.PersonalInterfaceImpl
java -ro.PersonalInterfaceImpl
pause
The files PersonalInterface.java, PersonalInterfaceImpl.java, and java.policy
should be stored under ro folder. The batch file should be stored one level
above.
The servlet file (rimServlet.java) should be saved in the folder:
resin-x.x.x\webapps\cpan423\WEB-INF\Classes and the userLogin.html
should be saved in the folder: resin-x.x.x\webapps\Cpan423. The following
configuration should be added to the web.xml file:
<servlet>
<servlet-name> rmi</servlet-name>
<servlet-class> rmiServlet </servlet-class>
</servlet>
<servlet-mapping>
<url-pattern> /rmiServlet</url-pattern>
<servlet-name> rmi </servlet-name>
</servlet-mapping>
Also you have to copy the interface class(Personalinterface.class) and the stub
class (PersonalInterfaceImpl_stub.class) to the folder in the folder:
resin-x.x.x\webapps\cpan423\WEB-INF\Classes
Ex2: RMI and JSP
In this example we will build a JSP called rmi.jsp that obtains a remote reference
to PersonalInterface object. The procedure for compiling and running the remote
6
object is the same as in Ex1. The JSP page should be saved in the folder in the
folder: resin-x.x.x\webapps\cpan423
Remember that you need the interface class(Personalinterface.class) and the
stub class (PersonalInterfaceImpl_stub.class) in the folder in the folder:
resin-x.x.x\webapps\cpan423\WEB-INF\Classes
Following is the source code for rmi.jsp:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>JSP Page</title>
</head>
<body>
<%@page import="java.rmi.* ,java.rmi.registry.*,ro.*" %>
<%
String uName=request.getParameter("userName");
String uPassword=request.getParameter("userPassword");
try
{
PersonalInterface pi=(PersonalInterface)
Naming.lookup("rmi://localhost:1099/PersonalInterface");
if (pi.check(uName,uPassword))
{
out.println("Login correct");
}
else
{
out.println("Login inccorrect <a
href='http://localhost:8080/loginUserJSP.html'> try again </a>");
}
}
catch(Exception e)
{
out.println(e.toString());
}
%>
</body>
</html>
7
And here is an HTML file called loginUserJSP.html that will be used to invoke
the rmi.jsp file:
<html>
<title>Login Example</title>
</head>
<body>
<form method="post" action="http://localhost:8080/cpan423/rmi.jsp">
Enter User Name: <input type="text" name="userName" size="20" /><br>
Enter User password: <input type="password" name="userPassword"
size="10" /><br>
<input type="submit" value="Login">
</form>
</html>
The file loginUserJSP.html should be stored in the folder in the folder:
resin-x.x.x\webapps\cpan423
8