sexta-feira, fevereiro 25, 2011

Enviando arquivo PDF a um Java Servlet

Bom, faz algum tempo que não posto nada e portanto não vou ficar escrevendo desnecessariamente. Basicamente tive a necessidade de enviar de uma aplicação Java (JSE) um arquivo .PDF a outra aplicação Java Web (JEE) usando protocolo HTTP pelo intercurso de um Java Servlet. Tal solução pode ser utilizado num Java Applet.

Segue abaixo o que foi feito.

Aplicação Java (JSE) é bastante simples. Para este exemplo, eu criei uma classe principal chamada Main e toda a lógica está dentro do método main da classe.

Coloque todo o conteúdo baixo dentro de um bloco try/catch. Cuide para captar o Exception e faça o tratamento de acordo com a sua imaginação e necessidade.

// URL da minha aplicação web.

URL url = new URL("http://localhost:8080/TestAppletServletConnServer/StudentServlet");

// Abro a conexão com a minha aplicação web.

URLConnection servletConnection = url.openConnection();

// Seto alguns flags importantes para nossa aplicação. O mais importante de todos é o setOutput igual a true!

servletConnection.setDoOutput(true); servletConnection.setAllowUserInteraction(false); servletConnection.setUseCaches(false);
servletConnection.setDefaultUseCaches(false);

// Seto o parametro MIME para que minha requisicao seja entendida que é um arquivo pdf.
servletConnection.setRequestProperty("Content-Type", "application/pdf");


// Pego a referencia ao OutputStream da propria conexao.
BufferedOutputStream outputToServlet = new BufferedOutputStream(servletConnection.getOutputStream());


// Abro o stream de entrada vindo do arquivo pdf fonte.

FileInputStream input = new FileInputStream(new File("C:\\Temp\\pdf\\testToServer.pdf"));


// Passo a referencia ao objeto BufferedInputStream


BufferedInputStream buf = new BufferedInputStream(input);

// Aqui inicia o loop para escrever no output do servlet aberto anteriormente.


int readBytes = 0;

while ((readBytes = buf.read()) != -1) {

outputToServlet.write(readBytes);

}


outputToServlet.flush();
outputToServlet.close();

// Aqui eu pego uma referencia a um objeto InputStream. Isso eu percebi que é necessário porque somente assim é feito a requisição a classe servlet
BufferedInputStream ois = new BufferedInputStream(servletConnection.getInputStream());

ois.close();


Vamos agora criar o Servlet utilizado no exemplo. Eu ponho tudo dentro de um método processRequest e este processará tando POST quanto GET. Novamente, coloque tudo dentro de um bloco try/catch.

// Pego a referencia ou objeto OuputStream que ha dentro do objeto response ServletOutputStream out = response.getOutputStream();

// Algumas coisas são necessárias e só há dentro do objeto ServletContext.
ServletContext context = this.getServletConfig().getServletContext();

// Seto o tipo de conteúdo
response.setContentType(request.getParameter("contentType"));

// Aqui eu leio do stream de entrada o arquivo pdf.

InputStream istream = request.getInputStream();


// Passo a referencia ao objeto BufferedInputStream.
BufferedInputStream bis = new BufferedInputStream(istream);

// Crio um objeto BufferedOutputStream para escrever a saída numa referencia ao OutputStream do Servlet. Isso é necessário para finalizar com o response.
BufferedOutputStream bos = new BufferedOutputStream(out);

// Crio um objet BufferedOutputStream passando uma referencia ao arquivo que vou criar.

BufferedOutputStream bos2file = new BufferedOutputStream(new FileOutputStream("C:\\Temp\\pdf\\testFromServer.pdf"));


// Stream the file back to the client

byte[] buffer = new byte[4096];
int size;
size = bis.read(buffer);
while (size != -1) {
bos.write(buffer, 0, size);
bos2file.write(buffer, 0, size);
size = bis.read(buffer);

}

bis.close();

bos.flush();
bos.close();

bos2file.flush();
bos2file.close();


Bom, existem outra maneiras de conseguir isso. A minha é uma das muitas possíveis soluções. Notem que não utilizo biblioteca de terceiros.

Sem mais,

Daniel Barcellos