Hoje me perguntaram como poderia ser feita uma transferência de arquivo via Servlet, então resolvi trazer uma implementação fake para servir de exemplo.
Então vamos criar um Servlet básico usando o NetBeans e o Glassfish que já vem embutido.
Então, crie uma aplicação web vazia e adicione um novo Servlet.
Certo. Agora só precisamos criar uma classe que leia um arquivo local e retorne um conjunto de bytes, para então transferirmos estes bytes via HTTPResponse.
Para tanto, defina a classe LeitorArquivo como abaixo:
private class LeitorArquivo{
private FileInputStream fis;
private String arquivo;
public LeitorArquivo(String caminho){
this.arquivo = caminho;
}
private FileInputStream getFileInputStream(){
if (fis == null){
try {
fis = new FileInputStream(arquivo);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
return fis;
}
public byte[] ler(long pos, long offset) throws java.io.IOException{
FileChannel fc = getFileInputStream().getChannel();
Long size = fc.size();
fc.position(pos);
if (pos + offset > size)
offset = (long)(size.intValue() - pos);
byte[] data = new byte[(int)offset];
ByteBuffer bb = ByteBuffer.wrap(data);
fc.read(bb);
return data;
}
public boolean arquivoLido(long pos, long offset) throws java.io.IOException{
long size = getFileInputStream().getChannel().size();
return (pos + offset >= size);
}
public void liberarArquivo(){
try {
if (getFileInputStream() != null)
getFileInputStream().close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Pronto, agora criamos o método de transferência em nosso Servlet:
private void streamBinaryData(byte[] pack, String mimeType, ServletOutputStream outstr, HttpServletResponse resp)
throws IOException{
BufferedOutputStream bos = null;
resp.setContentType(mimeType);
try{
bos = new BufferedOutputStream(outstr);
bos.write(pack, 0, pack.length);
bos.close();
outstr.flush();
outstr.close();
}catch (IOException e) {
throw e;
}
}
E modificamos o método processRequest, para que fique da seguinte forma:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String caminho = request.getParameter("arq");
String mime = request.getParameter("mime");
long pos = new Long(request.getParameter("pos")).longValue();
long offset = new Long(request.getParameter("offset")).longValue();
LeitorArquivo l = new LeitorArquivo(caminho);
streamBinaryData((byte[])l.ler(pos, offset) , mime, response.getOutputStream(), response);
l.liberarArquivo();
}
Agora basta rodar a aplicação (isso pode ser feito com o botão direito -> Executar). O servidor Glassfish vai iniciar e o Servlet vai ser inicializado juntamente à ele. Para testar nosso servlet, faça a chamada:
http://localhost:8080//<Contexto><Servlet>?arq=<Arquivo>&pos=<Inicio>&offset=<Fim>&mime=<Mime>
Por exemplo, se sua aplicação se chamar LeitorDeArquivos..
http://localhost:8080/LeitorDeArquivos/FornecedorArquivo?arq=C:\\bar.emf&pos=0&offset=9999999999999&mime=jpeg
Agora você pode instalar um servidor de aplicação como o Glassfish (o Tomcat seria melhor neste caso) na máquina onde o arquivo à transferir se encontra, e em uma outra máquina fazer a chamada ao servlet via HTTP.
Note que em uma implementação real nos preocupariamos com mais detalhes, como o checksum dos arquivos (para verificar se estão corrompidos), o fechamento thread-safe dos recursos, etc.
Este tutorial tem por objetivo ser simples e direto, então informações sobre servidores, servlets e leitura/escrita de arquivos foram omitidos. A documentação pode ajudar nestes quesitos.