[RESOLVIDO]Receber um arquivo Zip via Rest

Galera,

Estou tentando receber um arquivo via rest e nada. Segue os meus códigos. Onde estou errando nessa bagaça!!!

Server

@Path("/atualizacaoCompleta")
public class AtualizacaoCompleta {

    @GET
    @Path("/atualizarSistemaCompleto/{id}")
    @Produces("application/zip")
    public StreamingOutput atualizarSistemaCompleto(@PathParam("id") int id) {

        return new StreamingOutput() {
            public void write(OutputStream output) throws IOException, WebApplicationException {
                try {
                    BufferedOutputStream bus = new BufferedOutputStream(output);
                    File f = new File("D:\\Agenda.zip");
                    FileInputStream fizip = new FileInputStream(f);
                    byte[] buffer2 = IOUtils.toByteArray(fizip);
                    bus.write(buffer2);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
    }
}

Cliente

public class TesteWB2 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet getRequest = new HttpGet("http://localhost:8080/ServidorWebPerformancei/atualizacaoCompleta/atualizarSistemaCompleto/23");
            getRequest.addHeader("accept", "application/zip");
            HttpResponse response = httpClient.execute(getRequest);
            if (response.getStatusLine().getStatusCode() != 200) {
                throw new RuntimeException("Failed : HTTP error code : "
                        + response.getStatusLine().getStatusCode());
            }

            
        /// long l =   response.getEntity().getContent()getContentLength();
            
            BufferedReader br = new BufferedReader(
                    new InputStreamReader((response.getEntity().getContent())));

            String output;
            System.out.println("Output from Server .... \n");
            while ((output = br.readLine()) != null) {
                System.out.println(output);
            }

            httpClient.getConnectionManager().shutdown();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Vamos lá:

  1. Retorne um array de bytes que fica mais fácil (tenho um projeto mostrando isso: https://github.com/alesaudate/kickstart-springjerseyhibernate).
  2. Ter um recurso chamado “/atualizacaoCompleta” no path é OK, mas ter um caminho “/atualizarSistemaCompleto” é muuuuito errado.
  3. Você está usando commons-http para consumir o serviço, é isso? Porque não usa a API do seu framework REST?

[]'s

[quote=Alexandre Saudate]Vamos lá:

  1. Retorne um array de bytes que fica mais fácil (tenho um projeto mostrando isso: https://github.com/alesaudate/kickstart-springjerseyhibernate).
  2. Ter um recurso chamado “/atualizacaoCompleta” no path é OK, mas ter um caminho “/atualizarSistemaCompleto” é muuuuito errado.
  3. Você está usando commons-http para consumir o serviço, é isso? Porque não usa a API do seu framework REST?

[]'s[/quote]

com relação ao item 2 estou corrigindo, é pq eu peguei o projeto no meio do caminho.
Com relação ao item 3 estou usando o commons-http pq ele tem menos jar do que o Jersey, depois vou colocar o cliente no Android.

Estou tentando passar um .zip, pq a informação que esta chegando no android esta demorando muito, em media 10 minutos para atualizar todo o sistema.
Mas ja vi varios fatores que estao deixando lento:

  1. A pessoal que comecou esta buscando tabela por tabela, por exemplo, primeiro atualiza o cliente, ai abre uma conexao espera a boa vontade da rede, recebe os dados, grava no android e depois fecha a conexao. com isso sao aproximadamente 20 vezes. Estou colocando isso em um unico XML. Espero que melhore!!

Att

Olha so, O arquivo ate agora esta dando 1.3 mb quando eu compacto ele esta dando 100 kb.

Sim, mas o que eu quero dizer é que, se você retornar um array de bytes (ao invés de um StreamingOutput) deve ficar mais fácil

Blza, Consegui passar o array de bytes para o cliente.
So que não estou conseguindo passar o meu array de bytes em um arquivo.

segue o codigo:

 public static void main(String[] args) {
        try {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet getRequest = new HttpGet("http://localhost:8080/ServidorWebPerformancei/atualizacaoCompleta/atualizarSistemaCompleto/23");
            getRequest.addHeader("accept", "application/json");
            HttpResponse response = httpClient.execute(getRequest);
            if (response.getStatusLine().getStatusCode() != 200) {
                throw new RuntimeException("Failed : HTTP error code : "
                        + response.getStatusLine().getStatusCode());
            }


          


            BufferedReader br = new BufferedReader(
                    new InputStreamReader((response.getEntity().getContent())));

           long tamanho =  response.getEntity().getContentLength();
           
           byte content[] = new byte[(int)tamanho];
           
            String output;
            System.out.println("Gravando Zip no arquivo temporario \n");
            File fileTemp = File.createTempFile("arquivo", ".zip");
            FileWriter fw = new FileWriter(fileTemp, true);
            PrintWriter pw = new PrintWriter(fw);
            BufferedWriter bw = new BufferedWriter(pw);
            
          
            int readCount = 0;
            while ((output = br.readLine()) != null) {
                bw.write(output);
                System.out.println(output);
            }

            bw.flush();
            bw.close();
            httpClient.getConnectionManager().shutdown();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Mude esta linha:

getRequest.addHeader("accept", "application/json");

Para

getRequest.addHeader("accept", "application/zip");

[]'s

meu problema esta nessa parte do codigo:


long tamanho =  response.getEntity().getContentLength();
           
           byte content[] = new byte[(int)tamanho];
           
            String output;
            System.out.println("Gravando Zip no arquivo temporario \n");
            File fileTemp = File.createTempFile("arquivo", ".zip");
            FileWriter fw = new FileWriter(fileTemp, true);
            PrintWriter pw = new PrintWriter(fw);
            BufferedWriter bw = new BufferedWriter(pw);
            
          
            int readCount = 0;
            while ((output = br.readLine()) != null) {
                bw.write(output);
                System.out.println(output);
            }

            bw.flush();
            bw.close();

quando vou abrir o arquivo esta dando erro. falando que o arquivo esta com erro no cabecalho.
Eu tenho que pegar o Array de bytes que esta chegando para mim e gravar ele. Não estou sabendo como pegar o array de bytes e gravar!

Tira esse PrintWriter do meio. Ele vai converter seu array de bytes em texto.

ja tentei ler assim tambem:

 DataInputStream dis = new DataInputStream( response.getEntity().getContent());
            
            long tamanho = response.getEntity().getContentLength();

            byte content[] = new byte[(int) tamanho];

            String output;
            System.out.println("Gravando Zip no arquivo temporario \n");
            File fileTemp = File.createTempFile("arquivo", ".zip");
            dis.read(content);
            FileOutputStream fos = new FileOutputStream(fileTemp);
            DataOutputStream outputStream = new DataOutputStream(fos);
            outputStream.write(content);
            outputStream.flush();
            outputStream.close();
            dis.close();

e nada, quando vou abrir o meu zip da problema!!!

Tem certeza que o zip no servidor está abrindo corretamente? E os parâmetros de tamanho, conteúdo, etc., você já checou se estão corretos?

sim. No servidor esta abrindo corretamente.
Ai eu transformo ele em um array de bytes e mando ele para o cliente.
ai estou tentando usar o seguinte código para transformar ele zip novamente.



            byte content[] = new byte[(int) tamanho];
            String output;
            System.out.println("Gravando Zip no arquivo temporario \n");
            File fileTemp = new File("c:\\temp\\arquivo.zip");
            DataInputStream dis = new DataInputStream( response.getEntity().getContent());
            dis.read(content);
            FileOutputStream fos = new FileOutputStream(fileTemp);
            DataOutputStream outputStream = new DataOutputStream(fos);
            outputStream.write(content);
            outputStream.flush();
            outputStream.close();
            dis.close();

metodo que eu converto o File em byte

 InputStream is = null;
        byte[] buffer = null;
        try {
            is = new FileInputStream(inFile);
            buffer = new byte[is.available()];
            is.read(buffer);
            is.close();
        } catch (FileNotFoundException e) {
            PerformanceiLogger.logError("recuperaFileEmByte", e);
        } catch (IOException e) {
            PerformanceiLogger.logError("recuperaFileEmByte", e);
        }
        return buffer;

Outra coisa que eu reparei foi o tamanho, esta o mesmo tamanho em ambas as partes.

[quote=vcsmetallica]sim. No servidor esta abrindo corretamente.
Ai eu transformo ele em um array de bytes e mando ele para o cliente.
ai estou tentando usar o seguinte código para transformar ele zip novamente.



            byte content[] = new byte[(int) tamanho];
            String output;
            System.out.println("Gravando Zip no arquivo temporario \n");
            File fileTemp = new File("c:\\temp\\arquivo.zip");
            DataInputStream dis = new DataInputStream( response.getEntity().getContent());
            dis.read(content);
            FileOutputStream fos = new FileOutputStream(fileTemp);
            DataOutputStream outputStream = new DataOutputStream(fos);
            outputStream.write(content);
            outputStream.flush();
            outputStream.close();
            dis.close();

metodo que eu converto o File em byte

 InputStream is = null;
        byte[] buffer = null;
        try {
            is = new FileInputStream(inFile);
            buffer = new byte[is.available()];
            is.read(buffer);
            is.close();
        } catch (FileNotFoundException e) {
            PerformanceiLogger.logError("recuperaFileEmByte", e);
        } catch (IOException e) {
            PerformanceiLogger.logError("recuperaFileEmByte", e);
        }
        return buffer;

Outra coisa que eu reparei foi o tamanho, esta o mesmo tamanho em ambas as partes.[/quote]

Tente o seguinte:


byte[] bytes = (byte[])response.getEntity();

FileOutputStream fos = new FileOutputStream("teste.zip");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write(bytes);
bos.flush();
bos.close();

ele nao deixa fazer o cast nessa linha
byte[] bytes = (byte[])response.getEntity();

[quote=vcsmetallica]ele nao deixa fazer o cast nessa linha
byte[] bytes = (byte[])response.getEntity(); [/quote]

Então mantenha como estava, com DataInputStream. Também pode ser uma boa incluir um BufferedInputStream.

entao:

primeiro inicio o meu array de byte:

long tamanho = response.getEntity().getContentLength();
byte content[] = new byte[(int)tamanho];//faço um cast aqui

Segundo passo pego os dados do servidor e passo para o meu array de bytes

DataInputStream dis = new DataInputStream(response.getEntity().getContent());
dis.read(content);

terceiro passo gravar o infeliz no disco:

FileOutputStream fos = new FileOutputStream(fileTemp);
DataOutputStream outputStream = new DataOutputStream(fos);
outputStream.write(content);
outputStream.flush();
outputStream.close();

Cara, teria que ser a coisa mais facil da terra!!!

Att

[quote=vcsmetallica]entao:

primeiro inicio o meu array de byte:

long tamanho = response.getEntity().getContentLength();
byte content[] = new byte[(int)tamanho];//faço um cast aqui

Segundo passo pego os dados do servidor e passo para o meu array de bytes

DataInputStream dis = new DataInputStream(response.getEntity().getContent());
dis.read(content);

terceiro passo gravar o infeliz no disco:

FileOutputStream fos = new FileOutputStream(fileTemp);
DataOutputStream outputStream = new DataOutputStream(fos);
outputStream.write(content);
outputStream.flush();
outputStream.close();

Cara, teria que ser a coisa mais facil da terra!!!

Att

[/quote]

Você já checou se o que está sendo retornado é, de fato, um arquivo zip? Se estiver dando erro na requisição, ele vai retornar um HTML com o erro.

Sim, é mesmo arquivo, inclusive no lado servidor eu verifiquei o tamanho do array de bytes é o mesmo valor retornado pela linha

long tamanho = response.getEntity().getContentLength();

meu codigo que envia para o cliente:


 @Produces("application/zip")
    public Response atualizarSistemaCompleto(@PathParam("id") int id) {
        try {
            byte[] b = new ControleAtualizaSistemaCompleto().atualizarSistemaCompleto(id);
            return Response.status(200).entity(b).build();
        } catch (Exception e) {
            PerformanceiLogger.logError("atualizarSistemaCompleto", e);
        }
        return null;
    }

Observei o seguinte.
Quando eu mando para o cliente o array de bytes ele esta chegando incompleto, faltando algumas partes.
No lado do servidor esta certinho.