I am currently using the following to read a file from android docs here and here. The user selects (in the settings screen) if their site uses HTTP or HTTPS protocol. If their website uses the HTTP protocol then it works for both HttpURLConnection and HttpsURLConnection, but if their site uses HTTPS protocol then it doesn't work for HttpURLConnection protocol and worst of all it doesn't give me an exception error. Below is the sample code that I am using.
So in essence, how can I check to see if the web url is HTTPS protocol so checking if the user selected the correct protocol?
InputStream inputStream;
HttpURLConnection urlConnection;
HttpsURLConnection urlHttpsConnection;
boolean httpYes, httpsYes;
try {
if (httpSelection.equals("http://")) {
URL url = new URL(weburi);
urlConnection = (HttpURLConnection) url.openConnection();
inputStream = new BufferedInputStream((urlConnection.getInputStream()));
httpYes = True;
}
if (httpSelection.equals("https://")) {
URL url = new URL(weburi);
urlHttpsConnection = (HttpsURLConnection) url.openConnection();
urlHttpsConnection.setSSLSocketFactory(context.getSocketFactory());
inputStream = urlHttpsConnection.getInputStream();
https=True;
}
catch (Exception e) {
//Toast Message displays and settings intent re-starts
}
finally {
readFile(in);
if(httpYes){
urlConnection.disconnect();
httpYes = False;
}
if(httpsYes){
urlHttpsConnection.disconnect();
httpsYes = False;
}
}
}
EDIT:
To elaborate some more. I need to see if it returns a valid response from a website? So if the user selected http instead of https how can I check to see if http is the incorrect prefix/protocol?
How can I check if the website uses HTTPS or HTTP protocol? If the user then only puts in say www.google.com and I append https:// or http:// prefix to it, how do I know which one is the correct one to use?
You can Use android URLUtil to check whether url is HTTP or HTTPS:
public static boolean isHttpUrl (String url)
Returns True iff the url is an http: url.
public static boolean isHttpsUrl (String url)
Returns True iff the url is an https: url.
Edit:
public static boolean isValidUrl (String url)
Returns True iff the url is valid.
URLConnection result = url.openConnection();
if (result instanceof HttpsURLConnection) {
// https
}
else if (result instanceof HttpURLConnection) {
// http
}
else {
// null or something bad happened
}
Try this code:
mConnexion = (URLUtil.isHttpsUrl(mStringUrl)) ? (HttpsURLConnection) url.openConnection() : (HttpURLConnection) url.openConnection();
I have checked URLUtil class and checked that its contain so many methods for these kind of stuff, but i just extend the answer that you can simply do as below also :-
public static boolean isHttpOrHttpsUrl(String url) {
return url.matches("^(http|https|ftp)://.*$");
}
This can be checked by using Util.
isHttpUrl returns True iff the url is an http: url.
isHttpsUrl returns True iff the url is an https: url.
you can try this
boolean httpYes, httpsYes;
try {
URL url = new URL(weburi);
urlConnection = (HttpURLConnection) url.openConnection();
inputStream = new BufferedInputStream((urlConnection.getInputStream()));
httpYes = True;
}
catch (Exception e) {
//Toast Message displays and settings intent re-starts
URL url = new URL(weburi);
urlHttpsConnection = (HttpsURLConnection) url.openConnection();
urlHttpsConnection.setSSLSocketFactory(context.getSocketFactory());
inputStream = urlHttpsConnection.getInputStream();
https=True;
}
I think this works, at least it seems to be working, what do you guys think? I place this if statement just before the httpsYes = True and httpYes = True.
It seems that when the HTTPS protocol is selected it wants to redirect using response code 302, but for all other instances it connects with response code 200. I throw a new ConnectionException() error as that takes the user back to the settings screen to correct the URL error.
For the HTTPS protocol:
if (httpsURLConnection.getResponseCode() != 200) {
throw new ConnectException();
}
For the HTTP protocol:
if (urlConnection.getResponseCode() != 200) {
throw new ConnectException();
}
Comments? Should I use urlConnection.getResponseCode() > 199 && < 300? To cover all successful connects?
My recommendation is created function expression regular.
for example:
public void testUrl(Object urlHttp){
String url = "https://www.google.com";
if(url.matches("^(https?)://.*$")){
Object o = (HttpsURLConnection) urlHttp;
}else{
Object o = (HttpURLConnection) urlHttp;
}
}
Regards
Related
I try to use HttpURLConnection to send a post request to my local (xampp) server with an url like this http://xxx.xxx.0.3/Company/index.php/booking/c200/p-205/2025-02-09 8:2 , the server php file take param in url and send data to mysql database .
The url works fine on postman agent , and even another get method request works smooth in the android application .
Yet when i try the post method with following code :
public void postOrder() {
TextView tv = findViewById(R.id.tv1);
Thread t = new Thread( new Runnable() {
#Override
public void run() {
HttpURLConnection conn = null;
try {
String link = "http://xxx.xxx.0.3/Company/index.php/booking/c200/p-205/2025-02-09 8:2";
URL url = new URL(link);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setReadTimeout(10000 /*ms*/);
conn.setConnectTimeout(15000 /*ms*/);
conn.connect();
}
catch (IOException e) {
Log.d("HTTP error: ", e.toString());
}
finally {
conn.disconnect();
}
}
} );
t.start();
}
It never sent the url and thus no data is stored to database .
And with 6 hours of trial and error , google and searching , i added this line of code :
InputStream is = conn.getInputStream();
And it finally works .
Please answer me why it only works after adding this line of code , what does it do ? I thought the url is triggered right after conn.connect();
Calling connect() only connects, but it doesn't send anything yet. Call getResponseCode() to force the request to be sent. That method is safer than getInputStream() which will throw an exception if the response is not a 2xx (in which case you'd need getErrorStream()).
Is there an alternative way to updating a listitem without using the PATCH method or the base SDKs (since i'm doing through a HTTP client).
public Boolean updateItem(Item i) {
if(i.getId() != null) {
String URL = "https://graph.microsoft.com/v1.0/sites/"+siteId+"/lists/"+listId+"/items/"+i.getId()+"";
try {
URL url = new URL(URL);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("PATCH");
http.addRequestProperty("Accept", "application/json;odata.metadata=none");
http.addRequestProperty("Content-Type", "application/json");
http.setRequestProperty("Authorization", "Bearer "+getAuth());
http.setDoOutput(true);
http.setDoInput(true);
send(http.getOutputStream(), i.toJson());
http.connect();
if(http.getResponseCode() == 200) {
String content = read(http.getInputStream());
System.out.println(content);
return true;
}else {
String errorContent = read(http.getErrorStream());
System.out.println("UPDATE ITEM ERROR:"+errorContent);
}
}catch(IOException e) {
System.out.println("UPDATE ITEM (IOException):"+e.getMessage());
}
}
return false;
}
The getAuth() returns a valid access token.
I have attempted this:
http.setRequestProperty("X-HTTP-Method-Override", "PATCH");
However Microsoft seems to only recognise it as POST
Solved. I used Apaches HTTP Client to do the patch method (org.apache.http.client.methods.*).
I'm doing an Android app with an API with Python. The API is on a Google App Engine cloud and everything works fine when I tested it with Postman.
I'm trying to do a Login with a POST method. That method returns json with the user information I keep getting that error: FileNotFoundException
Here is some of my code:
try{
String account = params[0].get(0);
String password = params[0].get(1);
URL url = new URL("http", WEB_SERVICE_URL, PORT, REST_LOGIN);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setConnectTimeout(CONNECTION_TIMEOUT);
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setRequestProperty("Content-Type", "application/json");
httpURLConnection.setRequestProperty("Accept", "application/json");
JSONObject json = jsonParser.serialJsonLogin(nomCompte, motPasse);
osw = new OutputStreamWriter(httpURLConnection.getOutputStream(),"UTF-8");
osw.write(json.toString());
osw.flush();
String body = readStream(httpURLConnection.getInputStream());
osw.close();
Log.i(TAG, "Return : " + body);
user = jsonParser.deserializeJsonUser(body);
}catch (Exception e) {
mException = e;
}finally {
if (mHttpURLConnection != null) {
mHttpURLConnection.disconnect();
}
}
return user;
At: String body = readStream(httpURLConnection.getInputStream()); I'm getting a java.io.FileNotFoundException: http://10.0.2.2:8080/login
My readStream method is fine, I tested it. If I look in my Google App Engine logs, I can see that there is no 404, or anything wrong. If I find the user I get a 201 if not a 403. So even if the error says FileNotFound, I see status code which means that actually the URL is right.
UPDATE: My API was giving me a 201 and getInputStream apparently doesn't work on 201 status. Changed my return status to 200 in my API and it works fine.
Whenever I try to hit a url using java it will redirect me to login page. How can I first login then hit a specific url to get JSON in return ?
Here what I tried so far:
try {
URL url = new URL(GET_EXPENSE_FOR_VENDOR_URL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String response;
System.out.println("Output from Server .... \n");
while ((response = br.readLine()) != null) {
System.out.println(response);
Gson gson = new Gson();
gson.fromJson(response, ExpenseAllocationDTO[].class);
Type collectionType = new TypeToken<Collection<ExpenseAllocationDTO>>() {
}.getType();
expenseAllocationList = gson.fromJson(response, collectionType);
expenseAllocationDTODataModel = (new ExpenseAllocationDTODataModel(expenseAllocationList));
if (expenseAllocationList.isEmpty() || expenseAllocationList == null) {
expenseExists = true;
}
conn.disconnect();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
The problem
I believe the initial request is missing some headers. Only the Accept header is set.
How to solve it ?
Option #1
In order to discover the missing headers, open your favorite browser and browse to GET_EXPENSE_FOR_VENDOR_URL. Before browsing, open the webdeveloper toolbar in order to see headers sent by the browser.
Here is a sample screenshot of the webdeveloper toolbar under Chrome on Windows.
.
Option #2
If your browser doesn't have such a toolbar, you can use a tool like Fiddler for finding the missing headers.
Option #3
You can also use a tool like hurl.it in order to test the headers expected by the target server as you discover them. IMO, this tool can be more straight forward than Fiddler during the debugging phase.
Get back to your code
Once you have identified the missing headers, add them to your Java code like this:
URL url = new URL(GET_EXPENSE_FOR_VENDOR_URL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("Missing-Header-1", "...");
conn.setRequestProperty("Missing-Header-2", "...");
I'm trying to establish a Connection via HTTPS. I also set the "Authorization" property in the Request Header to Basic and provide an encoded auth string accordingly.
I checked with the Firefox Plugin HttpRequester and everythign works fine, which means I entered the url, choose "GET" as request method, add the Authorization to the header and after pressing submit I get back some xml which only a properly authorized user should get.
Unfortunately I can neither provide you with the actual auth info nor the real url in the SSCCE. However, I can tell you, that the Auth seems to work, since I get a 200 response. I also changed the Auth to a wrong value and get a "401 Authorization Required" response then.
It actually seems like the "?myparam=xyz" is somehow cut off, because when I remove this parameter from the url and test with Firefox HttpRequester again I get the same response as in Java.
Unfortunately I have no access to "theirdomain.com", so I don't know what's happending on the server side. But since it works with the Firefox HttpRequester, it should also work with Java.
What could be the reason? Thanks for your help!
EDIT:
I changed the url to "https://www.google.com/search?q=foo" and commented this line:
//con.setRequestProperty("Authorization", auth);
I can see from the returned string, that google received the "foo". So apparently the combination of Authorization and get parameter seems to be the problem, since both separately work fine.
SSCCE:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
public class HttpRequest
{
/**
* #param args
*/
public static void main(final String[] args)
{
System.out.println("start request");
final String urlString = "https://theirdomain.com/foo/bar/bob?myparam=xyz";
final String auth = "Basic XyzxYzxYZxYzxyzXYzxY==";
HttpsURLConnection con;
try
{
final URL url = new URL(urlString);
con = (HttpsURLConnection) url.openConnection();
con.setRequestProperty("Authorization", auth);
con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0");
con.setRequestMethod("GET");
// con.setDoOutput(true);
con.connect();
final int responseCode = con.getResponseCode();
if (responseCode != 200)
System.out.println("Server responded with code " + responseCode + " " + con.getResponseMessage());
else
{
System.out.println("Starting to read...");
final InputStream inStream = con.getInputStream();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
int c;
while (inStream != null && (c = inStream.read()) != -1)
{
baos.write(c);
}
System.out.println(new String(baos.toByteArray()));
}
}
catch (final IOException e)
{
System.out.println("could not open an HTTP connection to url: " + urlString);
e.printStackTrace();
}
finally
{
System.out.println("end request");
}
}
}
Have you tried adding
con.setRequestProperty("myparam", "xyz"); to your code?