Download via Java [RESOLVIDO]

Pessoal é o seguinte, estou tentando criar uma classe que efetue o download de um arquivo (*.mdb - MS-Access) via socket.

Criei o método abaixo para efetuar a conexao com o servidor http e logo apos criar o arquivo.:

public void enviar(){

		Properties systemSettings = System.getProperties();
		systemSettings.put("http.proxyHost", "172.24.200.100");
		systemSettings.put("http.proxyPort", "8080");
		System.setProperties(systemSettings);

		try{
			HttpURLConnection conn = (HttpURLConnection) this.url.openConnection();
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setRequestMethod("POST");
			conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.0; de-DE; rv:1.7.5) Gecko/20041122 Firefox/1.0");
			conn.setRequestProperty("Accept", "application/x-msdownload, application/msaccess");
			conn.setRequestProperty("Accept-Language", "pt-br");
			conn.setRequestProperty("Keep-Alive", "300");
			conn.setRequestProperty("Connection", "keep-alive");

			conn.connect();
			int tamanhoArquivo = conn.getContentLength();
			File file = new File("c:\\Thread\\arquivo.mdb");

			if(!file.exists()){
				file.createNewFile();
			}

			FileOutputStream fileStream = new FileOutputStream(file);
			byte [] byteFile = new byte[tamanhoArquivo];
			int offset = 0;   
			int numRead = 0;  
			int cont = 0;
			while (offset < byteFile.length && 
					(numRead=conn.getInputStream().read()) >= 0) {   
				fileStream.write(byteFile, 0, numRead);
				if(cont == 921){
					System.out.println(">");
					cont = 0;
				}
				cont++;;   
			}   
		}catch(Throwable e){
			e.printStackTrace();
		}
	}

Mas sempre quando executo este método me retorna uma exception:

java.io.IOException: Server returned HTTP response code: 411 for URL: http://sitedodownload.com/download.asp?PT=&snomearquivo=D:\pastas\arquivo.mdb
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
	at java.lang.reflect.Constructor.newInstance(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection$6.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.net.www.protocol.http.HttpURLConnection.getChainedException(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
	at br.com.unimed.cn.download.FileDownload.enviar(FileDownload.java:74)
	at br.com.unimed.cn.download.FileDownload.main(FileDownload.java:92)

alguém tem alguma idéia do que pode ser este problema?

sim, o servidor esta retornando um 411 a sua requisição.

Entaum isso eu percebi quando executei a classe.

Fiz algumas alterações no método:

public void enviar() throws Exception{

		Properties systemSettings = System.getProperties();
		systemSettings.put("http.proxyHost", "172.24.200.100");
		systemSettings.put("http.proxyPort", "8080");
		System.setProperties(systemSettings);


		HttpURLConnection conn = (HttpURLConnection) this.url.openConnection();
		conn.setDoOutput(true);
		conn.setDoInput(true);
		conn.setRequestMethod("POST");
		conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.0; de-DE; rv:1.7.5) Gecko/20041122 Firefox/1.0");
		conn.setRequestProperty("Accept", "application/ms-download, application/msaccess");
		conn.setRequestProperty("Accept-Language", "pt-br");
		conn.setRequestProperty("Keep-Alive", "300");
		conn.setRequestProperty("Connection", "keep-alive");

		conn.connect();
		
		File file = new File("c:\\Thread\\arquivo.mdb");

		if(!file.exists()){
			file.createNewFile();
		}

		FileOutputStream fileStream = new FileOutputStream(file);
		OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
        wr.write(this.parametros);
        wr.flush();
        
        BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line;
        int cont = 0;
        System.out.println("Baixando Arquivo: \n |");
        while ((line = rd.readLine()) != null) {
        	if(cont == 92100){
	       		System.out.println(">");
				cont = 0;
        	}
        	fileStream.write(line.getBytes());
        	cont++;
        }
        fileStream.close();
        wr.close();
        rd.close();
        
        wr = null;
        rd = null;
        
        System.out.println("Arquivo baixado com sucesso.");
		conn.disconnect();
		conn = null;
}

Agora consigo efetuar o download, mas ao abrir meu arquivo, o MS-ACCESS não reconhece como um arquivo de banco de dados.

Alguem tem alguma idéia de como gravar esse arquivo corretamente para que o access reconheça corretamente?

verifique o tamanho e o md5sum: acho que vc esta corrompendo o arquivo por uns bytes a menos ou a mais.

Então, vc tem algum pequeno exemplo de como posso fazer isso?

Dá a impressão que você em vez do seu arquivo baixou uma página HTML de erro. Experimente pegar o “arquivo” que você baixou e mude sua extensão para .html, e carregue-o

to baixando o arquivo correto, o problema eh que naum está baixando o arquivo completo…

ele naum copia quase 1 MB do arquivo original.

será que meu algoritmo ta errado?? alguem tem alguma sugestão sobre como leio o arquivo completo?

Acho que essa API pode te ajudar:

http://hc.apache.org/httpclient-3.x/

é o httpclient…
já foi muito útil pra mim!
:smiley:
flws

vc tem algum exemplo?

Fiz um passo a passo com estas bibliotecas da apache, mas é bem semelhante ao usar System.getProperties(); para setar o proxy e o HttpURLConnection para efetuar a conexao.

Meu problema acredito que eh um pouco mais embaixo.

Quando faço o download via Internet Explorer, abre normalmente.
Quando eu efetuo o download via aplicação java, sempre quando tento abrir o arquivo, este me pede uma senha.

Verifiquei os bytes que foram baixados via aplicacao java, e são exatamente os mesmos do arquivo .mdb baixado pelo internet explorer.

não sei por que acontece isso. Para testes tentei copiar o arquivo corrreto(baixado do IE) para um novo File, com extensao MDB… funcionou corretamente.

Alguém tem alguma idéia do pq está acontecendo isso com o meu download via aplicaçao Java?

a meu método é o seguinte:

public void enviar() throws Exception{

		Properties systemSettings = System.getProperties();
		systemSettings.put("http.proxyHost", "192.168.4.254");
		systemSettings.put("http.proxyPort", "8080");
		System.setProperties(systemSettings);


		HttpURLConnection conn = (HttpURLConnection) this.url.openConnection();
		conn.setDoOutput(true);
		conn.setDoInput(true);
		conn.setRequestMethod("GET");
		conn.setRequestProperty("Keep-Alive", "300");
		conn.setRequestProperty("Connection", "keep-alive");

		conn.connect();

		File file = new File("c:\\Thread\\arquivo.mdb");

		if(!file.exists()){
			file.createNewFile();
		}

		FileOutputStream fileStream = new FileOutputStream(file);

		OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
		wr.write(this.parametros);
		wr.flush();

		BufferedReader bis = new BufferedReader(new InputStreamReader(conn.getInputStream()));
		BufferedOutputStream bos = new BufferedOutputStream(fileStream);

		int x;
		int cont = 0;
		int numero = 0;
		System.out.println("Iniciando Download: ");
		System.out.print("0%");
		while((x = bis.read()) != -1){ 
			if(cont == 120){
				bos.write(posicoes.get(cont));
			}else{
				bos.write(x);
			} 
			if(cont == ((int)(868065))){
				numero++;
				System.out.print(">");
				cont = 0;
				if(numero == 25){
					System.out.print("25%");
				}else if(numero == 50){
					System.out.print("50%");
				}else if(numero == 75){
					System.out.print("75%");
				}
			}
			cont++;
		}   
		System.out.print("100%");

		bis.close();
		bos.close();
		fileStream.close();
		conn.disconnect();
		wr.close();

		bis = null;
		bos = null;
		fileStream = null;
		conn = null;
		wr = null;

		System.out.println("\nArquivo baixado com sucesso.");

	}

RESOLVIDO: alterei as seguintes linhas do código

byte[] buf = new byte[1024];
		
int x;
int cont = 0;
int numero = 0;
System.out.println("Iniciando Download: ");
System.out.print("0%");
while((x = bis.read(buf)) != -1){ 
	bos.write(buf,0,x);
	if(cont == ((int)(880))){
		numero++;
		System.out.print(">");
		cont = 0;
		if(numero == 25){
			System.out.print("25%");
		}else if(numero == 50){
			System.out.print("50%");
		}else if(numero == 75){
			System.out.print("75%");
		}
	}
	cont++;
}