SD 2018-Q2 - Prática
Prática Aula 02 - Calculadora Java RMI
Segundo Quadrimestre de 2018
Professor: Emilio Francesquini
E-mail: e.francesquini@ufabc.edu.br
Índice
O código abaixo implementa um simples servidor que faz as 4 operações aritméticas básicas utilizando Java RMI.
- Você pode baixar o código completo aqui: calculadora.zip
- Uma descrição mais detalhada do código pode ser vista aqui: pratica02.pdf
Número
Os tipos primitivos (assim como as classes Integer, Float, Double,
…) já implementam java.io.Serializable
. Aqui colocamos nossa
própria implementação para deixar claro o que é necessário fazer em um
caso mais geral e mais complexo que um simples número.
Download do .java
:
Numero.java
public interface Numero extends java.io.Serializable { double getValor(); }
NumeroImpl.java
public class NumeroImpl implements Numero { private double num; public NumeroImpl (double val) { num = val; } public double getValor() { return num; } }
Calculadora
Download do .java
:
Calculadora.java
import java.rmi.Remote; import java.rmi.RemoteException; public interface Calculadora extends Remote { public Numero soma (Numero a, Numero b) throws RemoteException; public Numero subtrai (Numero a, Numero b) throws RemoteException; public Numero multiplica (Numero a, Numero b) throws RemoteException; public Numero divide (Numero a, Numero b) throws RemoteException, DivisaoPorZeroException; }
CalculadoraImpl.java
public class CalculadoraImpl implements Calculadora { public Numero soma (Numero a, Numero b) { return new NumeroImpl (a.getValor() + b.getValor()); }; public Numero subtrai (Numero a, Numero b) { return new NumeroImpl (a.getValor() - b.getValor()); }; public Numero multiplica (Numero a, Numero b) { return new NumeroImpl (a.getValor() * b.getValor()); }; public Numero divide (Numero a, Numero b) throws DivisaoPorZeroException { if (b.getValor() == 0) throw new DivisaoPorZeroException(); return new NumeroImpl (a.getValor() / b.getValor()); }; }
DivisaoPorZeroException.java
public class DivisaoPorZeroException extends RuntimeException { }
Servidor
Download do .java
para o Servidor:
import java.rmi.registry.Registry; import java.rmi.registry.LocateRegistry; import java.rmi.server.UnicastRemoteObject; public class ServidorCalculadora { public static void main(String args[]) { try { //Crio o objeto servidor CalculadoraImpl calc = new CalculadoraImpl(); //Criamos o stub do objeto que será registrado Calculadora stub = (Calculadora)UnicastRemoteObject .exportObject(calc, 0); //Registra (binds) o stub no registry Registry registry = LocateRegistry.getRegistry(); registry.bind("calculadora", stub); System.out.println("Servidor iniciado."); } catch (Exception e) { System.err.println("Ocorreu um erro no servidor: " + e.toString()); } } }
Cliente
Download do .java
para o Cliente:
import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; public class ClienteCalculadora { public static void main(String[] args) { try { // Localiza o registry. É possível usar endereço/IP porta Registry registry = LocateRegistry.getRegistry(null); // Consulta o registry e obtém o stub para o objeto remoto Calculadora calc = (Calculadora) registry .lookup("calculadora"); // A partir deste momento, cahamadas à Caluladora podem ser // feitas como qualquer chamada a métodos Numero num1 = new NumeroImpl(3); Numero num2 = new NumeroImpl(4); //Aqui são feitas diversas chamadas remotas Numero soma = calc.soma(num1, num2); Numero sub = calc.subtrai(num1, num2); Numero mult = calc.multiplica(num1, num2); Numero div = calc.divide(num1, num2); System.out.println("Resultados obtidos do servidor:" + "\n\t+:" + soma.getValor() + "\n\t-:" + sub.getValor() + "\n\t*:" + mult.getValor() + "\n\t/:" + div.getValor()); try { calc.divide(new NumeroImpl(1), new NumeroImpl(0)); } catch (DivisaoPorZeroException e) { System.out.println( "Tentou dividir por zero! Esta é uma exceção remota."); } } catch (Exception e) { System.err.println("Ocorreu um erro no cliente: " + e.toString()); } } }