I have created and Android app that has to communicate with my website using JSON. JSON (on client, Android side) looks like this:
private static String JSONSend(Context ctx, JSONObject obj, String ObjName, String address) {
IHttpDispatcher disp = new HttpDispatcher();
Vector<String> ss = new Vector<String>();
String link = address;
String locale = uzmiLocale(ctx);
if(locale=="")
return "";
try {
obj.put("Lokal", locale);
ss.add(ObjName + obj.toString());
String ID = disp.getHttpResponse_POST(link, ss);
return ID;
} catch (Exception e) {
return "";
}
}
Above method is called from here:
public static String sendReq(Context ctx, String txt, String number) {
JSONObject jsn = new JSONObject();
try {
jsn.put("TextPoruke", txt);
jsn.put("BrTel", number);
return JSONSend(ctx, jsn, "JSNSend=", "www.mysite.com");
} catch (JSONException e1) {
return "";
}
}
Everything works fine on my Wamp server, but after moving my php code to webserver, nightmare started! Apparently, everything is sent the way it should be, but on serverside this php code is creating problems:
if(isset ($_POST['JSNSend']))
{
$argument = $_POST['JSNSend'];
$json = json_decode($argument,true);
$broj = $json['BrTel'];
$jsnLocale = $json['Lokal'];
it seems that result of "json_decode" is NULL, but $argument equals
{"\TextPoruke\": \"sometext\", \"BrTel\":\"111\"}
So passed JSON string seems ok, but for some reason it can't be decoded on webserver. Can anyone help me with this? Why is it not working?
Seems like your JSON got escaped prematurely which triggers a bad syntax error.
If $argument is in the format you state, then the following procedure would work:
<?php
$s = '{"\TextPoruke\": \"sometext\", \"BrTel\":\"111\"}';
echo 'Without stripslashes:' . PHP_EOL;
var_dump( json_decode( $s ) );
echo 'With stripslashes:' . PHP_EOL;
var_dump( json_decode( stripslashes($s) ) );
?>
Result:
Without stripslashes:
NULL
With stripslashes:
object(stdClass)#1 (2) {
["TextPoruke"]=>
string(8) "sometext"
["BrTel"]=>
string(3) "111"
}
Disable magic_quotes_gpc. This was a completely misguided ‘security’ feature that should never be used. It runs addslashes() on all user input, with the premise that this would solve SQL-injection problems (it doesn't).
If the server isn't yours and so you can't disable it, use the “Disabling magic quotes at runtime” hack on that link for now and consider moving to a new host.
Related
I have existing PHP that accepts arrays as parameters. This is currently being invoked from javascript and the javascript array is being set directly as part of the data object sent through AJAX call to the php.
Now, I want to send an array from an Android app and I don't want to change the existing php and javascript. I have looked for an answer, but don't see anything, other than the suggestion to encode the array as JSON and decode it in the php, but that will require lots of changes everywhere, including the javascript. It appears the javascript and the php are made to just work. Maybe something is done automatically to the array?
The PHP looks like this:
foreach($_POST as $key => $value) {
if (is_array($_POST[$key])){
for ($index = 0; $index < count($_POST[$key]); $index++){
if(ini_get('magic_quotes_gpc'))
$_POST[$key][$index] = stripslashes($_POST[$key][$index]);
$_POST[$key][$index] = htmlspecialchars(strip_tags($_POST[$key][$index]));
}
}
else {
if(ini_get('magic_quotes_gpc'))
$_POST[$key] = stripslashes($_POST[$key]);
$_POST[$key] = htmlspecialchars(strip_tags($_POST[$key]));
}
}
So, it is definitely expecting some parameters to be arrays.
The javascript currently does this:
$.ajax({
type: "POST",
url: 'php/getLibraryPatterns.php',
dataType: 'json',
data: data,
and data is a javascript object with arrays contained in it. For example:
var data = {};
if (sortBy.length > 0){
data.sortBy = sortBy;
}
and sortBy is an array in the javascript.
How do I pass an array from the Android app to this php? Currently, all of the parameters for my other calls to php have just been simple strings, so I use the following function to put all the parameters together in a string and then write that to the OutputStream of my HttpURLConnection. I have that all working, just not sure what to do with the arrays?
private String buildParameterString() throws UnsupportedEncodingException
{
if (m_parameterMap == null) return "";
StringBuilder result = new StringBuilder();
boolean first = true;
Iterator<Map.Entry<String, String>> itr = m_parameterMap.entrySet().iterator();
while(itr.hasNext())
{
Map.Entry<String, String> param = itr.next();
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(param.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(param.getValue(), "UTF-8"));
}
return result.toString();
}
I tried creating a JSONArray with the data, then convert to string and set it just like I would set the other strings I am sending. But, this does not appear to work, at least not automagically.
So, I am sending something like "[29]" or "['sortAsc']" as strings in the parameters.
I got back an empty list. I will continue to debug in the php to see what those look like there, but I expect they will be just strings and the php won't know what to do with that.
So, how can I send an array to the php? I don't want to have to change the php, as that means that the javascript then also has to change. Is there any way to do this from a java Android app?
Solution Found!
I found an answer in the JQuery documentation for ajax method. It says there that arrays are encoded like this:
%5B is '['
and %5D is ']'
For example, { a: [1,2] } becomes the string "a%5B%5D=1&a%5B%5D=2" with the default traditional: false setting.
I have encoded my arrays like that in the string that I write to the output stream. From https://api.jquery.com/jQuery.ajax/
Here is the code I am using to create my output stream:
private String buildParameterString() throws UnsupportedEncodingException
{
if (m_parameterMap == null || m_parameterMap.size() == 0) return "";
StringBuilder result = new StringBuilder();
for (int iPair = 0; iPair < m_parameterMap.size(); iPair++)
{
Pair<String, Object> param = m_parameterMap.get(iPair);
if (iPair > 0) result.append("&");
Object value = param.second;
if (value instanceof ArrayList){
for (int i = 0; i < ((ArrayList)value).size(); i++){
Object nextValue = ((ArrayList)value).get(i);
String nextValueStr = "";
if (nextValue instanceof String){
nextValueStr = (String)nextValue;
}
else {
nextValueStr = Integer.toString((Integer)nextValue);
}
if (i > 0) result.append("&");
result.append(URLEncoder.encode(param.first, "UTF-8"));
result.append("%5B%5D=");
result.append(URLEncoder.encode(nextValueStr, "UTF-8"));
}
}
else {
result.append(URLEncoder.encode(param.first, "UTF-8"));
result.append("=");
result.append(URLEncoder.encode((String)value, "UTF-8"));
}
}
return result.toString();
}
m_parameters is an ArrayList of Pair's where Pair is in android.util.
It works, this is the answer. You don't have to encode and decode in JSON string to do this. All the othere answers I have seen for this are just that. There is a way to encode the array into the string output.
Try this:
Outside of while loop:
JSONArray data = new JSONArray();
And put this in while loop:
JSONObject jsonObjSend = new JSONObject();
jsonObjSend.put(param.getKey(), param.getValue());
data.put(jsonObjSend);
From Android, send it as json data
public String convertMapToJson() {
Map<String, String> elements = new HashMap<>();
elements.put("Key1", "Value1");
elements.put("Key2", "Value2");
elements.put("Key3", "Value3");
JSONObject json = new JSONObject(elements);
return json.toString();
}
In server side PHP,
$json = file_get_contents('php://input');
// Converts it into a PHP object
$params = json_decode($json, true);
echo $params["Key1"];
I am trying to communicate to a php server from my gwt project.
I already got a GET request to work, however, my POST request doesn't work so far.
Here's my code:
Button synchronize = new Button("synchronize ",
new ClickHandler() {
public void onClick(ClickEvent event) {
String myurl = URL
.encode("php/test.php");
RequestBuilder builder = new RequestBuilder(
RequestBuilder.POST, myurl);
JSONObject jsonValue = new JSONObject();
jsonValue.put("name", new JSONString("Abc"));
builder.setHeader("Content-Type", "application/json");
try {
Request request = builder.sendRequest(jsonValue.toString(),
new RequestCallback() {
public void onError(Request request,
Throwable exception) {
processResponse("ERROR");
}
public void onResponseReceived(
Request request,
Response response) {
if (200 == response.getStatusCode()) {
processResponse(response
.getText());
} else {
processResponse("ERROR");
}
}
});
} catch (RequestException e) {
processResponse("ERROR");
}
}
});
public void processResponse(String responseString) {
Window.alert(responseString);
}
I can see that the post request goes out and the request payload is a json-object. However, when I try to access the data in the php script, I get the error that the index name is undefined.
Here's the PHP:
<?php
echo $_POST["name"];
?>
Is there something wrong with my PHP?
Does anyone have a working example for this?
While I haven't checked the PHP documentation so far, I tend to remember, that $POST contains the post request's variables, especially useful in a x-www-form-urlencoded request. .. Checked it, yes. I am right :-)
What you actually want is to read the body of the post request and parse it's JSON content to a PHP array or hash.
To read the body see here: How to get body of a POST in php?
$entityBody = file_get_contents('php://input');
Parsing json is described here: Parsing JSON file with PHP
I will not quote the code from there, as it maybe does not exactly fit your needs, but you look for json_decode($json, TRUE).
I would like to parse a string such as p1=6&p2=7&p3=8 into a NameValueCollection.
What is the most elegant way of doing this when you don't have access to the Page.Request object?
There's a built-in .NET utility for this: HttpUtility.ParseQueryString
// C#
NameValueCollection qscoll = HttpUtility.ParseQueryString(querystring);
' VB.NET
Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(querystring)
You may need to replace querystring with new Uri(fullUrl).Query.
HttpUtility.ParseQueryString will work as long as you are in a web app or don't mind including a dependency on System.Web. Another way to do this is:
NameValueCollection queryParameters = new NameValueCollection();
string[] querySegments = queryString.Split('&');
foreach(string segment in querySegments)
{
string[] parts = segment.Split('=');
if (parts.Length > 0)
{
string key = parts[0].Trim(new char[] { '?', ' ' });
string val = parts[1].Trim();
queryParameters.Add(key, val);
}
}
A lot of the answers are providing custom examples because of the accepted answer's dependency on System.Web. From the Microsoft.AspNet.WebApi.Client NuGet package there is a UriExtensions.ParseQueryString, method that can also be used:
var uri = new Uri("https://stackoverflow.com/a/22167748?p1=6&p2=7&p3=8");
NameValueCollection query = uri.ParseQueryString();
So if you want to avoid the System.Web dependency and don't want to roll your own, this is a good option.
I wanted to remove the dependency on System.Web so that I could parse the query string of a ClickOnce deployment, while having the prerequisites limited to the "Client-only Framework Subset".
I liked rp's answer. I added some additional logic.
public static NameValueCollection ParseQueryString(string s)
{
NameValueCollection nvc = new NameValueCollection();
// remove anything other than query string from url
if(s.Contains("?"))
{
s = s.Substring(s.IndexOf('?') + 1);
}
foreach (string vp in Regex.Split(s, "&"))
{
string[] singlePair = Regex.Split(vp, "=");
if (singlePair.Length == 2)
{
nvc.Add(singlePair[0], singlePair[1]);
}
else
{
// only one key with no value specified in query string
nvc.Add(singlePair[0], string.Empty);
}
}
return nvc;
}
To do this without System.Web, without writing it yourself, and without additional NuGet packages:
Add a reference to System.Net.Http.Formatting
Add using System.Net.Http;
Use this code:
new Uri(uri).ParseQueryString()
https://msdn.microsoft.com/en-us/library/system.net.http.uriextensions(v=vs.118).aspx
I needed a function that is a little more versatile than what was provided already when working with OLSC queries.
Values may contain multiple equal signs
Decode encoded characters in both name and value
Capable of running on Client Framework
Capable of running on Mobile Framework.
Here is my solution:
Public Shared Function ParseQueryString(ByVal uri As Uri) As System.Collections.Specialized.NameValueCollection
Dim result = New System.Collections.Specialized.NameValueCollection(4)
Dim query = uri.Query
If Not String.IsNullOrEmpty(query) Then
Dim pairs = query.Substring(1).Split("&"c)
For Each pair In pairs
Dim parts = pair.Split({"="c}, 2)
Dim name = System.Uri.UnescapeDataString(parts(0))
Dim value = If(parts.Length = 1, String.Empty,
System.Uri.UnescapeDataString(parts(1)))
result.Add(name, value)
Next
End If
Return result
End Function
It may not be a bad idea to tack <Extension()> on that too to add the capability to Uri itself.
If you don't want the System.Web dependency, just paste this source code from HttpUtility class.
I just whipped this together from the source code of Mono. It contains the HttpUtility and all it's dependencies (like IHtmlString, Helpers, HttpEncoder, HttpQSCollection).
Then use HttpUtility.ParseQueryString.
https://gist.github.com/bjorn-ali-goransson/b04a7c44808bb2de8cca3fc9a3762f9c
If you want to avoid the dependency on System.Web that is required to use HttpUtility.ParseQueryString, you could use the Uri extension method ParseQueryString found in System.Net.Http.
Make sure to add a reference (if you haven't already) to System.Net.Http in your project.
Note that you have to convert the response body to a valid Uri so that ParseQueryString (in System.Net.Http)works.
string body = "value1=randomvalue1&value2=randomValue2";
// "http://localhost/query?" is added to the string "body" in order to create a valid Uri.
string urlBody = "http://localhost/query?" + body;
NameValueCollection coll = new Uri(urlBody).ParseQueryString();
I just realized that Web API Client has a ParseQueryString extension method that works on a Uri and returns a HttpValueCollection:
var parameters = uri.ParseQueryString();
string foo = parameters["foo"];
private void button1_Click( object sender, EventArgs e )
{
string s = #"p1=6&p2=7&p3=8";
NameValueCollection nvc = new NameValueCollection();
foreach ( string vp in Regex.Split( s, "&" ) )
{
string[] singlePair = Regex.Split( vp, "=" );
if ( singlePair.Length == 2 )
{
nvc.Add( singlePair[ 0 ], singlePair[ 1 ] );
}
}
}
Just access Request.QueryString. AllKeys mentioned as another answer just gets you an array of keys.
HttpUtility.ParseQueryString(Request.Url.Query) return is HttpValueCollection (internal class). It inherits from NameValueCollection.
var qs = HttpUtility.ParseQueryString(Request.Url.Query);
qs.Remove("foo");
string url = "~/Default.aspx";
if (qs.Count > 0)
url = url + "?" + qs.ToString();
Response.Redirect(url);
Since everyone seems to be pasting his solution.. here's mine :-)
I needed this from within a class library without System.Web to fetch id parameters from stored hyperlinks.
Thought I'd share because I find this solution faster and better looking.
public static class Statics
public static Dictionary<string, string> QueryParse(string url)
{
Dictionary<string, string> qDict = new Dictionary<string, string>();
foreach (string qPair in url.Substring(url.IndexOf('?') + 1).Split('&'))
{
string[] qVal = qPair.Split('=');
qDict.Add(qVal[0], Uri.UnescapeDataString(qVal[1]));
}
return qDict;
}
public static string QueryGet(string url, string param)
{
var qDict = QueryParse(url);
return qDict[param];
}
}
Usage:
Statics.QueryGet(url, "id")
Hit up Request.QueryString.Keys for a NameValueCollection of all query string parameters.
To get all Querystring values try this:
Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(querystring)
Dim sb As New StringBuilder("<br />")
For Each s As String In qscoll.AllKeys
Response.Write(s & " - " & qscoll(s) & "<br />")
Next s
var q = Request.QueryString;
NameValueCollection qscoll = HttpUtility.ParseQueryString(q.ToString());
I translate to C# version of josh-brown in VB
private System.Collections.Specialized.NameValueCollection ParseQueryString(Uri uri)
{
var result = new System.Collections.Specialized.NameValueCollection(4);
var query = uri.Query;
if (!String.IsNullOrEmpty(query))
{
var pairs = query.Substring(1).Split("&".ToCharArray());
foreach (var pair in pairs)
{
var parts = pair.Split("=".ToCharArray(), 2);
var name = System.Uri.UnescapeDataString(parts[0]);
var value = (parts.Length == 1) ? String.Empty : System.Uri.UnescapeDataString(parts[1]);
result.Add(name, value);
}
}
return result;
}
let search = window.location.search;
console.log(search);
let qString = search.substring(1);
while(qString.indexOf("+") !== -1)
qString = qString.replace("+", "");
let qArray = qString.split("&");
let values = [];
for(let i = 0; i < qArray.length; i++){
let pos = qArray[i].search("=");
let keyVal = qArray[i].substring(0, pos);
let dataVal = qArray[i].substring(pos + 1);
dataVal = decodeURIComponent(dataVal);
values[keyVal] = dataVal;
}
This is my code, I think it's very useful:
public String GetQueryString(string ItemToRemoveOrInsert = null, string InsertValue = null )
{
System.Collections.Specialized.NameValueCollection filtered = new System.Collections.Specialized.NameValueCollection(Request.QueryString);
if (ItemToRemoveOrInsert != null)
{
filtered.Remove(ItemToRemoveOrInsert);
if (!string.IsNullOrWhiteSpace(InsertValue))
{
filtered.Add(ItemToRemoveOrInsert, InsertValue);
}
}
string StrQr = string.Join("&", filtered.AllKeys.Select(key => key + "=" + filtered[key]).ToArray());
if (!string.IsNullOrWhiteSpace(StrQr)){
StrQr="?" + StrQr;
}
return StrQr;
}
I have a url site.com/test.php which has the following code
<?php
$num1 = $_REQUEST['num1'] ;
$num2 = $_REQUEST['num2'] ;
$tot = $num1 + $num2 ;
?>
From an android application using POST/GET num1 and num2 parameters are passed to www.site.com/test.php
How can I make the response in such a way that the android application will be able to get the response from this request.
I tried this
header('Content-Type: application/json');
echo json_encode($response);
but all it does is echo it in the web view and im not able to get the response.Is there someway I can get the response as standard json response,which is not displayed but get it as soon as I hit the url as a response ?
** UPDATE **
#Override
public boolean shouldOverrideUrlLoading (WebView view, String url) {
if(flag) {
URL aURL = new URL(url);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
// read inputstream to get the json..
...
...
return true;
}
return false
}
#override
public void onPageFinished (WebView view, String url) {
if (url contains "form.html") {
flag = true;
}
}
this is the java code I got from SO , which Im planning to use in the android appication
Seems to be a problem in the handling of the response, not the generation of the JSON. Are you clicking a link to the JSON on a page that is has "form.html" in it? Because that is what seems to be assumed in the code you posted.
It seems to be better to just overload the shouldOverrideUrlLoading and check if the url matches your json page. Something like this:
#Override
public boolean shouldOverrideUrlLoading (WebView view, String url) {
if(url.toLowerCase().contains("www.site.com/test.php")) {
URL aURL = new URL(url);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
// read inputstream to get the json..
...
...
return true;
}
return false;
}
It might be a good idea to start an activity and load the JSON in that activity using, for example, an AsyncTask (network operations aren't allowed on the UI thread in the latest android APIs), instead of doing URL.openConnection immediately.
I’m working on a GWT web application that needs to communicate with a common web server. Unfortunately, the server only supports PHP, so I can’t use GWT RPC. That’s why I want to use a simple PHP script on server side, which returns all the necessary data in JSON format. Because I’m fairly new to GWT, my code is based on this example:
http://code.google.com/p/google-web-toolkit-doc-1-5/wiki/GettingStartedJSON
The PHP script seems to work fine. Firebug shows me the returned JSON data and the port 200:
Response:
[{"key1":"k1","value1":"v1"},{"key2":"k2","value2":"v2"},{"key2":"k3","value3":"v3]
However, the response is never processed further. Here is my code:
private static final String JSON_URL = "http://www.myUrl/myScript.php";
public HashMap<String, Integer> loadCalendarTable(String p1, String p2) {
table = new HashMap<String, Integer>();
String url = JSON_URL+"?p1="+p1+"&p2="+p2;
url = URL.encode(url);
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);
try {
Request request = builder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
Window.alert("Couldn't retrieve JSON");
}
public void onResponseReceived(Request request, Response response) {
if (200 == response.getStatusCode()) {
try {
// parse the response text into JSON
JSONValue jsonValue = JSONParser.parse(response.getText());
JSONArray jsonArray = jsonValue.isArray();
if (jsonArray != null) {
HashMap<String, Integer> hm = updateTable(jsonArray);
}
else
throw new JSONException();
}
catch (JSONException e) {
Window.alert("Could not parse JSON");
}
}
else
Window.alert("Couldn't retrieve JSON (" + response.getStatusText() + ")");
}
});
//(*)
}
catch (RequestException e) {
Window.alert("Couldn't retrieve JSON");
}
return table;
}
private HashMap<String, Integer> updateTable(JSONArray array) {
//do something
return table;}
By executing the application on the web server, there occurs no exception and no alert pops up. By using some alerts (which I omitted in the code above for readability), I noticed that the try-statement in new RequestBuilder() is executed. Another alert at (*) shows, that the try-statement is passed. (No exception occurs, as mentioned before). Obviously, the method onResponseReceived() is never executed. I never called this method, so this could be the reason for my problem. But then, I don’t understand where I should call onResponseReceived().
Remark:
I omitted my PHP script, because that’s actually the same as showed in the online example (http://code.google.com/p/google-web-toolkit-doc-1-5/wiki/GettingStartedJSON). Besides, the script seems to work properly.
How do you know that onResponseRecieved is not being executed? This should be called when your script.php returns JSON data. Assuming your server sends back a 200 status code, the response might be parsed, but no nothing is done with the data
try {
// parse the response text into JSON
JSONValue jsonValue = JSONParser.parse(response.getText());
JSONArray jsonArray = jsonValue.isArray();
if (jsonArray != null) {
HashMap<String, Integer> hm = updateTable(jsonArray);
// Now what? hm isn't actually used for anything...
} else {
throw new JSONException();
}
From the value returned at the end of the method, table is apparently important, but it will be returned, empty before the onResponseRecieved callback is ever invoked. This is because all GWT Ajax calls are asynchronous - the script won't stop running while waiting for the server to resume. Create an alert with response.getTest() in the if (jsonArray != null) block, and you may find that this code is getting called after all. If so, you've fallen victim to That's not async - it is considered generally good JavaScript practice (and all but mandatory in GWT) to wait for results to arrive when ready, and to keep executing as normal in the meantime.