Connect to remote server with username/password for downloading files - java

I need to connect to a remote server which requires username/password and need to download videos and other pdf documents. What is the best way in java. A little code sample will be highly appreciable. I tried following, accept my apologies in advance if this code seems like a novice effort as I just started Java and learning the best practices from the guru's like you :). Problem is how to authenticate, how to provide username/password to the server.
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class Downloader {
URL url;
public Downloader(){
try {
url = new URL("https://d396qusza40orc.cloudfront.net/algs4partI/slides%2F13StacksAndQueues.pdf");
try {
URLConnection con = url.openConnection();
con.connect();
InputStream inStream = url.openStream();
FileOutputStream outStream = new FileOutputStream("data.dat");
int bytesRead;
byte[] buffer = new byte[100000];
while((bytesRead = inStream.read(buffer)) > 0){
outStream.write(buffer, 0 , bytesRead);
buffer = new byte[100000];
}
outStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args){
Downloader d = new Downloader();
}
}

You should be able to provide the username/password as part of the URL:
E.g.
https://username:password#example.com/secure/myfile.pdf
This does assume that the site is using standard HTTP authentication.
If some sort of custom authentication is being done you may need to supply a per-generated cookie containing authentication information or possibly do a separate log-in request before trying to download your file. This will all depend on the setup of the remote server.

Related

Is there a way to read PDF file stream with out using byte[ ] or readAllBytes() using java 1.8

My requirement is to invoke a Rest api, the o/p of which is a pdf file & generate a PDF file using a scripting language which is based on java.
We are using readAllBytes() method in our scripts, as we cannot use byte[] in our scripts(restriction). Equivalent java code for our script is below. As using readAllBytes() method is not recommended for reading large streams, is there an alternative for this without using byte[]? .
Please note: We are using 1.8 java and cannot use any third party libraries except Apache Commons IO.
Thank you for your help.
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class ExecuteReportFromScript {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
byte[] buffer = new byte[1024];
URL url = new URL("restEndPoint");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Cookie", "myCookieData");
con.setRequestProperty("Accept", "application/json");
con.setDoOutput(true);
con.connect();
System.out.println("Response Code:" + con.getResponseCode());
InputStream ip = con.getInputStream();
BufferedInputStream is = new BufferedInputStream(ip);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write( is.readAllBytes());
/*
* int length; while ((length = is.read(buffer)) > -1 ) { bos.write(buffer, 0,
* length); }
*/
bos.flush();
File file = new File("PathToFile\\FileName.pdf");
try(BufferedOutputStream salida = new BufferedOutputStream(new FileOutputStream(file))){
salida.write(bos.toByteArray());
salida.flush();
}
ip.close();
is.close();
bos.close();
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Write the stream directly to a file using Files.copy(InputStream in, Path target, CopyOption... options) (since Java 7).
Path file = Paths.get("PathToFile\\FileName.pdf");
try (InputStream in = new BufferedInputStream(con.getInputStream())) {
Files.copy(in, file);
}

Can't download file from internet using java

I'm trying to download file from internet using java but there have a problem. I'm not failed but each time when I'm trying to download it's downloading only 250-300 KB only though the file size is larger than that. I have tried a lot of ways but every time the result is same.
I have tried Apache Commons IO like this,
import java.io.File;
import java.net.URL;
import org.apache.commons.io.FileUtils;
public class Main {
public static void main(String[] args) {
try {
String from = "https://download.gimp.org/mirror/pub/gimp/v2.8/gimp-2.8.10.tar.bz2";
String to = "/home/ashik/gimp-2.8.10.tar.bz2";
System.out.println("Starting!");
FileUtils.copyURLToFile(new URL(from), new File(to), Integer.MAX_VALUE, Integer.MAX_VALUE);
System.out.println("Finished!");
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
I have tried Java NIO like this,
import java.io.FileOutputStream;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
public class Main {
public static void main(String[] args) {
try {
String from = "https://download.gimp.org/mirror/pub/gimp/v2.8/gimp-2.8.10.tar.bz2";
String to = "/home/ashik/gimp-2.8.10.tar.bz2";
System.out.println("Starting!");
ReadableByteChannel rbc = Channels.newChannel(new URL(from).openStream());
FileOutputStream fos = new FileOutputStream(to);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
System.out.println("Finished!");
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
I have also followed some stackoverflow solutions like, How to download and save a file from Internet using Java? , How to download large sized Files (size > 50MB) in java, etc but none of them are working.
Every time it's downloading but file size is only 250-300 KB. How to solve this problem?
Platform:
OS: Debian-9
JDK-Version: Oracle JDK-9
IDE: Eclipse Oxygen
Thank you in advance.
You don’t need a third-party library to do this. You could use Channels, but it’s shorter to use Files.copy:
try (InputStream stream = new URL(from).openStream()) {
Files.copy(stream, Paths.get(to));
}
In your case, the URL is redirecting to a different location. Ordinarily, calling setInstanceFollowRedirects would be sufficient:
HttpURLConnection conn = new URL(from).openConnection();
conn.setInstanceFollowRedirects(true);
try (InputStream stream = conn.getInputStream()) {
Files.copy(stream, Paths.get(to));
}
However, this is a special case. Your URL is an https URL, which redirects to an http URL.
Java considers that insecure (as it should), so it will never automatically follow that redirect, even if setInstanceFollowRedirects has been called.
Which means you have to follow the redirects yourself:
URL url = new URL(from);
HttpURLConnection conn;
while (true) {
conn = (HttpURLConnection) url.openConnection();
conn.setInstanceFollowRedirects(true);
int responseCode = conn.getResponseCode();
if (responseCode != HttpURLConnection.HTTP_MOVED_PERM &&
responseCode != HttpURLConnection.HTTP_MOVED_TEMP &&
responseCode != 307) {
break;
}
url = new URL(conn.getHeaderField("Location"));
}
try (InputStream stream = conn.getInputStream()) {
Files.copy(stream, Paths.get(to));
}

Streaming picture from java to php?

I am taking screenshot of my desktop and i want to know how i would go if i want to send it to php site and then display it?
I have made this and no results about streaming.
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import javax.imageio.ImageIO;
public class Stream{
static public void captureScreen() throws Exception {
Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
Rectangle screenRectangle = new Rectangle(screenSize);
Robot robot = new Robot();
BufferedImage image = robot.createScreenCapture(screenRectangle);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
ImageIO.write(image, "png", buffer);
byte[] data = buffer.toByteArray();
try {
// open a connection to the site
URL url = new URL("http://futuretechs.eu/stream.php");
URLConnection con = url.openConnection();
// activate the output
con.setDoOutput(true);
PrintStream ps = new PrintStream(con.getOutputStream());
// send your parameters to your site
ps.print("image=" + encodeArray(data));
System.out.println(encodeArray(data));
// we have to get the input stream in order to actually send the request
con.getInputStream();
// close the print stream
ps.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try{
System.out.println("[ Stream Started ]");
while(true){
Thread.currentThread().sleep(100);
Stream.captureScreen();
}
// System.out.println("[ Stream Ended ]");
}
catch(Exception e)
{
e.printStackTrace();
}
}
static String encodeArray(byte[] in) throws IOException {
StringBuffer out = new StringBuffer();
out.append(Base64Coder.encode(in, 0, in.length));
return out.toString();
}
}
How now i would send from java the byte[] to php and play it?
So it would go like this
Java Client program sends to php site the byte[] content and then the php shows it to the user who is at the site?
Thank you!
EDIT: CODE UPDATED
What is that site you wanna upload the screenshot content? Is that site on the internet?
There are different approaches.
- You could have a php page which waits for an HTTP-POST request, with the screenshot in the payload, while the site itself has a php-module running on that server and gets invoked by the web-request.
- That server probably supports WebDav, then you could upload your screenshot via HTTP-PUT and invoke a php site with HTTP-GET (while sending the filename with your HTTP-GET-Args).
It's hard to tell, if we don't know the php-site, it's API and/or it's behaviour.
well its better to convert the image bytes into base64 before sending to php
when you send to php you can use this function imagecreatefromstring($image_data) to display
display.php
<?php
$image = $_POST['image'];
$data = base64_decode($image);
$im = imagecreatefromstring($data);
if ($im !== false) {
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);
}
else {
echo 'An error occurred.';
}
?>
this should work with (PHP 4 >= 4.0.4, PHP 5)
Let me know if it works :)
Edit :
I am not really good with java try the below
As asked java code
try {
// open a connection to the site
URL url = new URL("http://www.yourdomain.com/yourphpscript.php");
URLConnection con = url.openConnection();
// activate the output
con.setDoOutput(true);
PrintStream ps = new PrintStream(con.getOutputStream());
// send your parameters to your site
ps.print("image=BASE64_ENCODED_STRING_HERE");
// we have to get the input stream in order to actually send the request
con.getInputStream();
// close the print stream
ps.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
or Use HTTP Client in java
HttpClient client = new HttpClient();
PostMethod method = new PostMethod("http://www.yourdomain.com/yourphpscript.php");
method.addParamezter("image","BASE64_ENCODED_STRING"); // or whatever
int statusCode = client.executeMethod(method);

Client Server File Transfer Java

I am trying to write an application using Java that will allow me to transfer files between a server and a client that requests the file. I plan to do it using sockets. My algorithm is somewhat like this:
On Server:
Create the connection between client and server.
Once connected find the file u need to send to client.
Then send the size of file to client.
Then send file broken down in parts.
On Client
After connection is created, ask for the file.
Receive the file size, then accept data till u reach file size.
Stop.
Please correct me if i am wrong somewhere in the algorithm
This isn't really an "algorithm" question; you're designing a (simple) protocol. What you've described sounds reasonable, but it's too vague to implement. You need to be more specific. For example, some things you need to decide:
How does the receiving program know what filename it should save to? Should that be sent through the socket, or should it just ask the user?
How is the file size transmitted?
Is it a character string? If so, how is its length indicated? (With a null terminator? A newline?)
Is it a binary value? If so, how big? (32 bits or 64?) What endianness?
What does "broken down in parts" mean? If you're writing to a TCP socket, you don't need to worry about packet boundaries; TCP takes care of that.
Does the recipient send anything back, like a success or failure indication?
What happens when the whole file has been transmitted?
Should both ends assume that the connection must be closed?
Or can you send multiple files through a single connection? If so, how does the sender indicate that another file will follow?
Also, you're using the terms "client" and "server" backward. Typically the "client" is the machine that initiates a connection to a server, and the "server" is the machine that waits for connections from clients.
You can also add Acknowledgement from server once a particular part of the file is recieved,
similar to what we have in HTTP protocol , that would ensure proper delivery of the file has been received on the server.
Here is the method that I use, it uses the socket's input and output streams to send and receive the files, and when it's done, it will automatically restart the server and reconnect to it from the client.
Server Code:
package app.server;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Functions
{
private static ServerSocket server;
private static Socket socket;
public static void startServer(int port)
{
try
{
server = new ServerSocket(port);
socket = server.accept();
}
catch (IOException ex)
{
Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
}
}
private static void restartServer()
{
new Thread()
{
#Override
public void run()
{
try
{
socket = server.accept();
}
catch (IOException ex)
{
Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
}
}
}.start();
}
public static void sendFile(String inputFilePath)
{
FileInputStream fis;
BufferedInputStream bis;
OutputStream os;
BufferedOutputStream bos;
try
{
File input = new File(inputFilePath);
fis = new FileInputStream(input);
bis = new BufferedInputStream(fis);
os = socket.getOutputStream();
bos = new BufferedOutputStream(os);
byte[] buffer = new byte[1024];
int data;
while(true)
{
data = bis.read(buffer);
if(data != -1)
{
bos.write(buffer, 0, 1024);
}
else
{
bis.close();
bos.close();
break;
}
}
}
catch (FileNotFoundException ex)
{
Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IOException ex)
{
Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
}
restartServer();
}
}
Client Code:
package app.client;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Functions
{
private static Socket socket;
private static String hostName;
private static int portNumber;
public static void connectToServer(String host, int port)
{
new Thread()
{
#Override
public void run()
{
try
{
hostName = host;
portNumber = port;
socket = new Socket(host, port);
}
catch (IOException ex)
{
Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
}
}
}.start();
}
private static void reconnectToServer()
{
try
{
socket = new Socket(hostName, portNumber);
}
catch (IOException ex)
{
Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void receiveFile(String outputFilePath)
{
InputStream is;
BufferedInputStream bis;
FileOutputStream fos;
BufferedOutputStream bos;
try
{
File output = new File(outputFilePath);
is = socket.getInputStream();
bis = new BufferedInputStream(is);
fos = new FileOutputStream(output);
bos = new BufferedOutputStream(fos);
byte[] buffer = new byte[1024];
int data;
while(true)
{
data = bis.read(buffer);
if(data != -1)
{
bos.write(buffer, 0, 1024);
}
else
{
bis.close();
bos.close();
break;
}
}
}
catch (IOException ex)
{
Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
}
reconnectToServer();
}
}
This method works very well, I use it for my server and client file transfer program, all you need to do is enter the Server Host's IP address and choose a port number (I use 8888).

java https login and browsing

I want to login to an https site on the internet with java and then read some information. I already looked with firebug to the headers, however I couldn't manage to make it ...
Firebug tells:
https://service.example.net/xxx/unternehmer/login.html?login=Anmelden&loginname=xxx&password=xxx&sessionid=&sprache=de
And then I want to browse to this site:
https://service.example.net/xxx/unternehmer/ausgabe.html?code=PORTAL;sessionid=03112010150442
how can I do this with java?
I already tried something like:
import java.net.*;
import java.io.*;
import java.security.*;
import javax.net.ssl.*;
public class HTTPSClient {
public static void main(String[] args) {
int port = 443; // default https port
String host = "service.example.net";
try {
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
// enable all the suites
String[] supported = socket.getSupportedCipherSuites();
socket.setEnabledCipherSuites(supported);
Writer out = new OutputStreamWriter(socket.getOutputStream());
// https requires the full URL in the GET line
out.write("POST https://" + host + "//xxx/unternehmer/login.html?login=Anmelden&loginname=xxx&password=xxx&sessionid=&sprache=de HTTP/1.1\r\n");
out.write("Host: " + host + "\r\n");
out.write("\r\n");
out.flush();
// read response
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
// read the header
String s;
while (!(s = in.readLine()).equals("")) {
System.out.println(s);
}
System.out.println();
// read the length
String contentLength = in.readLine();
int length = Integer.MAX_VALUE;
try {
length = Integer.parseInt(contentLength.trim(), 16);
}
catch (NumberFormatException ex) {
// This server doesn't send the content-length
// in the first line of the response body
}
System.out.println(contentLength);
int c;
int i = 0;
while ((c = in.read()) != -1 && i++ < length) {
System.out.write(c);
}
System.out.println("1.part done");
out.close();
in.close();
socket.close();
}
catch (IOException ex) {
System.err.println(ex);
}
}
}
unfortunately that doesnt work for the login ....
and i also dont know where to get this sessionid...everytime it is a different one.
i hope you can help me.
ps: i replaced some relevant information with xxx
Problem solved :)
First I added the libraries from apache:
httpclient
commons-httpclient
commons-codec
commons-logging
then I combined several tutorials.
my code:
import java.io.BufferedWriter;
import java.io.FileWriter;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.http.client.params.CookiePolicy;
public class Test {
public static final String TARGET_HTTPS_SERVER = "www.example.net";
public static final int TARGET_HTTPS_PORT = 443;
public static void main(String[] args) throws Exception {
HttpClient httpClient = new HttpClient();
httpClient.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
PostMethod post = new PostMethod("https://www.example.com/login.html");
post.setRequestHeader(new Header(
"User-Agent", "Mozilla/5.0 /Windows; U; Windows NT 4.1; de; rv:1.9.1.5) Gecko/20091102 Firefox/3.0"));
post.addParameter("login", "true");
post.addParameter("username", "xxx");
post.addParameter("password", "xxx");
post.addParameter("language", "de");
httpClient.executeMethod(post);
System.out.println(post.getResponseBodyAsString());
String body=post.getResponseBodyAsString();
//Get the session id by parsing the code, i know this is not pretty
String sessionid=body.substring(body.indexOf("session")+10,body.indexOf("session")+10+14);
System.out.print(sessionid);
GetMethod get=new GetMethod("https://www.example.com/thesiteyouwannabrowse?sessionid="+sessionid);
get.setRequestHeader(new Header(
"User-Agent", "Mozilla/5.0 /Windows; U; Windows NT 4.1; de; rv:1.9.1.5) Gecko/20091102 Firefox/3.0"));
httpClient.executeMethod(get);
System.out.println(get.getResponseBodyAsString());
//write it into a file
try{
// Create file
FileWriter fstream = new FileWriter("file.html");
BufferedWriter out = new BufferedWriter(fstream);
out.write(get.getResponseBodyAsString());
//Close the output stream
out.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
post.releaseConnection();
}
}
I myself have done similar things. I got it working using this "manual" approach, but it was quite a hassle, especially with the cookie management.
I would recommend you to have a look at Apache HttpClient library. (I threw away the code I had when I realized how easy it was to use this library.)
As org.life.java points out, here http://hc.apache.org/httpclient-3.x/sslguide.html is a good howto on how to get started with SSL using this library.

Categories

Resources