Http Ok3 Returns two responses - java

I am connecting black box backend, I have no control over the source and cannot modify the backend, using Ok Http 3. But for some reason, I am getting two results and I don't know what's going on. I suspect two threads are becoming active. But I don't know how to stop it. I tried both Synchronous and Asynchronous connection to no effect. I am new to Ok Http 3, so I am not sure what I am doing wrong.
I/Results: {"TotalResultsCount":3,"Results":[{
I/Results: {"TotalResultsCount":24,"Results":[
Here's is my synchronous code
class CallBackendSync extends AsyncTask {
OkHttpClient client = new OkHttpClient();
JSONObject resultsObject = null;
#Override
protected Object doInBackground(Object [] objects) {
String searchTerm = (String) objects[0];
String url = (String) objects[1];
String token = (String) objects[2];
String results = "";
//Search Body
RequestBody searchBody = new FormBody.Builder()
.add("QueryText", searchTerm)
.add("Categories", "")
.add("ChargeOutPerMinuteFrom", "0")
.add("ChargeOutPerMinuteTo", "0")
.add("maxDistance", "0")
.add("longitude", "0")
.add("latitude", "0")
.add("page", "0")
.build();
//Create request
Request.Builder builder = new Request.Builder();
builder.url(url);
builder.addHeader("Accept", "application/json");
if (token != null) {
builder.addHeader("Authorization", token);
}
builder.post(searchBody);
Request request = builder.build();
try {
Response response = client.newCall(request).execute();
results = results + response.body().string();
resultsObject = new JSONObject(results);
Log.i("Results", results);
return resultsObject;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String s){
super.onPostExecute(s);
displayResults(resultsObject);
}
}
I am calling the backend from MainActivity using the code fragment below
CallBackendSync sync = new CallBackendSync();
String [] params = {searchTerm, serverBaseUrl + url, accessToken};
sync.execute(params);
Any ideas about what's going wrong will be much appreciated.

Related

Getting bad response trying to send a request

I'm trying to send a request to a NodeJS server, I'm always getting Bad Request message with status code 400.
I tried using Postman to check if the problem was on the server, but in Postman it worked correctly.
I'm using OkHttp and trying to send a request like this:
private Request request;
private final OkHttpClient client = new OkHttpClient();
private void makePost(String nameOfProduct, String serialOfProduct, String priceOfProduct, String gender, String uriList, String colors, String sizes) {
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("name", nameOfProduct)
.addFormDataPart("serial",serialOfProduct)
.addFormDataPart("price",priceOfProduct)
.addFormDataPart("gender",gender)
.addFormDataPart("color", colors)
.addFormDataPart("size", sizes)
.addFormDataPart("imagesUri",uriList)
.build();
Log.d("COLROS", colors);
request = new Request.Builder()
.url("http://10.0.2.2:4000/products/add")
.header("Content-Type", "application/json")
.post(requestBody)
.build();
try{
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
Headers responeHeaders = response.headers();
for (int i = 0; i < responeHeaders.size(); i++) {
Log.d("iu", "makePost: "+responeHeaders.name(i) + ": " + responeHeaders.value(i));
}
Log.d("iu", "makePost: "+response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
You are sending Form data (application/x-www-form-urlencoded) but setting the header as json
Try to remove the line:
.header("Content-Type", "application/json")
and use:
.header("Content-Type", "application/x-www-form-urlencoded")
To send JSON data, you must build a JSON string. I'll use Gson library here, make sure you include it in your module level gradle file as follows:
implementation 'com.google.code.gson:gson:2.8.6'
Next you need a class to serialize into JSON:
public class Order {
public String name;
public String serial;
public int price;
public String gender;
//Other fields go here...
//This empty constructor is required by Gson
public Order() {}
}
Now you build an object of this class as you require:
private void makePost(String nameOfProduct, String serialOfProduct, String priceOfProduct, String gender, String uriList, String colors, String sizes) {
Order order = new Order();
order.name = nameOfTheProduct;
order.price = priceOfTheProduct;
//Fill in other fields here...
//Now get a JSON data string from this object using Gson:
Gson gson = new Gson();
String jsonData = gson.toJson(order);
public static final MediaType mediaTypeJSON = MediaType.get("application/json; charset=utf-8");
RequestBody requestBody = RequestBody.create(mediaTypeJSON, jsonData);
//Build the request
Request request = new Request.Builder()
.url("http://10.0.2.2:4000/products/add")
.post(requestBody)
.build();
//Finally send the request as you already do in your code
//Using the call: Response response = client.newCall(request).execute();
}

Okhttp post return null

I printed the json in execution I copied it I try the same json and url in postman and it's working so I don't think the problem is with url or json . rs variable in main is always null
public class PostLocation {
public static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
public String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = null;
try {
response = client.newCall(request).execute(); return response.body().string();
} finally {
if (response != null) { response.close(); }
}
}
String bowlingJson(Double lg,Double lt) {
return "{\"id\": null,\"datetime\": \"2019-01-10T19:00:00.000+0000\",\"user\": {\"id\": 1 },\"latitude\": "+lt+",\"longitude\": "+lg+"}";
}
}
main :
String rs = null;
String json = null;
//post
try{
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
PostLocation pl = new PostLocation();
json = pl.bowlingJson(location.getLongitude(), location.getLatitude());
System.out.println(json);
rs = pl.post("http://localhost:8080/api/v1/locations", json);
}catch (IOException EX){
}finally {
t.setText("\n " + location.getLongitude() + " " + location.getLatitude() );
}
The problem was java.net.ConnectException :
I changed localhost(127.0.0.1) with 10.0.2.2 because Android emulator runs in a Virtual Machine
then I had a problem java.net.SocketTimeoutException: timeout
I added :
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(5, TimeUnit.MINUTES) // connect timeout
.writeTimeout(5, TimeUnit.MINUTES) // write timeout
.readTimeout(5, TimeUnit.MINUTES); // read timeout
client = builder.build();
Now it's working
This is your formatted Json:
{
"id":null,
"datetime":"2019-01-10T19:00:00.000+0000",
"user":{
"id":1
},
"latitude":"+lt+",
"longitude":"+lg+"
}
This looks to me that lt and lg will always have +'s around them.
Why don't you use String.format for example:
String.format("{\"id\": null,\"datetime\": \"2019-01-10T19:00:00.000+0000\",\"user\": {\"id\": 1 },\"latitude\": %f,\"longitude\": %f}", lt, lg);

Create Rest Project in SOAP UI using java

I am able to create SOAP Project and execute associated test case.
SOAP Code Snippet:
public String executeSoapTestcase(final SoapUIData soapUIData) throws Exception {
SoapUI.getSettings().setBoolean(HttpSettings.RESPONSE_COMPRESSION, false);
final WsdlProject project = new WsdlProject();
String response = null;
final WsdlInterface[] ifaceArray = WsdlInterfaceFactory.importWsdl(project, soapUIData.getWsdlPath(), true);
if (ifaceArray == null) {
throw new IllegalArgumentException(
"inside SoapUIService.executeTestcase Binding not found in the specified WSDL");
}
final WsdlInterface wsdlInterface = ifaceArray[0];
Operation[] wsdlOperations = wsdlInterface.getAllOperations();
if (wsdlOperations == null) {
throw new IllegalArgumentException(
"inside SoapUIService.executeTestcase Operations not found in the specified WSDL");
}
wsdlInterface.changeEndpoint(wsdlInterface.getEndpoints()[0], soapUIData.getEndpoint());
final WsdlOperation operation = (WsdlOperation) wsdlOperations[0];
final WsdlRequest request = operation.addNewRequest("addRequest");
request.setRequestContent(soapUIData.getXmlRequest());
final WsdlSubmit<?> wsdlSubmit = (WsdlSubmit<?>) request.submit(new WsdlSubmitContext(request), false);
final WsdlResponse wsdlResponse = (WsdlResponse) wsdlSubmit.getResponse();
log.info("inside utm-soapui-service SoapUIService.executeTestcase Submit status : " + wsdlSubmit.getStatus());
if (wsdlResponse != null) {
response = wsdlResponse.getContentAsString();
}
return response;
}
Same thing i want to do for REST Project: I want to create Rest Project using wadl and execute test case.
public void executeRestTestcase() throws Exception {
final WsdlProject project = new WsdlProject();
final RestServiceBuilder serviceBuilder = new RestServiceBuilder();
serviceBuilder.createRestService(project,"Your Rest URL");
final StringToStringMap headers = new StringToStringMap();
headers.put("Authorization", "Basic **********");
headers.put("Accept", "application/json");
final RestRequest request =
(RestRequest) project.getInterfaceList().get(0).getOperationList().get(0).getRequestList().get(0);
request.setRequestHeaders(headers);
final Submit submit = (Submit) request.submit(new WsdlSubmitContext(request), false);
final Response response = submit.getResponse();
String responseContent = response.getContentAsString();
log.info(responseContent);
}
The above solution is working fine but by default it is using GET and could not able to find any method to change from GET to POST.
I am trying to send POST request with REST Body and looking for the code for the same
public void executeRestTestcase() throws Exception {
final WsdlProject project = new WsdlProject();
final RestServiceBuilder serviceBuilder = new RestServiceBuilder();
serviceBuilder.createRestService(project,"http://restapi.adequateshop.com/api/authaccount/registration");
final StringToStringMap headers = new StringToStringMap();
headers.put("Authorization", "Basic a93e4973-11f8-4efe-9d22-6edc3d46c186");
headers.put("Accept", "application/json");
final RestRequest request = (RestRequest) project.getInterfaceList().get(0).getOperationList().get(0).getRequestList().get(0);
request.setRequestHeaders(headers);
ReadJsonAsString redjson = new ReadJsonAsString();
String testrf = redjson.readFileAsString("");
request.setRequestContent(testrf);
RestMethod HttpMethod = request.getRestMethod();
WsdlSubmit submit = (WsdlSubmit) request.submit(new WsdlSubmitContext(request), false);
final Response response = submit.getResponse();
String responseContent = response.getContentAsString();
System.out.println("RESPONSE: " + responseContent);
}

Posting multipart form data via Android AsyncTask

My issue is with the writeArgsToConn() function.....i think. I cant figure out how to implement it.
I am trying to post multipart-formdata from an Android device using AsyncTask class. Can anyone help with this? I want to stay away from the depreciated org.apache.http.legacy stuff and stick with up-to-date Android libraries.
I was able to use similar implementation for a class called DoPostJSON which used Content-Type: application/json and that class works fine.
Same question but on Reddit: https://redd.it/49qqyq
I had issues with getting nodejs express server to detect the parameters being sent in. My DoPostJSON class worked fine and my nodejs server was able to detect parameters...for some reason DoPostMultiPart doesnt work and nodejs server cant see paramters being passed in. I feel like I am using the library the wrong way.
public class DoPostMultiPart extends AsyncTask<JSONObject, Void, JSONObject> implements Post{
#Override
public HttpURLConnection createConn(String action) throws Exception{
URL url = new URL(Utils.host_api + action);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Cache-Control", "no-cache");
conn.setReadTimeout(35000);
conn.setConnectTimeout(35000);
return conn;
}
#Override
public JSONObject getResponse(HttpURLConnection conn) throws Exception {
int responseCode = conn.getResponseCode();
String response = "";
if (responseCode == HttpsURLConnection.HTTP_OK) {
InputStream in = new BufferedInputStream(conn.getInputStream());
BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(in));
String line = "";
StringBuilder stringBuilder = new StringBuilder();
while ((line = responseStreamReader.readLine()) != null)
stringBuilder.append(line).append("\n");
responseStreamReader.close();
response = stringBuilder.toString();
} else {
throw new Exception("response code: " + responseCode);
}
conn.disconnect();
return new JSONObject(response);
}
// TODO: fix this function
#Override
public void writeArgsToConn(JSONObject args, HttpURLConnection conn) throws Exception {
// define paramaters
String fullname = args.getString("fullname");
String email = args.getString("email");
String password = args.getString("password");
String confpassword = args.getString("confpassword");
Bitmap pic = (Bitmap) args.get("pic");
// plugin paramters into request
OutputStream os = conn.getOutputStream();
// how do I plugin the String paramters???
pic.compress(Bitmap.CompressFormat.JPEG, 100, os); // is this right???
os.flush();
os.close();
}
#Override
protected JSONObject doInBackground(JSONObject... params) {
JSONObject args = params[0];
try {
String action = args.getString("action");
HttpURLConnection conn = createConn(action);
writeArgsToConn(args, conn);
return getResponse(conn);
} catch (Exception e) {
Utils.logStackTrace(e);
return null;
}
}
}
I solved my issue by using OkHttpClient library.
JSONObject args = params[0];
try
{
final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addFormDataPart("fullname", args.getString("fullname"))
.addFormDataPart("email", args.getString("email"))
.addFormDataPart("password", args.getString("password"))
.addFormDataPart("confpassword", args.getString("confpassword"))
.addFormDataPart("pic", "profile.png", RequestBody.create(MEDIA_TYPE_PNG, (File) args.get("pic")))
.build();
Request request = new Request.Builder()
.url(Utils.host_api + args.getString("action"))
.post(requestBody)
.build();
OkHttpClient client = new OkHttpClient();
Response response = client.newCall(request).execute();
return new JSONObject(response.body().string());
}
catch (Exception e)
{
Utils.logStackTrace(e);
return null;
}

Continuous connection via HttpGet?

Hey all I am writing an android aplication which gets a JSON object from a node.js server. My code is below (I do not have access to the server code). Is there any way to consistently check the server for a change in the JSON object (if they update it)? Right now it only does one GET and stops. I want to be able to query for a change and continue working with the new updates. Thoughts? Thanks.
Called from OnCreate():
new Read().execute("JSONkey");
Here is my Read ASyncTask:
public class Read extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String...param) {
try {
read_json = getCoords();
httpText.append(read_json.toString() + "\n");
try{
}catch(Exception e){ e.printStackTrace(); }
JSONArray data = read_json.getJSONArray(param[0]);
for (int i = 0; i < data.length(); ++i){
JSONObject info = data.getJSONObject(i);
Coordinate pt = new Coordinate(info.getInt("point"), info.getString("name"), info.getDouble("lat"), info.getDouble("long"));
coords.put(pt.getPoint(), pt);
coordList.add(new GeoPoint(pt.getLat(),pt.getLong()));
}
return "Success"; //get "text"
} catch (Exception e){
return "Fail";
}
}
#Override
protected void onPostExecute(String result){
//Doing something with JSON
//new Read().execute("coords"); tried doing this, but I feel it is not right.
}
}
and the GetCoords():
public JSONObject getCoords()
throws ClientProtocolException, IOException, JSONException{
StringBuilder url = new StringBuilder(URL);
HttpGet get = new HttpGet(url.toString());
HttpResponse response = client.execute(get);
int status = response.getStatusLine().getStatusCode();
if(status == 200){
HttpEntity entity = response.getEntity();
String data = EntityUtils.toString(entity);
JSONObject last = new JSONObject(data);
return last;
}else{
return null;
}
}
The proper way to do this is with a WebSocket but given the constrain of not being able to control the server side, your best bet is to
Put your code inside a service:
http://developer.android.com/reference/android/app/IntentService.html
Then use the Alarm Manager to schedule periodic updates.
http://developer.android.com/reference/android/app/AlarmManager.html

Categories

Resources