using Get request with URLConnection - java

I am currently writing program to communicate with a device in my network, and the following code is what I have so far, it passed authentication and can get the webpage from the device, however i couldnt get the GET request to work, when I run the code below, i get the error:
Exception in thread "main" java.io.FileNotFoundException: http://192.168.100.222:80
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
when I input data on the webpage, its equivalent of going http://l192.168.xxx.xxx/2?A=3&p=1&X=1234, and from tcpflow, it does GET /2?A=4&p=1&X=1234 HTTP/1.1,
I tried creating a new url connection with http://192.168.xxx.xxx/2?A=3&p=1&X=1234, and it worked, but i have multiple input options and i dont want to create a new connection for each of them, how can I do the equivalent while staying connected? or what I did wrong in the code?
thanks in advance.
public class main {
public static void main(String[] argv) throws Exception {
Authenticator.setDefault(new MyAuthenticator());
URL url = new URL("http://192.168.xxx.xxx");
URLConnection connection = url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write("Get /2?A=4&p=1&X=1234 HTTP1.1");
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String decodedString;
while ((decodedString = in.readLine()) != null) {
System.out.println(decodedString);
}
in.close();
}

I don't want to create a new connection for each of them
Don't worry about that. HttpURLConnection does connection pooling under the hood. Just use your actual URLs, don't try to out-think Java.

Related

Read from URL if content is image [duplicate]

I am trying to write a java program that will automatically download and name some of my favorite web comics. Since I will be requesting multiple objects from the same domain, I wanted to have a persistent http connection that I could keep open until all the comics have been downloaded. Below is my work-in-progress. How do I make another request from the same domain but different path without opening a new http connection?
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class ComicDownloader
{
public static void main(String[] args)
{
URL url = null;
HttpURLConnection httpc = null;
BufferedReader input = null;
try
{
url = new URL("http://www.cad-comic.com/cad/archive/2002");
httpc = (HttpURLConnection) url.openConnection();
input = new BufferedReader(new InputStreamReader(httpc.getInputStream()));
String inputLine;
while ((inputLine = input.readLine()) != null)
{
System.out.println(inputLine);
}
input.close();
httpc.disconnect();
}
catch (IOException ex)
{
System.out.println(ex);
}
}
}
According to the documentation here, HTTP persistence is being handled transparently in Java, although it gives you the options to control it too via http.keepAlive and http.maxConnections system properties.
However,
The current implementation doesn't
buffer the response body. Which means
that the application has to finish
reading the response body or call
close() to abandon the rest of the
response body, in order for that
connection to be reused. Furthermore,
current implementation will not try
block-reading when cleaning up the
connection, meaning if the whole
response body is not available, the
connection will not be reused.
Take a look at the link and see if it really helps you.
According to this link http://docs.oracle.com/javase/6/docs/technotes/guides/net/http-keepalive.html, HTTP connection reuse is enabled by default, you can use Wireshark to check the interactions between your client and server. The first request contains TCP and SSL handshakes(if your request is https), the subsequent requests fired in the keep-alive time, contains no TCP and SSL handshakes, just application data transfers.
Even though HttpURLConnection enable keep-alive by default, it is not guaranteed that HttpURLConnection uses same TCP connection for multiple HTTP requests. I faced same kind of issue when writing HTTPS client application. Solved this issue by using single instance of SSLContext, SSLSocketFactory and HttpsURLConnection.
public class MyHTTPClient {
private SSLContext mSSLContext = null;
private SSLSocketFactory mSSLSocketFactory = null;
private HttpsURLConnection mConnection = null;
public void init() {
//Setup SSL context and Socket factory here
}
pubblic void sendRequest() {
URL url = new URL("https://example.com/request_receiver");
mConnection = (HttpsURLConnection) url.openConnection();
mConnection.setSSLSocketFactory(mSSLSocketFactory);
// Setup request property and send request
// Open input stream to read response
// Close output, input streams
mConnection.disconnect();
}
}

theMovieDB api call throwing IOEXception

I am making an android app that uses theMovieDB API.
Look at the part of my class extending AsyncTask.
private HttpURLConnection urlconnection = null;
private URL url;
protected String doInBackground(String[] task)
{
String DATA=null;
String baseAddress="https://api.themoviedb.org/3/movie/";
String apiKey="225b36fd29826b4c9821dd90bfc4e055";
Uri Url = Uri.parse(baseAddress).buildUpon().appendEncodedPath(task[0]).appendQueryParameter("api_key",apiKey).build();
Log.d("built URL",Url.toString());
try
{
url= new URL(Url.toString());
urlconnection= (HttpURLConnection) url.openConnection();
urlconnection.setRequestMethod("GET");
urlconnection.connect();
InputStream inputStream = urlconnection.getInputStream();
if (inputStream==null)
{
return null;
}
BufferedReader reader= new BufferedReader(new InputStreamReader(inputStream));
StringBuffer buffer=null;
String line;
while ((line=reader.readLine())!=null)
{
buffer.append(line+'\n');
}
DATA=buffer.toString();
}
I am getting IOException (seen in logcat). I checked the built URL on the browser(it was working). The Same set of syntax did work on openweather api. Is there any other thing that themovieDb API need? Help me Solve it. I did check there documentation but there was no info for android.
i got the Solution. I was connected to my mobile hotspot which due to some reason does not work as expected. Switching to my home WIFI fixed the issue.
Thanks for giving your time on my question

Is it really necessary to use url.openConnection()?

As we all know both these codes will yield the same result
public class MainApp {
public static void main(String[] args) throws IOException {
URL google = new URL("http://www.google.com");
google.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(google.openStream()));
reader.lines().forEach(System.out::println);
}
}
and
public class MainApp {
public static void main(String[] args) throws IOException {
URL google = new URL("http://www.google.com");
BufferedReader reader = new BufferedReader(new InputStreamReader(google.openStream()));
reader.lines().forEach(System.out::println);
}
}
So what's the point in using google.openConnection()?
May be javadoc for this method helps:
public java.net.URLConnection openConnection() throws java.io.IOException
Returns a URLConnection instance that represents a connection to the remote object referred to by the URL. A new instance
of URLConnection is created every time when invoking the
URLStreamHandler.openConnection(URL) method of the protocol handler
for this URL.
It should be noted that a URLConnection instance does not establish
the actual network connection on creation. This will happen only when
calling URLConnection.connect().
If for the URL's protocol (such as HTTP or JAR), there exists a
public, specialized URLConnection subclass belonging to one of the
following packages or one of their subpackages: java.lang, java.io,
java.util, java.net, the connection returned will be of that subclass.
For example, for HTTP an HttpURLConnection will be returned, and for
JAR a JarURLConnection will be returned.
Use this if you want to add some specific connectivity properties to your connection.
For example:
URLConnection urlConnection = google.openConnection();
urlConnection.setReadTimeout(1000);
urlConnection.setConnectTimeout(1000);
Since the code for openStream() is:
public final InputStream openStream() throws java.io.IOException {
return openConnection().getInputStream();
}
It seems quite redundant indeed.
But if I were you, if I openConnection()d, I would then get the InputStream on the returned URLConnection.
openConnection() does not modify the URL object, it returns a URLConnection instance that you could then use. The code in the question ignores the return value of openConnection(), so, in this case, it's indeed pointless. it would only be useful if you actually do something with this connection object, such as, e.g., modifying its timeout:
URL google = new URL("http://www.google.com");
URLConnection conn = google.openConnection();
conn.setTimeout(7); // just an example
BufferedReader reader =
new BufferedReader(new InputStreamReader(conn.getInputStream()));
reader.lines().forEach(System.out::println);

Getting HTTP audio and then playing it back in android

I have a API that takes a string and converts in into audio when I do a HTTP get in android. I want to be able to play it back when I recieve it but I don't know how to do this. Can someone help me. Here is my code so far:
public static String getHTML(String urlToRead) throws Exception {
StringBuilder result = new StringBuilder();
URL url = new URL(urlToRead);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");

pinnaclesports api basic auth with java

When trying to get account balance used api I got an exception:
IOException: Server returned HTTP response code: 401 for URL:
https://api.pinnaclesports.com/v1/client/balance
Here's the code:
public void getBalance() throws Exception{
byte[] bytes = "username:password".getBytes("UTF-8");
String encoded = Base64.encodeBase64String(bytes);
System.out.println(encoded);
URL api = new URL("https://api.pinnaclesports.com/v1/client/balance");
URLConnection apiConnection = api.openConnection();
apiConnection.addRequestProperty("Authorization", "Basic "+encoded);
BufferedReader in = new BufferedReader(new InputStreamReader(apiConnection.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
I think your authentication is broken or not set properly. The API uses Basic Auth and a Base64 encoded username/password pair. You should read http://www.pinnaclesports.com/en/api/manual#authentication and make sure that your authorization is correct.
Here's an explanation for HTTP status code 401:
Similar to 403 Forbidden, but specifically for use when authentication
is possible but has failed or not yet been provided. The response
must include a WWW-Authenticate header field containing a challenge
applicable to the requested resource.
Try using an Authenticator, like this:
Authenticator.setDefault(new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("username", "password".toCharArray());
}
});
URL api = new URL("https://api.pinnaclesports.com/v1/client/balance");
BufferedReader in = new BufferedReader(new InputStreamReader(api.openStream()));
Or if that doesn't work, then try using an HttpURLConnection instead of URLConnection,
like this:
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty ("Authorization", "Basic " + encoded);
You might also find this related post helpful, using Apache Commons.

Categories