I am a student studying Volley request.
There's an error that I can't solve, so I'm asking you to find a solution.
I don't understand why can't POST from Android to PHP at all.
It worked well in other situations, but not only in JsonArrayRequest.
I'll attach the code, so if there's any problem with my code, please let me know.
This is string request code in Android Studio
package kr.ac.castcommunity.cc.request
import android.util.Log
import com.android.volley.Request
import com.android.volley.Response
import com.android.volley.Response.success
import com.android.volley.toolbox.JsonArrayRequest
import com.android.volley.toolbox.StringRequest
import java.util.HashMap
import org.json.JSONObject
import com.android.volley.toolbox.JsonObjectRequest
import org.json.JSONArray
class CommentRequest(boardid : String , listener: Response.Listener<JSONArray>) :
JsonArrayRequest(Request.Method.POST, URL, JSONArray(), listener, Response.ErrorListener { error ->
Log.d("COMMENT ERROR", "Server Response FAIL: $error")
}) {
private val parameters: MutableMap<String, String>
companion object {
private val URL = "http://MyIP/cc/commentlist.php"
}
init {
parameters = HashMap()
parameters["boardid"] = boardid
Log.d("boardID :",boardid)
}
override fun getParams(): Map<String, String> {
return parameters
}
}
This is PHP code
(It works well if I randomly assign a variable.)
(But it doesn't work when I interlock it.)
<?php
$con = mysqli_connect("localhost", "root", "root", "cc");
mysqli_query($con, 'SET NAMES utf8');
$boardid = $_POST["boardid"]; // but It's not operating
//$boardid = "1"; // It's operating
$boardid = (int)$boardid;
$statement = mysqli_prepare($con, "select * from comment where boardid = ?");
mysqli_stmt_bind_param($statement, "i", $boardid);
mysqli_stmt_execute($statement);
mysqli_stmt_store_result($statement);
mysqli_stmt_bind_result($statement, $commentid, $boardid, $content, $writer, $date);
$response = array();
$response["success"] = false;
$result = array();
while(mysqli_stmt_fetch($statement)){
$response["success"] = true;
$response["commentid"] = $commentid;
$response["boardid"] = $boardid;
$response["content"] = $content;
$response["writer"] = $writer;
$response["date"] = substr($date,10,-3);
array_push($result, array(
"success"=>$response["success"],
"commentid" => $response["commentid"],
"boardid" => $response["boardid"],
"content" => $response["content"],
"writer" => $response["writer"],
"date" => $response["date"]));
}
echo json_encode($result);
?>
D/COMMENT ERROR: Server Response Fail: com.android.volley.ParseError: org.json.JSONException: Value <br of type java.lang.String cannot be converted to JSONArray
and response code
val boardid = intent.getIntExtra("bnum", 0)
mCommentRecyclerView = comment_recyclerView
val responseListener = Response.Listener<JSONArray> { response ->
try {
Log.d("response", "comment response Start")
for (i in 0 until response.length()) {
val jobject = response.getJSONObject(i)
val success = jobject.getBoolean("success")
val boardid = jobject.getInt("boardid")
val commentid = jobject.getInt("commentid")
val content = jobject.getString("content")
val date = jobject.getString("date")
val writer = jobject.getString("writer")
if (success == true) {
mDatas.add(Comment(boardid, commentid, content, date, writer))
} else {
return#Listener
}
}
mAdpater = CommentAdapter(this, mDatas)
mCommentRecyclerView!!.adapter = mAdpater
mCommentRecyclerView!!.addItemDecoration(BoardDecoration(20))
val lm = LinearLayoutManager(this)
lm.reverseLayout = true
lm.stackFromEnd = true
mCommentRecyclerView!!.layoutManager = lm
mCommentRecyclerView!!.setHasFixedSize(true)
val decoration = DividerItemDecoration(this, LinearLayoutManager.VERTICAL)
mCommentRecyclerView!!.addItemDecoration(decoration)
} catch (e: JSONException) {
e.printStackTrace()
}
}
val commentRequest = CommentRequest(boardid.toString(), responseListener)
val queue = Volley.newRequestQueue(this#DetailActivity)
queue.add(commentRequest)
I really don't know why. I need your help.
Through your error message. I think there is a problem with the conversion of String to JsonObject.
You can print out the response from the server first, and then print out the conversion parameters.
I think the error appears in the for loop code below. Please check if the error is caused by the <br> tag.
Log.d("response", "comment response Start")
for (i in 0 until response.length()) {
val jobject = response.getJSONObject(i)
val success = jobject.getBoolean("success")
val boardid = jobject.getInt("boardid")
val commentid = jobject.getInt("commentid")
val content = jobject.getString("content")
val date = jobject.getString("date")
val writer = jobject.getString("writer")
println(jobject)
println(success)
println(boardid)
println(commentid)
println(content)
println(date)
println(writer)
if (success == true) {
mDatas.add(Comment(boardid, commentid, content, date, writer))
} else {
return#Listener
}
}
Related
Hello as i am new to flutter, i want to fetch data from php api to flutter app with json data which have multiple data's in one file
my flutter code
Future<Album> fetchAlbum() async {
final response = await http.post(
Uri.parse('https://domain/folder/api.php'),
body: jsonEncode({
"description": 'description',
"naw": "homeprod",
}),
);
if (response.statusCode == 200) {
// If the server did return a 201 CREATED response,
// then parse the JSON.
return Album.fromJson(jsonDecode(response.body));
} else {
// If the server did not return a 201 CREATED response,
// then throw an exception.
throw Exception('Failed to create.');
}
}
class Album {
//final int productid;
String description;
Album({this.description = ""});
factory Album.fromJson(Map<String, dynamic> json) {
return Album(
//productid: json['product_id'],
description: json['description'],
);
}
}
this my php code on server
if($postjson['naw']=="homeprod"){
$prod = array();
$query = mysqli_query($mysqli, "SELECT * FROM product order by rand() limit 30");
while($getpost = mysqli_fetch_array($query))
{
$prod[] = array(
'description' => $getpost['description']
);
}
if($query) $result = json_encode(array('success'=>true, 'prodlists'=>$prod));
else $result = json_encode(array('success'=>false));
echo $result;
}
always flutter return with Null data type with sub type string.
Thank you in advance
I been working on this for days.
Our backend have a signature checking which is done using PHP:
private $HMAC_ALGO = 'md5';
public function decodeAndValidateMessage($data,$signature,$secretkey) {
if (!is_string($data)) {
throw new InvalidRequestException($data);
}
$decodedData = base64_decode($data);
// if not json returned the throw exception...
$jsonDecoded = json_decode($decodedData,true);
if (!$jsonDecoded) {
throw new InvalidRequestException($decodedData);
}
// validate
$signatureRef = base64_encode(hash_hmac($this->HMAC_ALGO,$decodedData,$secretkey,true));
if ($signature === $signatureRef) {
return $jsonDecoded;
} else {
throw new InvalidSignatureException();
}
}
I made it work on iOS:
func hmac(_ algorithm: HMACAlgorithm, key: String) -> String {
let cKey = key.cString(using: String.Encoding.utf8)
let cData = self.cString(using: String.Encoding.utf8)
var result = [CUnsignedChar](repeating: 0, count: Int(algorithm.digestLength()))
CCHmac(algorithm.toCCHmacAlgorithm(), cKey!, Int(strlen(cKey!)), cData!, Int(strlen(cData!)), &result)
let hmacData:Data = Data(bytes: UnsafePointer<UInt8>(result), count: (Int(algorithm.digestLength())))
let hmacBase64 = hmacData.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
print(String(hmacBase64))
return String(hmacBase64)
}
Any idea/help on doing this on Kotlin/Android? I'm being stuck on InvalidSignatureException error.
fun generateSignature(data : HashMap<String, Any>) : String {
val hmac = Mac.getInstance("HmacMD5")
hmac.init(SecretKeySpec(Constant.PRIVATEKEY.toByteArray(Charsets.UTF_8), hmac.algorithm))
return Base64.encodeToString(data.toString().toByteArray(),Base64.URL_SAFE + Base64.NO_PADDING + Base64.NO_CLOSE + Base64.NO_WRAP)
}
Thanks :D I really appreciate for any help :D
Update:
Just to make my question simpler?
Is it possible to make translate the iOS line of code to Kotlin?
enum HMACAlgorithm {
case md5, sha1, sha224, sha256, sha384, sha512
func toCCHmacAlgorithm() -> CCHmacAlgorithm {
var result: Int = 0
switch self {
case .md5:
result = kCCHmacAlgMD5
case .sha1:
result = kCCHmacAlgSHA1
case .sha224:
result = kCCHmacAlgSHA224
case .sha256:
result = kCCHmacAlgSHA256
case .sha384:
result = kCCHmacAlgSHA384
case .sha512:
result = kCCHmacAlgSHA512
}
return CCHmacAlgorithm(result)
}
func digestLength() -> Int {
var result: CInt = 0
switch self {
case .md5:
result = CC_MD5_DIGEST_LENGTH
case .sha1:
result = CC_SHA1_DIGEST_LENGTH
case .sha224:
result = CC_SHA224_DIGEST_LENGTH
case .sha256:
result = CC_SHA256_DIGEST_LENGTH
case .sha384:
result = CC_SHA384_DIGEST_LENGTH
case .sha512:
result = CC_SHA512_DIGEST_LENGTH
}
return Int(result)
}
}
this is how I call the function
var params : Dictionary
params.generateSignature()
fun generateSignature(data : HashMap) : String {
val hmac = Mac.getInstance("HmacMD5")
hmac.init(SecretKeySpec(Constant.PRIVATEKEY.toByteArray(Charsets.UTF_8), hmac.algorithm))
return Base64.encodeToString(data.toString().toByteArray(),Base64.URL_SAFE + Base64.NO_PADDING + Base64.NO_CLOSE + Base64.NO_WRAP)
}
Someone finally found out the answer.
My mistake is hashmap should be run under JSONObject
var obj = JsonObject(data)
and use obj.toString() :D
I am creating an app similar to those from online stores
I did an ArrayList for products added to the shopping cart.
How I must do to send this into my PHP script and add this to MySQL database.
I tried return count of my ArrayList elements, but I can't.
This is PHP code:
<?php
$postedArray = $_POST["arrayToPOST"];
$response = array();
if(isset($postedArray))
{
$count = count($postedArray);
$response["Count"] = $count;
$response["postedArray"] = $postedArray;
}
else
{
$response["Count"] = 0;
$response["postedArray"] = "ERROR ON POST";
}
echo json_encode($response);
?>
This is my function in Android app:
val arrayList: ArrayList<String> = ArrayList<String>()
arrayList.add("First value")
arrayList.add("Second value")
arrayList.add("Third value")
val gson = GsonBuilder()
.setLenient()
.create()
val retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(gson))
.baseUrl("http://192.168.100.11/")
.build()
val webAPIInterface = retrofit.create(WebAPIInterface::class.java)
var call = webAPIInterface.postData(arrayList)
call.enqueue(object : Callback<ResponsePOJO> {
override fun onFailure(call: Call<ResponsePOJO>?, t: Throwable?) {
Log.e("MainActivity", "Retrofit 2 ERROR: "+t.toString())
}
override fun onResponse(call: Call<ResponsePOJO>?, response: Response<ResponsePOJO>?)
{
Log.v("MainActivity", "RESPONSE: "+response!!.body().toString())
if(response!!.isSuccessful)
{
Log.v("MainActivity", "Response is successful")
Log.v("MainActivity", "")
}
else
{
Log.e("MainActivity", "Response isnt successful")
}
}
})
I looking for solution in internet, but I found nothing.
Please help !
I currently handle MongoDB with PHP.
I am trying to process data on Android using that value.
PHP:
public function Find($collection, $query = null, $fields = null) {
/* init */
$this->mClient = new MongoClient(...);
$this->mDBName = $dbName;
$this->mDB = $this->mClient->{$this->mDBName};
if(!isset($this->mDB)) {
// TODO
return;
}
/* find query */
$coll = $this->mDB->{$collection};
if(isset($query)) {
if(isset($fields)) $cursor = $coll->find($query, $fields);
else $cursor = $coll->find($query);
} else {
$cursor = $coll->find();
}
return json_encode(iterator_to_array($cursor, false));
}
ANDROID:
// Get String From PHP
// ex) [{"_id":{"$id":"59ad4d2425b572b7124be684"},"name":"\uacf5\ud3ec"},{"_id":{"$id":"59ad4d3625b572b7124be69a"},"name":"SF"}]
String result = getHttpData(getInstance().mStrUrl, data);
// In this part, data processing is done
List<DBObject> arr = new ArrayList<DBObject>();
//JSONObject json = new JSONObject(result);
JSONArray jsonArray = new JSONArray(result);
int len = jsonArray.length();
for (int i=0;i<len;i++){
String json = jsonArray.get(i).toString();
//Object o = com.mongodb.util.JSON.parse(result);
Object o = com.mongodb.util.JSON.parse(json);
DBObject dbObj = (DBObject) o;
arr.add(dbObj);
}
In the above case, referring to "_ id" will return BasicDBObject. It is necessary to receive an ObjectID.
Likewise for child document "_id" should be ObjectID.
HOW?
I am not receiving the myStatus when retrieving it from the php login. I get p_id and full name but not the status. I am parsing it to separate out the & but keep getting a null result from login. section 6 and section 7 are the areas I think I am having issues can anyone help?
login AS3
package {
import flash.display.MovieClip;
import flash.text.*;
import flash.events.*;
import flash.ui.Keyboard;
import flash.net.*;
import MainDocument;
public class Login extends MovieClip {
public function Login() {
// constructor code
// modify existing text boxes
login_txt.tabEnabled = true;
login_txt.tabIndex = 1;
login_txt.border = true;
login_txt.borderColor = 0xAAAAAA;
login_txt.background = true;
login_txt.backgroundColor = 0xFFFFDD;
pwd_txt.tabEnabled = true;
pwd_txt.tabIndex = 2;
pwd_txt.border = true;
pwd_txt.borderColor = 0xAAAAAA;
pwd_txt.background = true;
pwd_txt.backgroundColor = 0xFFFFDD;
login_btn.tabEnabled = true;
login_btn.tabIndex = 3;
//add button event listeners
login_btn.addEventListener(MouseEvent.MOUSE_UP, doLogin);
login_close_btn.addEventListener(MouseEvent.MOUSE_UP, doClose);
addEventListener(KeyboardEvent.KEY_DOWN, onEnter);
} // end construtor
private function onEnter(e:KeyboardEvent):void{
// nothing yet
if(e.keyCode == Keyboard.ENTER){
trace("User presses keyboard ENTER key");
doLogin(null); // must be null to meet the need for a parameter
}// end if
}// end function
// SECTION 1 – This is a function we need for removing extra whitespace coming from CWP server
function trimWhitespace($string:String):String {
if ($string == null) {
return "";
} //end if
return $string.replace(/^\s+|\s+$/g, ""); // see regular expressions
} // end function
private function doLogin(e:MouseEvent):void{
//trace("User presses OK button");
// SECTION 2 – URL request variable declared with path to server script
var req:URLRequest=new URLRequest(MainDocument.localPath + "login.php");
req.method = URLRequestMethod.POST;
// SECTION 3 – Upload variables are named as URL variables
var vars:URLVariables=new URLVariables();
vars.login = login_txt.text;
vars.pwd = pwd_txt.text;
req.data = vars;
// SECTION 4 – The URL Loader class instance is set to perform the HTTP POST
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.VARIABLES;
loader.load(req);
// SECTION 5 – listeners are added for both the HTTP status and COMPLETE
loader.addEventListener(HTTPStatusEvent.HTTP_STATUS,onHTTPStatus);
loader.addEventListener(Event.COMPLETE, retrieveData);
// SECTION 6 – The complete handler function is embedded within the doLogin() function
function retrieveData(e:Event):void {
// For the CWP server we must parse our own incoming data
var rawString:String = trimWhitespace(unescape(e.target.data));
var stArray:Array = rawString.split("&"); //split on ampersand character
trace("retrieve data");
for(var i:uint; i<stArray.length; i++){
stArray[i] = trimWhitespace(stArray[i]);
var pair:Array = stArray[i].split("=");
pair[0] = trimWhitespace(pair[0]);
switch (pair[0]){
case "myStatus":
var ms:String = trimWhitespace(pair[1]); // status data value
break;
case "p_id":
var id:int = int(trimWhitespace(pair[1])); // player id
break;
case "fullname":
var fn:String = trimWhitespace(pair[1]); // fullname
break;
default: // this is all the other junk---> dump
//do nothing
} // end switch
} //end for
// SECTION 7 – A switch statement to deal with cases of myStatus
switch (ms){
case "NOTOK" :
MainDocument.doc.showMsg("There is a communication problem\nTry Again!");
break;
case "OK" :
if(fn != "INVALID"){
MainDocument.doc.showMsg("Welcome " + fn);
//MainDocument.player_id = id;
//MainDocument.player_name = fn;
MainDocument.doc.removeLogin();
MainDocument.doc.turnOffButton("both");
//MainDocument.doc.enable_chat_button();
//MainDocument.doc.activateConsole();
////////////////////////
// start game here
////////////////////////
}else{
MainDocument.doc.showMsg("Login or password is incorrect. Try again, or \nif you are not a member, please register");
MainDocument.doc.turnOnButton("register");
MainDocument.doc.turnOffButton("login");
}
break;
default:
//MainDocument.doc.showMsg("An unknown problem has occured");
} // end switch
} // end function
// SECTION 8 – Handler function for HTTP status – also embedded
function onHTTPStatus(event:HTTPStatusEvent):void {
//trace("HTTP response code " + event.status);
if(event.status!=200){
MainDocument.doc.showMsg("There is an I/O Error #" + event.status);
} // end if
} // end function
} // end function doLogin
private function doClose(e:MouseEvent):void{
// nothing yet
trace("User presses Close button");
MainDocument.doc.showMsg(""); // clears any message
MainDocument.doc.removeLogin();
MainDocument.doc.turnOnButton("both");
}// end function
}//end class
}// end package
login.php
<?php
require_once("settings.inc.php");
// Create vars and load with incoming POST data
$login = $_POST['login'];
if(!isset($login)){
$login = $_GET['login'];
}
$pwd = $_POST['pwd'];
if(!isset($pwd)){
$pwd = $_GET['pwd'];
}
//=========================================================================================
// MAIN
//=========================================================================================
if(!(isset($login) && isset($pwd))){
print "myStatus=NOTOK&dummy=dummy";
}else{
$query = "SELECT `p_id`,`p_name` FROM `player` WHERE `p_login`='$login' AND `p_pwd`='$pwd'";
$result = mysqli_query($link,$query);
$row = mysqli_fetch_row($result);
if($row[0] != null && $row[0] != ''){
$p_id = $row[0];
$fullname = trim($row[1]);
$myStatus = $row[2];
print "myStatus=OK&p_id=" . trim($p_id) . "&fullname=" . trim($fullname) . "&dummy=dummy";
}else{
$fullname = "INVALID";
print "myStatus=OK&fullname=" . trim($fullname) . "&dummy=dummy";
} //end else
} //end else
?>