OKHttp put and post requests not working - php

I'm trying to use OKHttp to send a request to my php backend. I'm using this code:
public static String putRequestWithHeaderAndBody(String url, String header, String jsonBody) throws IOException
{
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, jsonBody);
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.put(body) //PUT
.addHeader("Authorization", header)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
I then try to read the put body from php using this line of code:
$data = json_decode(file_get_contents("php://input"), true);
However, it always seems to be empty. I feel like I am making a silly mistake, I cannot seem to find out what is wrong though.
The request does return the correct response body when I send it using Postman.

Related

Cannot retrieve error message using Symfony HttpClient if the response is not "ok"

I use Symfony HttpClient to call an external API. When the status code is 200 I can use getContent() method to retrieve the API response. If the API response is 400, a ClientException is thrown, and I cannot get the external API message.
$httpClient = HttpClient::create();
$response = $httpClient->request($method, $url);
if (200 !== $response->getStatusCode()) {
$apiResponse['statusCode'] = $response->getStatusCode();
$httpInfo = $response->getInfo();
$content = $response->getContent(); //this throws ClientException
}
You can use
$response->getContent(false)
to get the response and not an error thrown.
Explanation from Code:
public function getContent(bool $throw = true): string
Note that you lose a bit of the very meaningful wrapping functionality HttpClient provides you here.

laravel callback url with file_get_contents('php://input')

in vanilla php i would create a callbak url with just
try
{
//response content type application/json
header("Content-Type:application/json");
//read incoming request
$postData = file_get_contents('php://input');
.......
......
but in laravel i'm yet to get a clear explanation on how to achieve the same
ive tried using
$postData = Request::getContent();
but it returns blank
If you need data in request use (new \Illuminate\Http\Request())->all() or use DI
public function someAction(\Illuminate\Http\Request $request)
{
dd($request->all());
}

Android / Loopj - How can i POST a complex JSON object to a server?

In one of my application, in which I use the Loopj library, I need to send a complex object to a web-service (running on PHP). I decided to send a JSON object via HTTP POST request using Loppj example.
JSONObject params = new JSONObject();
try
{
params.put("params1", "value1");
params.put("params2", "value2");
params.put("params3", "value3");
}
catch(JSONException e)
{
// ...
}
StringEntity entity = new StringEntity(params.toString(), HTTP.UTF_8);
ArrayList<Header> array = new ArrayList<>();
array.add(new BasicHeader("Content-type", "application/json"));
array.add(new BasicHeader("Accept", "application/json"));
Header[] headers = new Header[headers.size()];
headers = headers.toArray(array);
AsyncHttpClient client = new AsyncHttpClient();
client.post(context, url, headers, entity, "application/json", new JsonHttpResponseHandler()
{
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response)
{
//...
}
#Override
public void onFailure(int statusCode, Header[] headers, Throwable e, JSONObject errorResponse)
{
// ...
}
});
Unfortunately, $_POST / $_REQUEST are always empty. I've searched different tips but none of them is working. I haven't restriction on routes in my web-service, just a simple function to dump posted parameters.
EDIT 1
To check posted parameters, I coded a simple PHP page to log them. Thanks to #Steve, I was abble to find them in php://input.
file_put_contents(__DIR__ . '/post_data.log', json_encode($_POST));
file_put_contents(__DIR__ . '/input_data.log', file_get_contents('php://input'));
The fact is that I'm not the owner of the final web-services, so I can't change access to data. They must be accessible through $_POST. So, sending application/json isn't the solution ? How AJAX can send complex objects to a server and find them in $_POST, and not Android ?
EDIT 2
I tried to do the same with PostMan and $_POST is always empty. So, I analyzed the request sent by jQuery.ajax(...) (which allow you to send JSON object) and it generate proper key/value from JSON object.
For example, the JSON object :
{
"users":[
{
"name":"jean",
"age":"25",
"city":"paris"
}
]
}
It is converted in 3 pairs key/value :
users[0][name] : jean
users[0][age] : 25
users[0][city] : paris.
So, I guess I need a function which convert my JSONObject into RequestParams object and send it "normally" through "x-www-form-urlencoded". I don't know if there's any native function which can do this but I found the Javascript equivalent (Query-string encoding of a Javascript Object).
serialize = function(obj, prefix) {
  var str = [], p;
  for(p in obj) {
    if (obj.hasOwnProperty(p)) {
      var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
      str.push((v !== null && typeof v === "object") ?
        serialize(v, k) :
        encodeURIComponent(k) + "=" + encodeURIComponent(v));
    }
  }
  return str.join("&");
}
As I said previously, I wrote a helper class which convert JSONObject to RequestParams which can "normally" be sent over POST HTTP method.
I copy/paste it and wrote a quick README file. If you have any suggestions or even pull-requests, please share.
Hope it helps.
https://github.com/schnapse/json-to-requestparams

Retrofit does not send header

I'm currently working on an Android app and I have a problem, I'm trying to send a header in my request with retrofit but when I check on my server with PHP it looks like the header does not even exists.
Here is my code:
Android
#Headers("SECRET_KEY: QWERTZUIOP")
#GET("{TableName}/")
Call<List<Data>> cl_getAllFromTable(#Path("TableName") String TableName);
PHP Server
$secret_key = $_SERVER['HTTP_SECRET_KEY'];
I'd be glad if someone could help. Thanks in advance.
Teasel
// Define the interceptor, add authentication headers
Interceptor interceptor = new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder().addHeader("User-Agent", "Retrofit-Sample-App").build();
return chain.proceed(newRequest);
}
};
// Add the interceptor to OkHttpClient
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.interceptors().add(interceptor);
OkHttpClient client = builder.build();
// Set the custom client when building adapter
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
Reference: https://guides.codepath.com/android/Consuming-APIs-with-Retrofit

Handling different php responses after a javascript http post request

I am developing an android application that uses the PHP/MySQL to send data from app to server in order to register/login users. I already wrote the Javascript and PHP files to send and receive JSON data an insert it into MySQL database. The problem I have is how to handle different responses from PHP.
Exemple:
<?php
//decode json object
$json = file_get_contents('php://input');
$obj = json_decode($json);
//variables
$user_firstname = $obj->{'user_firstname'};
$user_lastname = $obj->{'user_lastname'};
$user_email = $obj->{'user_email'};
$user_password = $obj->{'user_password'};
if([variables] != null){
//check for an existing email in db
mysql_query("Check if email exists");
if(email exist){
//pass a response to java file
return user_exists;
die();
}else{
//success
return success;
}
}
?>
All I want is to handle those different return values in order to interact with the user inside the android app.
I think you should user HTTP response codes for this. For example, your php script will return HTTP 200 - OK when user successfully created and HTTP 409 Conflict when user already exists. This is how RESTfull APIs usually works this. On Android you'll have to check the status code and decide what to do.
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httpget = new HttpPost("http://www.google.com/");
HttpResponse response = httpclient.execute(httpget);
int statusCode = response.getStatusLine().getStatusCode();
You can craft a json response by creating an associative array and passing it to json_encode() which will return a string that you can echo to the java client. Don't forget to set the appropriate Content-Type header using the header() function. It's also a good idea to set the HTTP response code appropriately. I'm picturing something like this:
$responseArray = array('response' => 'success'); // or 'user_exists'
$responseJson = json_encode($responseArray);
header('HTTP/1.1 200 OK'); // or 4xx FAIL_TEXT on failure
header('Content-Type: application/json');
echo $responseJson;
You'll then have to parse this response on the java client.

Categories