This question already has answers here:
Checking if a URL exists or not
(4 answers)
Closed 6 years ago.
How can I check in Java if a file exists on a remote server (served by HTTP), having its URL? I don't want to download the file, just check its existence.
import java.net.*;
import java.io.*;
public static boolean exists(String URLName){
try {
HttpURLConnection.setFollowRedirects(false);
// note : you may also need
// HttpURLConnection.setInstanceFollowRedirects(false)
HttpURLConnection con =
(HttpURLConnection) new URL(URLName).openConnection();
con.setRequestMethod("HEAD");
return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
}
catch (Exception e) {
e.printStackTrace();
return false;
}
}
If the connection to a URL (made with HttpURLConnection) returns with HTTP status code 200 then the file exists.
EDIT: Note that since we only care it exists or not there is no need to request the entire document. We can just request the header using the HTTP HEAD request method to check if it exists.
Source: http://www.rgagnon.com/javadetails/java-0059.html
public static boolean exists(String URLName){
try {
HttpURLConnection.setFollowRedirects(false);
// note : you may also need
// HttpURLConnection.setInstanceFollowRedirects(false)
HttpURLConnection con =
(HttpURLConnection) new URL(URLName).openConnection();
con.setRequestMethod("HEAD");
return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
}
catch (Exception e) {
e.printStackTrace();
return false;
}
}
Checking if a URL exists or not
Check this, it works for me. Source URL: Check if URL exists or not on Server
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String customURL = "http://www.desicomments.com/dc3/08/273858/273858.jpg";
MyTask task = new MyTask();
task.execute(customURL);
}
private class MyTask extends AsyncTask<String, Void, Boolean> {
#Override
protected void onPreExecute() {
}
#Override
protected Boolean doInBackground(String... params) {
try {
HttpURLConnection.setFollowRedirects(false);
HttpURLConnection con = (HttpURLConnection) new URL(params[0]).openConnection();
con.setRequestMethod("HEAD");
System.out.println(con.getResponseCode());
return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
}
catch (Exception e) {
e.printStackTrace();
return false;
}
}
#Override
protected void onPostExecute(Boolean result) {
boolean bResponse = result;
if (bResponse==true)
{
Toast.makeText(MainActivity.this, "File exists!", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(MainActivity.this, "File does not exist!", Toast.LENGTH_SHORT).show();
}
}
}
}
Assuming the file is being served through http, you can send a HEAD request to the URL and check the http response code returned.
The only true way is to download it :). On some servers usually you can get away by issuing a HEAD request insted of a GET request for the same url. This will return you only the resource metadata and not the actual file content.
Update: Check org.life.java's answer for the actual technical details on how to do this.
Make a URLConnection to it. If you succeed, it exists. You may have to go so far as opening an input stream to it, but you don't have to read the contents. You can immediately close the stream.
Related
My question is how I can check the availability of an URL:
My code
public boolean URLvalide(){
String URL_CHECK = "testurl";
try {
URL url = new URL(URL_CHECK);
URLConnection con = url.openConnection();
con.connect();
return true;
} catch (MalformedURLException e) {
return false;
} catch (IOException e) {
return false;
}
}
It returns false every time
The following code use the core Java implementation for checking if a link is accessible. It should be adaptable to Android. Remember that the URL should be completed, i.e. with scheme, host name, otherwise an exception is thrown.
public boolean checkURL () {
try {
URL myUrl = new URL("http://www.google.com");
HttpURLConnection connection = (HttpURLConnection) myUrl.openConnection();
connection.connect();
int statusCode = connection.getResponseCode();
if (statusCode == HttpURLConnection.HTTP_OK) {
System.out.println("Accessible");
} else {
System.out.println("Not-Accessible");
}
} catch (Exception e) {
System.out.println("not-accessible");
}
}
Updated:
In Android, the above method may fail due to two reasons.
The URL you are targeting is of http protocol instead of https. In this case you need to allow clear text traffic in your application manifest.
<application>
...
android:usesCleartextTraffic="true"
2.You might be running the check url code in your main thread. Android prevent accessing network request in main thread. To solve this put your code in an AsyncTask or in a separate thread. The following code is just for illustration.
Thread backgroundThread = new Thread(new Runnable() {
#Override
public void run() {
checkURL();
}
});
backgroundThread.start();
I've class with methods
class Wrapper {
public static String AuthIn(String Login, String Password){
String response = HTTPRequest.POST(client, GetAuthUrl(), RequestBuilder.AuthInVk(login, password));
System.out.println(response);
}
public static String GetInfoUser(){
String response = HTTPRequest.GET(client, "http://site1.com");
System.out.println(response);
}
}
When i call this methods in MainActivity class and get error message "Main thread ..... etc"
How write Wrapper class in AsyncTask ?
Here is a nice example taken from codexpedia, for more details please check their site.
public class MainActivity extends AppCompatActivity {
TextView tvWeatherJson;
Button btnFetchWeather;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvWeatherJson = (TextView) findViewById(R.id.tv_weather_json);
btnFetchWeather = (Button) findViewById(R.id.btn_fetch_weather);
btnFetchWeather.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new FetchWeatherData().execute();
}
});
}
private class FetchWeatherData extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
// These two need to be declared outside the try/catch
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String forecastJsonStr = null;
try {
// Construct the URL for the OpenWeatherMap query
// Possible parameters are avaiable at OWM's forecast API page, at
// http://openweathermap.org/API#forecast
URL url = new URL("http://api.openweathermap.org/data/2.5/forecast/daily?q=94043&mode=json&units=metric&cnt=7&appid=2de143494c0b295cca9337e1e96b00e0");
// Create the request to OpenWeatherMap, and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
forecastJsonStr = buffer.toString();
return forecastJsonStr;
} catch (IOException e) {
Log.e("PlaceholderFragment", "Error ", e);
// If the code didn't successfully get the weather data, there's no point in attemping
// to parse it.
return null;
} finally{
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("PlaceholderFragment", "Error closing stream", e);
}
}
}
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
tvWeatherJson.setText(s);
Log.i("json", s);
}
}
}
If you want to pass data into the async task doInBackground or onPostExcute and more check this stackoverflow comment : what-arguments-are-passed-into-asynctaskarg1-arg2-arg3
Keep in mind that your AsyncTask won't stop even when the activity has destroyed. A better way to create a network call from an activity is with an Handler Or just use an asyncHttp client lib such as ok-http , google volley :)
You always must perform network request form other thread than UI thread. So you can create abstarct class (network dispatcher) which extend AsyncTask or Thread or Runnable and add abstarct method which will be called in run/doInBackground/etc. Next implement abstarct method in your method. But it a little improvement to your boilerplate code. Also you can use JavaRx (AndroidRx) to perform networking method. Also you can use Retrofit with JavaRx.
EDIT
I see you edit your question. If you want use AsyncTask you should implement it and perform request in doInBackgroud
I want to start programming Android apps that can communicate with a server to receive/send data and store it on the server.
I have been reading about this and I think I only need to send the data to the server with POST request (perhaps a XML file since I may need to send images), then parse the XML on the server side, and do whatever I need.
To start I'm just trying to send some text through my app.
This is my Post class, for the AsyncTask use:
public class Post extends AsyncTask<String, Void, Boolean> {
Context context;
String response;
public Post (Context ctx){
context = ctx;
}
#Override
protected Boolean doInBackground(String... params) {
URL url;
HttpURLConnection conn;
try {
url = new URL("http://192.168.1.40/index.php");
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(5000);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "text/xml; charset=\"utf-8\"");
conn.setDoInput(true);
conn.setDoOutput(false);
conn.connect();
String body = "<test>\"some testing\"</test>";
//Send POST
OutputStreamWriter output = new OutputStreamWriter(conn.getOutputStream(),"UTF8");
output.write(body);
output.flush();
output.close();
//Get response
String line = "";
InputStream is = conn.getInputStream();
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) sb.append(line);
response = sb.toString();
br.close();
is.close();
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public String getResponse(String s)
{
}
Using a button to send the request:
public class MainActivity extends ActionBarActivity {
Context ctx;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ctx = this;
Button b = new Button(this);
b.setText("Send POST");
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Post p = new Post(ctx);
p.execute();
while(p.getStatus() != AsyncTask.Status.FINISHED);
Toast.makeText(ctx,p.getResponse(),Toast.LENGTH_LONG).show();
}
});
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
params.topMargin = 0;
params.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
addContentView(b,params);
}
And this is my server side php code:
<?php print_r($_POST);?>
I know there are a lot of posts about this stuff, I went through many of them but I can't figure out this problem.
The HttpURLConnection response code is 200 which means HTTP_OK.
In the index.php page the only output is: "Array ()".
When I debug, the response string is also "Array ()", the problem is that the status of the AsyncTask is "RUNNING" all the time.
P.S - I'm using wampserver as webserver
Thanks in advance.
EDIT: I followed Pawel advice and tried this before the Toast:
while(p.getStatus() != AsyncTask.Status.FINISHED);
The app crashed, so I guess it never gets the FINISHED status.
Also tried the AsyncTask.get() method, like this:
try {
Toast.makeText(ctx, p.get().toString(), Toast.LENGTH_LONG).show();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
Got a "false" in the Toast text wich means my p.doInBackground() completed the execution. Why do I still don't have any results?
LAST EDIT: I'm not giving up yet! After a lot of debugging and frustration I think I have found the problem. It was the PHP code! I was expecting it to show me in the browser the post request but It does not work that way apparently.
I changed it to this:
<?php file_put_contents('test.txt', file_get_contents('php://input')); ?>
Now I can see the file with the content.
My only problem with this is that if I remove the code to read the response from the server, it does not create the file. Is there something wrong or it's just normal behavior?
You should read this:
http://developer.android.com/reference/android/os/AsyncTask.html
You know that Post is Asynchronous operation since it extends AsyncTask ? Which means that it can be completed after your invoke Toast.makeText(ctx,p.getResponse(),Toast.LENGTH_LONG).show();
Small hint:
Check in above linked documentation about methods:
public final Result get () and public final AsyncTask.Status getStatus ().
Now you should have your results availabe when it is done.
I am new in android, i have searched for solution, but i could not get the suitable one, that s why i am
posting this Qn,
I can't get any value in servlet,And no Errors in LogCat, Some Toast are in my code to check execution flow, The all Toast will work only in the first attempt, If i click my button second time, Only the first Toast will work,
Please help me to find a solution,
This is my android code
public void onClick(View v) {
final String u=txt_name.getText().toString();
final String p=txt_pswd.getText().toString();
Toast.makeText(getApplicationContext(), u+p,Toast.LENGTH_LONG).show();
new AsyncTask<String , Void, Void>() {
#Override
protected Void doInBackground(String... params) {
try{
//Log.d("Asynctask", ""+params);
//Looper.prepare();
URL url=new URL("http://10.0.2.2:8080/LoginExample/LoginServlet");
HttpURLConnection urlConnection=(HttpURLConnection)url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("GET");
//Toast.makeText(getApplicationContext(), "connecting..",Toast.LENGTH_LONG).show();
urlConnection.connect();
//Toast.makeText(getApplicationContext(), "connected",Toast.LENGTH_LONG).show();
urlConnection.getOutputStream().write(("key1="+u+"&key2="+p).getBytes());
//Toast.makeText(getApplicationContext(), "sending....",Toast.LENGTH_LONG).show();
}catch(Exception e)
{
System.out.println("ERROR IN URL CONNECTION---"+e);
}
//Looper.loop();
return null;
}
}.execute();
});
And this is my servlet,
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, java.io.IOException {
try
{
System.out.println("-----servlet--------------");
// UserBean user = new UserBean();
String uname=request.getParameter("key1");
String password=request.getParameter("key2");
System.out.println("uname ins ervlet==="+uname);
System.out.println("password in servlet==="+password);
}
catch (Throwable theException)
{
System.out.println(theException);
}
}
}
AsyncTask is not written correctly. There is NO NEED to write Looper in doINBAckground. In ideal cases,doInBackground don't deal with UI elements. Remove Toasts statement too. Use Log class to print log.
You request part seems wrong. If its get tye request try
URL url=new URL("http://10.0.2.2:8080/LoginExample/LoginServlet?"+"key1="+u+"&key2="+p);
Also check Internet permission in your manifest file.
Provide Stacktrace of your error.
This is my solution,
public void onClick(View v) {
final String u=txt_name.getText().toString();
final String p=txt_pswd.getText().toString();
Toast.makeText(getApplicationContext(), u+p,Toast.LENGTH_LONG).show();
new AsyncTask<String , Void, Void>() {
#Override
protected Void doInBackground(String... params) {
try{
URL url=new URL("http://10.0.2.2:8080/LoginExample/LoginServlet?"+"key1="+u+"&key2="+p);
HttpURLConnection urlConnection=(HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
BufferedReader br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String result = br.readLine();
Log.d("MainActivity", result);
}catch(Exception e)
{
e.printStackTrace();
System.out.println("ERROR IN URL CONNECTION---"+e);
}
// Looper.loop();
return null;
}
}.execute();
}
After being confused about how to do so (as can be seen here and here, I am now successfully connecting to my server app and the appropriate RESTful method with this code:
public void onFetchBtnClicked(View v){
if(v.getId() == R.id.FetchBtn){
Toast.makeText(getApplicationContext(), "You mashed the button, dude.", Toast.LENGTH_SHORT).show();
new CallAPI().execute("http://10.0.2.2:28642/api/Departments/GetCount?serialNum=4242");
}
}
public static class CallAPI extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
String urlString=params[0]; // URL to call
String resultToDisplay = "";
InputStream in = null;
// HTTP Get
try {
URL url = new URL(urlString);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream());
} catch (Exception e ) {
System.out.println(e.getMessage());
return e.getMessage();
}
return resultToDisplay;
}
protected void onPostExecute(String result) {
Log.i("FromOnPostExecute", result);
}
} // end CallAPI
I realize I need to assign something (other than an empty string at initialization) to resultToDisplay, but what? What part of "in" do I need to access/covert to a string?
UPDATE
The "manual" way is working for me, but the fancypants apache io utils "not so much" (well, it compiles...). This is my code:
try {
URL url = new URL(urlString);
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream());
resultToDisplay = getStringFromInputStream(in);
total = IOUtils.toString(in);
resultToDisplay's assignment works (I get, "18"). total's assignment does not (I get, "").
Note: The "getStringFromInputStream()" method is from Raghunandan's link.
UPDATE 2
This works just dandy (using WIllJBD's idea to use apache commons' IOUtils):
new CallWebAPI().execute("http://10.0.2.2:28642/api/Departments/GetCount?serialNum=4242");
. . .
private class CallWebAPI extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
String urlString=params[0]; // URL to call
String result = "";
// HTTP Get
try {
URL url = new URL(urlString);
HttpURLConnection urlConnection =
(HttpURLConnection)url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
if (null != inputStream)
result= IOUtils.toString(inputStream);
} catch (Exception e ) {
System.out.println(e.getMessage());
return e.getMessage();
}
return result;
}
#Override
protected void onPostExecute(String result) {
Log.i("RenameTheWashingtonFootballTeamTheRedskinPeanuts", result);
}
}
...and so apparently it is not necessary to add anything like "compile files('libs/commons-io-2.4.jar')" to the dependencies section of build.gradle, as seemingly was at least necessary at one time, according to this. If anybody can verify such a[m,pp]endments to build.gradle are no longer needed, I'd be gradleful.
UPDATE 4
I just noticed that I inadvertently removed the "#Override" from the onPostExecute() method, but it made no difference - it worked fine without it, and it works fine once I restored it. So what's the advantage of [not] having it - is it just superfluous fluff?
why not use something like IOUtils?
InputStream inputStream = urlConnection.getInputStream();
if (inputStream != null)
String content = IOUtils.toString(inputStream);
http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/IOUtils.html
now you can parse the string into Json or XML, using one of many libraries.