Por que usar RMI
Neste projeto, pensei em várias maneiras de comunicação entre o cliente e o servidor. Como estava trabalhando em um aplicativo cliente rico, finalmente selecionei a tecnologia entre RMI e soquetes Java. Entre eles, RMI A flexibilidade não é alta. Tanto o cliente quanto o servidor devem ser escritos em Java, mas é mais conveniente de usar. Por outro lado, os soquetes java, embora mais flexíveis, precisam definir o protocolo de comunicação entre o servidor e o cliente. É bastante problemático. Depois de pesar várias vezes, finalmente escolhi o RMI para comunicação servidor-cliente.
Problema no upload de arquivo
No processo de uso do java-rmi, você inevitavelmente encontrará um problema de upload de arquivo. Como os fluxos de arquivo não podem ser transmitidos no rmi (por exemplo, os parâmetros do método no rmi não podem ser FileInputStream e similares), então temos que escolher um compromisso. .A melhor maneira é primeiro usar FileInputStream para ler o arquivo em uma matriz Byte, depois passar essa matriz Byte como um parâmetro para o método RMI e, em seguida, restaurar a matriz Byte para um outputStream no lado do servidor, para que possa ser. passou pelo RMI Vamos transferir arquivos
Isto também tem a desvantagem de a precisão dos dados transmitidos não poder ser verificada.
Deixe-me explicar com um exemplo abaixo.
ArquivoCliente
Copie o código do código da seguinte forma:
pacote rmiupload;
importar java.io.BufferedInputStream;
importar java.io.File;
importar java.io.FileInputStream;
importar java.io.FileNotFoundException;
importar java.io.IOException;
importar java.net.MalformedURLException;
importar java.rmi.Naming;
importar java.rmi.NotBoundException;
importar java.rmi.RemoteException;
classe pública ArquivoCliente {
public ArquivoCliente() {
// TODO stub do construtor gerado automaticamente
}
public static void main(String[] args) {
tentar {
FileDataService fileDataService = (FileDataService) Naming.lookup("rmi://localhost:9001/FileDataService");
fileDataService.upload("/Users/NeverDie/Documents/test.mp4", new FileClient().fileToByte("/Users/NeverDie/Music/test.mp4"));
} catch (MalformedURLException | RemoteException | NotBoundException e) {
// TODO Bloco catch gerado automaticamente
e.printStackTrace();
}
}
//Este método é mais importante. Através deste método, um arquivo chamado filename é convertido em uma matriz de bytes.
byte privado[] fileToByte(String nome do arquivo){
byte[] b = nulo;
tentar {
Arquivo arquivo = novo arquivo (nome do arquivo);
b = novo byte[(int) arquivo.comprimento()];
BufferedInputStream é = new BufferedInputStream(new FileInputStream(arquivo));
é.ler(b);
} catch (FileNotFoundException e) {
// TODO Bloco catch gerado automaticamente
e.printStackTrace();
} catch (IOException e) {
// TODO Bloco catch gerado automaticamente
e.printStackTrace();
}
retornarb;
}
}
ArquivoDataService
pacote rmiupload;
importar java.net.URL;
importar java.rmi.Remote;
importar java.rmi.RemoteException;
interface pública FileDataService estende Remote{
//O nome do arquivo aqui deve ser o endereço onde o arquivo está armazenado no lado do servidor
public void upload (String filename, byte[] file) lança RemoteException;
}
ArquivoDataService_imp
Copie o código do código da seguinte forma:
pacote rmiupload;
importar java.io.BufferedOutputStream;
importar java.io.File;
importar java.io.FileNotFoundException;
importar java.io.FileOutputStream;
importar java.io.IOException;
importar java.net.URL;
importar java.rmi.RemoteException;
importar java.rmi.server.RMIClientSocketFactory;
importar java.rmi.server.RMIServerSocketFactory;
importar java.rmi.server.UnicastRemoteObject;
classe pública FileDataService_imp estende UnicastRemoteObject implementa FileDataService{
public FileDataService_imp() lança RemoteException {
}
@Substituir
public void upload(String nome do arquivo, byte[] fileContent) lança RemoteException{
Arquivo arquivo = novo arquivo (nome do arquivo);
tentar {
se (!file.exists())
arquivo.createNewFile();
BufferedOutputStream os = novo BufferedOutputStream(novo FileOutputStream(arquivo));
os.write(fileConteúdo);
} catch (FileNotFoundException e) {
// TODO Bloco catch gerado automaticamente
e.printStackTrace();
} catch (IOException e) {
// TODO Bloco catch gerado automaticamente
e.printStackTrace();
}
;
}
Servidor de arquivos
Copie o código do código da seguinte forma:
pacote rmiupload;
importar java.net.MalformedURLException;
importar java.rmi.Naming;
importar java.rmi.RemoteException;
importar java.rmi.registry.LocateRegistry;
classe pública Servidor de Arquivos {
FileDataService fileDataService;
servidor de arquivos público() {
tentar {
arquivoDataService = new FileDataService_imp();
LocateRegistry.createRegistry(9001);
Naming.rebind("rmi://localhost:9001/FileDataService", fileDataService);
} catch (RemoteException e) {
// TODO Bloco catch gerado automaticamente
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Bloco catch gerado automaticamente
e.printStackTrace();
}
}
/**
* @param argumentos
*/
public static void main(String[] args) {
novo Servidor de Arquivos();
}
}