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!
Related
Im trying to send a post to a backend API from android and this is what I have but some special characters relating to application/x-www-form-urlencoded content type wont be sent or cause problems. Im wondering if there is a way to send the special characters in this format? (+,&) I'm attempting to send the message "This is a message + a test" but my database is getting "This is a message a test"
I've tried passing JSON but the backend that my co-students wrote doesn't accept JSON and returns a 401 not authorized error.
public void sendMessage() {
if(!mEdit.getText().toString().trim().matches("")) { //Cant send empty strings
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
URL url = new URL(Sendurl); //Create URL
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //Create a Connector
conn.setRequestMethod("POST"); //Dictate the Method
conn.setRequestProperty("Content-Type", "application/json; utf-8"); //Some other properties
conn.setRequestProperty("Accept", "application/json");
conn.setDoOutput(true);
conn.setDoInput(true);
//This part causes a 401 error because it is the equivalent of passing parameters but our backend uses body formatting
JSONObject jsonParam = new JSONObject();
Date date = new Date();
RequestParams params = new RequestParams();
params.put("username", "admin");
params.put("sessionID", 1);
params.put("cardNum", 111111111);
params.put("sentByStaff", "false");
params.put("message", "This is the message + a test");
params.put("time", date.getTime()/1000);
Log.i("JSON", params.toString());
// OutputStreamWriter os = new OutputStreamWriter(conn.getOutputStream()); //Prepare the connection for output
POST_PARAMS = params.toString(); //Converts post parameters to body type
System.out.println(POST_PARAMS);
try(OutputStream os = conn.getOutputStream()) {
byte[] input = POST_PARAMS.getBytes("utf-8");
os.write(input, 0, input.length);
os.flush();
os.close();
}
//os.write(POST_PARAMS); //Write our parameters to the post
//os.flush(); //Do the thing
//os.close();
Log.i("STATUS", String.valueOf(conn.getResponseCode())); //Debug
Log.i("MSG", conn.getResponseMessage()); //Debug
int responseCode = 0; //get response code
responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) { //On success
mEdit.setText("");
}
conn.disconnect(); //disconnect after attempting post
getMessage(); //update our messages
} catch (Exception e) { //dirty catch all
e.printStackTrace();
}
}
});
thread.start();
}
}
I'm a QA with desire to learn more about Java programming and problem I'm experiencing is this:
I'm trying to POST Employee data to the database of some fake Rest API, but I'm getting
Cannot write to a URLConnection if doOutput=false - call
setDoOutput(true)"
So far, I tried some ideas from StackOverflow, but inexperienced as I am, I could easily fall deeper into a problem.
So URL is: http://dummy.restapiexample.com/api/v1/create and firstly I created an Employee class of json object:
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
Employees em = new Employees();
em.setEmployeeName("Alex");
em.setEmployeeSalary("1234");
em.setEmployeeAge("28");
try{
URL url = new URL("http://dummy.restapiexample.com/api/v1/create");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Unsuccessful call: HTTP error : "
+ conn.getResponseCode());
}
// URLConnection urlc = url.openConnection();
// urlc.setDoOutput(true);
PrintWriter pw = new PrintWriter(conn.getOutputStream());
pw.print(new Gson().toJson(em));
pw.close();
pw.flush();
BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream())
);
String json = "";
String output;
while ((output = br.readLine()) != null) {
json += output;
}
conn.disconnect();
System.out.println("Employee name: " + em.getEmployeeName());
}
catch (MalformedURLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
Well, using one of your ideas and added next lines of code (it's commented in above code):
URLConnection urlc = url.openConnection();
urlc.setDoOutput(true);
So the code looks like:
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
Employees em = new Employees();
em.setEmployeeName("Alex");
em.setEmployeeSalary("1234");
em.setEmployeeAge("28");
try{
URL url = new URL("http://dummy.restapiexample.com/api/v1/create");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Unsuccessful call: HTTP error : "
+ conn.getResponseCode());
}
URLConnection urlc = url.openConnection();
urlc.setDoOutput(true);
PrintWriter pw = new PrintWriter(urlc.getOutputStream());
pw.print(new Gson().toJson(em));
pw.close();
pw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(
(urlc.getInputStream())));
String json = "";
String output;
while ((output = br.readLine()) != null) {
json += output;
}
conn.disconnect();
System.out.println("Employee name: " + em.getEmployeeName());
}
catch (MalformedURLException e) {
e.printStackTrace(); }
catch (IOException e) {
e.printStackTrace();
}
}}
With this second code I'm not getting that error, but there is no inserting to the database(checking that using postman, with GET method)...
Well, what am I missing? I guess, I'm missing something basic...
Using url.openConnection twice means you get two different connections. You send the request to the second connection, and try to read the response from the first connection. You should call doOutput on the connection you open originally.
The second problem is you're calling getResponseCode before the request is sent. In http, the request must be sent entirely before the server sends a response. You should move the code that calls doOutput and writes the request body before the code that tries to check the response code.
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.
I've always been told you should zip the data to be more efficient. On the input size, this is relatively easy, as shown below:
HttpURLConnection urlConnection=(HttpURLConnection) new URL(url).openConnection();
urlConnection.setRequestProperty("Accept-Encoding", "gzip");
InputStream instream=urlConnection.getInputStream();
Map<String, List<String>> headers = urlConnection.getHeaderFields();
List<String> contentEncodings=headers.get("Content-Encoding");
boolean hasGzipHeader=false;
if (contentEncodings!=null) {
for (String header:contentEncodings) {
if (header.equalsIgnoreCase("gzip")) {
hasGzipHeader=true;
break;
}
}
}
if (hasGzipHeader) {
instream = new GZIPInputStream(instream);
}
The output side seems a tad bit trickier. I've found how to just send a general Post statement output, as follows:
HttpsURLConnection conn = (HttpsURLConnection) url
.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Accept-Encoding", "gzip");
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
OutputStream os = conn.getOutputStream();
os.write(getQuery(results).getBytes(Charset.forName("UTF8")));
private String getQuery(List<BasicNameValuePair> params)
throws UnsupportedEncodingException {
StringBuilder result = new StringBuilder();
boolean first = true;
for (BasicNameValuePair pair : params) {
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(pair.getName(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(pair.getValue(), "UTF-8"));
}
return result.toString();
}
But I can't figure out how to get the output stream gziped, if it's even possible. I can't figure out how to tell if the server will accept the connection, and how to tell the server that the data is zipped. It's easy enough to send the data encoded, as follows:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzipStream = new GZIPOutputStream(baos);
gzipStream.write(getQuery(results).getBytes(
Charset.forName("UTF8")));
os.write(baos.toByteArray());
Yes, for input (download) the Android implementation of HttpURLConnection does gunzip transparently. But for output (upload) this is not done automatically. The client cannot know whether server supports compression. So you have to do it manually and you have to be sure that your servers understand the request.
You can find an example at DavidWebb.
The code to gzip the payload:
static byte[] gzip(byte[] input) {
GZIPOutputStream gzipOS = null;
try {
ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
gzipOS = new GZIPOutputStream(byteArrayOS);
gzipOS.write(input);
gzipOS.flush();
gzipOS.close();
gzipOS = null;
return byteArrayOS.toByteArray();
} catch (Exception e) {
throw new WebbException(e); // <-- just a RuntimeException
} finally {
if (gzipOS != null) {
try { gzipOS.close(); } catch (Exception ignored) {}
}
}
}
And you have to set the following header:
connection.setRequestProperty("Content-Encoding", "gzip");
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;
}
}