I tried to download XML by using the code below:
#Override
protected String doInBackground(String... params) {
try {
URL url = new URL("http://xx.xx.xx.xx/1.xml");
URLConnection ucon = url.openConnection();
ucon.setRequestProperty("Accept", "application/xml");
InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte) current);
}
String str = new String(baf.toByteArray(), "UTF8");
return str;
} catch (MalformedURLException e) {
Log.e(DEBUG_TAG, "6",e);
} catch (IOException e) {
Log.e(DEBUG_TAG, "7",e);
}
return "error";
}
and I am getting the error:
12-12 08:12:15.434: ERROR/myLogs(10977): java.io.FileNotFoundException: http://xx.xx.xx.xx/1.xml
If I open this url in browser is see:
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Home>
<Child sex="male" age="5" name="Vasya"/>
<pets>
<Dog age="3" name="Druzshok"/>
</pets>
</Home>
I guess your server intercept some request .
for example :
check [User-Agent] in headers.
ucon.setRequestProperty("Accept", "application/xml"); remove the line..
You are wondering why the java URL object throws a file not found? It means the server responded to your request with a "404 not found" or for whatever reason no response was given by the server.
So you are wondering why that when you visit it in the browser it works fine, because the browser is treated differently by the server than your script. First try setting the user-agent to be the same as your browser. Servers are cracking down on robots more and more these days because of impolite script writers banging on their websites.
Source:
java.io.FileNotFoundException for valid URL
maybe server filter ['User-Agent'].
code:
#Override
protected String doInBackground(String... params) {
try {
URL url = new URL("http://xx.xx.xx.xx/1.xml");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(false);
conn.setUseCaches(false);
conn.setReadTimeout(60 * 1000);
conn.setConnectTimeout(30*1000);
conn.setRequestProperty("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:39.0) Gecko/20100101 Firefox/39.0");
BufferedReader reader = new java.io.BufferedReader(new java.io.InputStreamReader(conn.getInputStream(),"UTF-8"));
StringBuilder buf = new StringBuilder(512);
String line = null;
while((line=reader.readLine())!=null){
buf.append(line).append("\n");
}
conn.disconnect();
return buf.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Related
I am trying to send json string from my android app to my php server. Below is the complete code from my mobiledb_control.php and httpconnect.java
The Log.v("HTTPSENDER","WORKED"); runs, and I get no errors.
However my error_log("in"); does not run.
How do I display the JSON sent via android into my error_log() ?
HttpConnect.java:
public class HttpConnect {
public HttpConnect(){
}
public void sendData(String jsonObject){
try{
URL url = new URL("http://www.alextanti.net/PHPDashboard/Backend/mobiledb_control.php");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(),"UTF-8"));
output.write("json="+jsonObject);
output.flush();
output.close();
Log.v("HTTPSENDER","WORKED");
}catch(Exception e){
e.printStackTrace();
}
}
}
mobiledb_control.php:
<?php
ini_set('display_errors', 1);
ini_set('log_errors', 1);
ini_set("error_log", "../Logs/error.log");
error_reporting(E_ALL);
if(!empty($_POST['json'])){
echo(var_dump($_POST['json']));
error_log($_POST['json']);
}
$headers = apache_request_headers();
?>
try this in PHP code
and turn on error reporting like this
// Report all PHP errors (see changelog)
error_reporting(E_ALL);
and
print_r($_POST);
for more clarification what you are getting from post.
use encode and decode functions of php for making and parsing json.
$request=json_decode($_POST['json']); // it gives the Array
foreach($request as $values){
echo($values['your_value1'])
echo($values['your_value2'])
}
please refer this url : http://php.net/manual/en/function.json-decode.php
Seemed to have fixed it but I have no idea how
PHP File:
<?php
ini_set('display_errors', 1);
ini_set('log_errors', 1);
ini_set("error_log", "../Logs/location.log");
error_reporting(E_ALL);
if(!empty($_POST['json'])){
echo(var_dump($_POST['json']));
error_log($_POST['json']);
}
?>
JAVA File:
public class HttpConnect {
public HttpConnect(){
}
public void sendData(String jsonObject){
try{
URL url = new URL("http://www.alextanti.net/PHPDashboard/Backend/mobiledb_control.php");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(),"UTF-8"));
output.write("json="+jsonObject);
output.flush();
output.close();
Log.v("HTTPSENDER","WORKED");
Log.v("HTTPSENDER",""+conn.getResponseCode());
}catch(Exception e){
e.printStackTrace();
}
}
}
In designing server-client communication, it is imperative to make sure both client and server can communicate with each other. With that in mind, can you please provide the server response code by adding this in your code inside try block:
try {
...
Log.d(TAG, "code: " + conn.getReturnCode());
InputStream is = conn.getInputStream();
String serverReply = readIt(is, 500);
Log.d(TAG, serverReply);
...
}
public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
Reader reader = null;
reader = new InputStreamReader(stream, "UTF-8");
char[] buffer = new char[len];
reader.read(buffer);
return new String(buffer);
}
It will return 200 and 401 respectively. Returns -1 if no code can be
discerned from the response (i.e., the response is not valid HTTP).
Cheers!
I am using restheart to provide a restful interface to mongodb. The interface is set up and running and provides the correct answer if a GET request is sent through Chrome. However if I use the following java code using a HttpURLConnection I get a 201 response with no content.
try {
videos = new URL("http://www.example.com:8080/myflix/videos");
} catch (Exception et) {
System.out.println("Videos URL is broken");
return null;
}
HttpURLConnection hc = null;
try {
hc = (HttpURLConnection) videos.openConnection();
String login="admin:admin";
final byte[] authBytes = login.getBytes(StandardCharsets.UTF_8);
final String encoded = Base64.getEncoder().encodeToString(authBytes);
hc.addRequestProperty("Authorization", "Basic "+encoded);
hc.setDoInput(true);
hc.setDoOutput(true);
hc.setUseCaches(false);
hc.setRequestMethod("GET");
hc.setRequestProperty("Accept-Encoding", "gzip, deflate, sdch");
hc.setRequestProperty("Content-Type", "application/json");
hc.setRequestProperty("Accept", "application/json,text/html,application/hal+json,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*");
} catch (Exception et) {
System.out.println("Can't prepare http URL con");
return (null);
}
BufferedReader br = null;
try {
OutputStreamWriter writer = new OutputStreamWriter(
hc.getOutputStream());
} catch (Exception et) {
System.out.println("Can't get reader to videos stream");
}
String inputLine;
String sJSON = null;
try {
int rc = hc.getResponseCode();
What is the correct way to authenticate using Java to the resthert interface? (Details on the restheart authentication is here Restheart authentication
I made few changes (look for inline comments starting with <==) and it works:
The way you generate the authentication request header is correct. When I run your code I actually got 415 Unsupported Media Type, that went away commenting out hc.setDoOutput(true). A GET is a input operation, in fact you were also trying to get an OutStream from the connection: you need to get an InputStream actually.
URL url;
try {
url = new URL("http://127.0.0.1:8080/test/huge");
} catch (Exception et) {
System.out.println("Videos URL is broken");
Assert.fail(et.getMessage());
return;
}
HttpURLConnection hc = null;
try {
hc = (HttpURLConnection) url.openConnection();
String login = "admin:admin";
final byte[] authBytes = login.getBytes(StandardCharsets.UTF_8);
final String encoded = Base64.getEncoder().encodeToString(authBytes);
hc.addRequestProperty("Authorization", "Basic " + encoded);
System.out.println("Authorization: " + hc.getRequestProperty("Authorization"));
hc.setDoInput(true);
//hc.setDoOutput(true); <== removed, otherwise 415 unsupported media type
hc.setUseCaches(false);
hc.setRequestMethod("GET");
hc.setRequestProperty("Accept-Encoding", "gzip, deflate, sdch");
hc.setRequestProperty("Accept", "application/json,text/html,application/hal+json,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*");
} catch (Exception et) {
System.out.println("Can't prepare http URL con");
}
System.out.println(hc.toString());
BufferedReader br = null;
try {
InputStreamReader reader = new InputStreamReader(hc.getInputStream()); // <== the request is a GET, data is in input
} catch (Exception et) {
System.out.println("Can't get reader to videos stream");
}
int rc = hc.getResponseCode();
System.out.println("response code: " + rc);
System.out.println("response message: " + hc.getResponseMessage());
Assert.assertEquals(200, rc);
My android servlet is designed to post request and receive responses with a tomcat servlet on an Apache Tomcat server. For debugging, I have set up the Servlet with identical POST and GET methods so I can try the functionalities and accessability via browsers.
To cut the long story short: When I deploy the app, I can easily access it from the AVD device browser via 10.0.2.2:8080/my_app?request=test and I get a result that's just fine. Same is true for access from my machine with localhost:8080/my_app?request=test.
But when I try it from my app, I always get a java.io.FileNotFoundException: http://10.0.2.2:8080/my_app.
Why?
What did I try so far: The app has internet permissions and they also work, for to get to the Servlet communication point, I have to go through a login procedure via PHP first, and it's on the same server and works normally.
My AsyncTaskconnecting to the servlet looks like this:
AsyncTask<Void,Void,String> getDBdata = new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
URL url = null;
try {
url = new URL("http://10.0.2.2:8080/my_app");
} catch (MalformedURLException e) {
e.printStackTrace();
}
String text;
text = null;
JsonArray js = null;
try {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("action", "getDBData");
connection.setDoInput(true);
connection.connect();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder builder = new StringBuilder();
String aux = "";
while ((aux = in.readLine()) != null) {
builder.append(aux);
}
text = builder.toString();
} catch (IOException e) {
e.printStackTrace();
}
return text;
Alright, of course I've been trying to send params in the header, and this led to BS. Rookie mistake!
bcody's answer from this question helped me a lot with debugging! Also, taking a look at the server protocol from the servlet might have led me to the error earlier.
This is the code that finally worked:
AsyncTask<Void,Void,String> getDBdata = new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
URL url = null;
try {
url = new URL(Constants.SERVER_URL + getDBdataURL);
} catch (MalformedURLException e) {
e.printStackTrace();
}
String text;
text = null;
try {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setRequestProperty("User-Agent", "Mozilla/5.0 ( compatible ) ");
connection.setRequestProperty("Accept", "*/*");
connection.setChunkedStreamingMode(0);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setDoOutput(true);
connection.setRequestMethod("POST");
String request = "action=getDBdata";
PrintWriter pw = new PrintWriter(connection.getOutputStream());
pw.print(request);
pw.close();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder builder = new StringBuilder();
String aux = "";
while ((aux = in.readLine()) != null) {
builder.append(aux);
}
text = builder.toString();
} catch (IOException e) {
e.printStackTrace();
}
return text;
}
Ok so I'm working on an app with 2 activities.
Let's call the 1st one LoginActivity which appears on top of my MainActivity. Also, I have a class SenderReceiver which extends AsyncTask that takes care of the connection to my https server.
The 1st time I call SenderReceiver from my LoginActivity, everything works fine & I get a 200 response & I'm able to use the JSON retrieved.
After that, the LoginActivity finishes & returns a result to the MainActivity. This is when I know I'm logged in & I can proceed.
Now whenever I execute SenderReceiver to get other information, I get the 403 response with a java.io.FileNotFoundException: https://url_of_my_server. But if I call the login again, it works.
Below is the SenderReceiver code snippet which connects to the server.
I'm also connecting to the same server on the iOS version of the app & never have issues with subsequent calls after the login.
Now this is my 1st time using https connections & such, I'm not really sure how it works on Android so I must be missing something or doing something wrong.
#Override
protected Boolean doInBackground(Object... params) {
frag = (Fragment)params[0]; // For later
addedParams = (List<NameValuePair>)params[1];
postPage = (String)params[2];
InputStream is = null;
try {
URL url = new URL(Constants.kWebService);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setReadTimeout(15000);
conn.setConnectTimeout(20000);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
//conn.setDoInput(true);
conn.setRequestProperty("CONTENT_TYPE", "application/json");
conn.setRequestProperty("X-requested-with", "XMLHttpRequest");
String base64EncodedCredentials = "Basic " + Base64.encodeToString((Constants.kHTTPSUser+":"+Constants.kHTTPSPass).getBytes(), Base64.NO_WRAP);
conn.setRequestProperty("Authorization", base64EncodedCredentials);
String param = "page="+postPage+"&";
for(int i = 0; i < addedParams.size(); i++) {
String and = (i < addedParams.size()-1)? "&": "";
param += addedParams.get(i).getName()+"="+ URLEncoder.encode(addedParams.get(i).getValue(), "UTF-8")+and;
}
conn.setFixedLengthStreamingMode(param.getBytes().length);
PrintWriter out = new PrintWriter(conn.getOutputStream());
out.print(param);
out.close();
// Starts the query
conn.connect();
int responseCode = conn.getResponseCode();
is = conn.getInputStream();
// Convert the InputStream into a string
responseSTR = Constants.inputStreamToString(is).toString();
return true;
// Makes sure that the InputStream is closed after the app is
// finished using it.
} catch (ProtocolException pe) {
Constants.Log("Protocol Exception:"+pe.getMessage());
} catch (IOException io) {
Constants.Log("IO Exception:"+io.getMessage());
io.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException io) {
Constants.Log("is.close IO Exception:"+io.getMessage());
}
}
}
return false;
}
Fixed it!
All I had to do was to set the cookie header with:
conn.setRequestProperty("Cookie", Constants.kCookies);
& retrieve that cookie after the response in order to set it with:
List<String> cookies = conn.getHeaderFields().get("Set-Cookie");
if(cookies != null) {
Constants.kCookies = cookies.get(0);
}
That way in the initial HttpURLConnection connections (i.e:login) the cookie is empty & not needed. Once a connection is successful (after "login") it receives the cookie & sets it.
After that, any subsequent connection sends that cookie as part of the header.
The updated method below:
#Override
protected Boolean doInBackground(Object... params) {
frag = (Fragment)params[0];
addedParams = (List<NameValuePair>)params[1];
postPage = (String)params[2];
InputStream is = null;
try {
URL url = new URL(Constants.kWebService);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setReadTimeout(15000);
conn.setConnectTimeout(20000);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
//conn.setDoInput(true);
conn.setRequestProperty("CONTENT_TYPE", "application/json");
conn.setRequestProperty("X-requested-with", "XMLHttpRequest");
String base64EncodedCredentials = "Basic " + Base64.encodeToString((Constants.kHTTPSUser+":"+Constants.kHTTPSPass).getBytes(), Base64.NO_WRAP);
conn.setRequestProperty("Authorization", base64EncodedCredentials);
// Get the cookie from my Constants file & set it, Constants.kCookies is a static String
conn.setRequestProperty("Cookie", Constants.kCookies);
String param = "page="+postPage+"&";
for(int i = 0; i < addedParams.size(); i++) {
String and = (i < addedParams.size()-1)? "&": "";
param += addedParams.get(i).getName()+"="+ URLEncoder.encode(addedParams.get(i).getValue(), "UTF-8")+and;
}
conn.setFixedLengthStreamingMode(param.getBytes().length);
PrintWriter out = new PrintWriter(conn.getOutputStream());
out.print(param);
out.close();
// Starts the query
conn.connect();
int responseCode = conn.getResponseCode();
Constants.Log("The response code is: " + responseCode);
is = conn.getInputStream();
// Retrieve the cookie from the response & if not null save it to Constants.kCookies
List<String> cookies = conn.getHeaderFields().get("Set-Cookie");
if(cookies != null) {
Constants.kCookies = cookies.get(0);
}
// Convert the InputStream into a string
responseSTR = Constants.inputStreamToString(is).toString();//readIt(is, len);
return true;
// Makes sure that the InputStream is closed after the app is
// finished using it.
} catch (ProtocolException pe) {
Constants.Log("Protocol Exception:"+pe.getMessage());
} catch (IOException io) {
Constants.Log("IO Exception:"+io.getMessage());
io.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException io) {
Constants.Log("is.close IO Exception:"+io.getMessage());
}
}
}
return false;
}
In my java application I used a Httpsurlconnection to post some string data to the server. When I test this code on android, it works perfectly. However, in a java application it does not work. Client java application is as follows:
public static void main(String[] args) {
disableSslVerification();
new HttpsClient().testIt();
}
private void testIt() {
String https_url = "https://XXX.XX.XXX.XXX:XXXX/XXXXX/TestServlet";
URL url;
try {
url = new URL(https_url);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
print_content(con, "test");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void print_content(HttpsURLConnection connection, String data) {
if (connection != null) {
try {
connection.setConnectTimeout(6000);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
Charset cSet = Charset.forName("UTF-8");
byte bytes[] = data.getBytes(cSet);
connection.setRequestProperty("Content-Length", ""
+ Integer.toString(bytes.length));
connection.setRequestProperty("Content-Language", "tr");
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(
connection.getOutputStream());
wr.write(bytes);
wr.flush();
wr.close();
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is, cSet));
String line;
StringBuilder response = new StringBuilder();
while ((line = rd.readLine()) != null) {
response.append(line);
response.append(System.getProperty("line.separator"));
}
rd.close();
System.out.println(response.toString());
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}
And the servlet is as follows:
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String s = getHTML(request);
try {
out.print("received data:");
out.print(s);
} finally {
out.close();
}
}
private String getHTML(HttpServletRequest request) throws IOException {
int n = request.getContentLength();
if (n < 1) {
return "";
}
byte bytes[] = new byte[n];
request.getInputStream().read(bytes);
return new String(bytes, "UTF-8");
}
When I run this application, servlet's response is:
received data:tâââ
Always only the first character is correctly send to the servlet. The same code works perfect on android. Can anyone help me please? Thanks...
I can't see an obvious problem with your code that would cause this.
Can anyone help me please?
I suggest that you take a methodical approach to investigating the problem. Use a packet sniffer to check what is actually being sent over the wire. Check that the actual headers in the request and response are correct. Check that the request and response bodies are really properly encoded UTF-8 ...
What you find in your investigation / evidence gathering will help you figure out where the problem (or problems) are occurring ... and that will allow you to home in on the part(s) of your code that is/are responsible.
request.getInputStream().read(bytes);
You might need to do this read in a loop. At the very least, check how many bytes have been read. The array appears to be empty except for the first char.
Reads some number of bytes from the input stream and stores them into
the buffer array b. The number of bytes actually read is returned as
an integer. This method blocks until input data is available, end of
file is detected, or an exception is thrown.