Storm bolt Async HTTP Call - java

I got requirement to make asynchronous http call in my bolt.
In this bolt only async http call to be made and after getting response it should insert to elastic search.
i followed the this link here is pseudocode.
public void prepare(Map arg0, TopologyContext context,
OutputCollector collector) {
httpclient = HttpAsyncClients.createDefault();
httpclient.start();
_collector = collector;
}
public void execute(Tuple tuple) {
try{
if( !isTickTuple(tuple) ) {
data = (data)tuple.getValueByField("source");
httpCall(data,"http://");
}
}catch(Exception e){
logger.warn(e.getMessage());
if(logger.isDebugEnabled())logger.debug(e.getMessage(),e);
}finally{
_collector.ack(tuple);
}
}
public void httpCall(String data,String url) {
HttpPost postRequest = new HttpPost(url);
HttpEntity httpEntity = null;
//CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
postRequest.addHeader("content-type", "application/json");
postRequest.setEntity(httpEntity);
HttpAsyncRequestProducer producer = HttpAsyncMethods.create(postRequest);
AsyncCharConsumer<HttpResponse> consumer = new AsyncCharConsumer<HttpResponse>() {
HttpResponse response;
#Override
protected void onResponseReceived(final HttpResponse response) {
this.response = response;
}
#Override
protected void onCharReceived( CharBuffer buf, IOControl ioctrl) throws IOException {
// Do something useful
}
#Override
protected void releaseResources() {
}
#Override
protected HttpResponse buildResult( HttpContext context) {
return this.response;
}
};
httpclient.execute(producer, consumer, new FutureCallback<HttpResponse>() {
#Override
public void completed(HttpResponse response) {
int responseCode = response.getStatusLine().getStatusCode();
if(logger.isDebugEnabled())logger.debug("Response code::"+responseCode );
if (responseCode == HttpServletResponse.SC_OK) {
HttpEntity entity = response.getEntity();
try {
String data = EntityUtils.toString(entity, "UTF-8");
if(logger.isDebugEnabled())logger.debug("Response string");
updatedata(data);
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
if(logger.isDebugEnabled())logger.debug("completed Method:::: "+response.toString());
}
#Override
public void failed(Exception ex) {
if(logger.isDebugEnabled())logger.debug("!!! Async http request failed!", ex);
}
#Override
public void cancelled() {
if(logger.isDebugEnabled())logger.debug("Async http request canceled!");
}
});
}
here response code(200) is printing in log but the logger after this line
String data = EntityUtils.toString(entity, "UTF-8");
is not printing. Can any body provide link or code with better approach.
Updated:
i added logger inside onCharReceived method Its printing the Response now chunk by chunk.
Can anyone tell how to get complete response or should use other library.

Related

How to send param value to Server and get data using AsyncTask (by POST Request)?

this code is ok for get data from server but if my API is POST Method how to pass params to server by POSt Request and fetch data. code is here, please let me know
public class GetTripTeportData extends AsyncTask<String, Integer,String> {
#Override
protected void onPreExecute() {...}
#Override
protected String doInBackground(String... params) {
String responseBodyText = null;
OkHttpClient client = new OkHttpClient();
try {
Request request = new Request.Builder().url(excelApi).build();
Response response = null;
response = client.newCall(request).execute();//.....
responseBodyText = response.body().string();
JSONObject resultData = new JSONObject(responseBodyText);
JSONArray itemArray = resultData.getJSONArray("data");
for (int i=0; i<itemArray.length();i++){
JSONObject jobject = itemArray.getJSONObject(i);
String iduser = jobject.getString("id");
String vehicleno = jobject.getString("vehicleno");
String startdate = jobject.getString("startdate");
allList.add(new ExcelReportAdminResponse(iduser,vehicleno,startdate));
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
return responseBodyText;
}
#Override
protected void onPostExecute(String s) {......}
}
To post data with default http client with async task you can do as below:
First create network utility class as below:
public class NetworkUtilities {
public static String postData(String Url, String message ){
try {
URL url = new URL(Url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000); /*milliseconds*/
conn.setConnectTimeout(15000); /* milliseconds */
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setFixedLengthStreamingMode(message.getBytes().length);
conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
conn.setRequestProperty("X-Requested-With", "XMLHttpRequest");
conn.connect();
OutputStream os = new BufferedOutputStream(conn.getOutputStream());
os.write(message.getBytes());
os.flush();
InputStream is = conn.getInputStream();
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
catch (Exception e){
Log.e("Exception: " , e.toString());
}
finally {
// os.close();
//is.close();
//conn.disconnect();
}
return "";
}
}
Then write async task to call that postData() method from NetworkUtilities class as below:
private class PostDataAsync extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
return NetworkUtilities.postData(params[0], params[1]);
}
#Override
protected void onPostExecute(String result) {
Log.e("Data response: ", result);
}
#Override
protected void onPreExecute() {
// TODO: Loader and stuff to add later here.
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
Then to call that async task means to call api do as below:
String message = "";
try {
JSONObject jsonBody = new JSONObject();
jsonBody.put("user_id", session.getSession());
message = jsonBody.toString();
} catch (Exception e) {
Log.e("JSON error: ", e.toString());
}
PostDataAsync postData = new PostDataAsync();
postData.execute("YOUR_POST_API_URL_HERE", message);
By using this way you can be able to post data with async task.
For POST call with JSON body
final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, /*YOUR JSON REQUEST*/ jsonString);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try {
Response response = client.newCall(request).execute();
} catch(IOException io){
// do something
}

Making volley request with return value

I am new to Android Volley requests. I have managed to make post and get requests to the server and get the response.
public void getCardDetails() throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
StringRequest postRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// response
Log.d("Response from server","Customer Account"+response);
try {
results = signInActivity.splitQuery(response);
String encodedMessage = results.get("encodedMessage");
String serverSignature = results.get("signature");
//Log.d("CustomerAccount","encodedMessage:"+ encodedMessage);
String decodeMessage = security.decodeBase64(encodedMessage);
Log.d("CustomerAccount","DecodedMessage"+ decodeMessage);
customerDetailsXML = decodeMessage;
try {
String computedSignature = security.hashMac(decodeMessage, signature_key);
int responseCode = xmlHandler.getResponseCode(decodeMessage);
Log.d("CustomerAccount","Response Code: "+responseCode);
if (responseCode == 1001){
getCardBalance();
Log.d("CustomerAccount","Success");
}
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (JDOMException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// error
Log.d("Error.Response", error.toString());
}
}
) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<>();
headers.put("Content-type", "application/x-www-form-urlencoded;charset=\"utf-8\"");
headers.put("Accept", "application/x-www-form-urlencoded");
headers.put("Cache-Control", "no-cache");
headers.put("Pragma", "no-cache");
headers.put("User-Agent", "Mozilla/5.0");
headers.put("Content-length", dataStream.toString());
return headers;
}
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("encodedMessage", encodedMessage_req);
params.put("signature", signature);
return params;
}
};
Volley.newRequestQueue(this).add(postRequest);
}
The above request get the server response in a String XML format. I want to be able for the method in which i do the request to return the XML so i can manipulate it as i want out of the request method.
Any pointers on how to achieve this?
do something like this:
make an interface class:
public interface MyListener{
public void myMethod(String response);
}
change your method inputs: public void getCardDetails(MyListener listener)
in your public void onResponse(String response)
add this:
`listener.myMethod(response);`

How can my method return a String [duplicate]

This question already has answers here:
Android - loopJ AsyncHttpClient return response onFinish or onSuccess
(2 answers)
Closed 7 years ago.
I am coding my Android application and hit a roadblock.
I cant get a certain method to return a string.
I am using loopjs Async Http Client.
The code is as follows
public static String networkOps(final String relativeURL){
AsyncHttpClient client = new AsyncHttpClient();
client.get(BASE_URL+relativeURL, new TextHttpResponseHandler() {
#Override
public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
Log.e(TAG,responseString);
}
#Override
public void onSuccess(int statusCode, Header[] headers, String responseString) {
String response = responseString;
Log.i(TAG,responseString);
Log.i(TAG,BASE_URL+relativeURL);
}
});
return response;
}
Pass in the ResponseHandler with the callback implemented.
Inside your activity:
private void doNetworkCall() {
NetworkUtil.networkOps(final String relativeURL, new TextHttpResponseHandler() {
#Override
public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
Log.e(TAG,responseString);
}
#Override
public void onSuccess(int statusCode, Header[] headers, String responseString) {
doSomethingWithResponse(responseString);
Log.i(TAG,BASE_URL+relativeURL);
}
});
private void doSomethingWithResponse(String response) {
....
Log.i(TAG,responseString);
}
Try:
public static String networkOps(final String relativeURL){
String response = null;
AsyncHttpClient client = new AsyncHttpClient();
client.get(BASE_URL+relativeURL, new TextHttpResponseHandler() {
#Override
public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
Log.e(TAG,responseString);
}
#Override
public void onSuccess(int statusCode, Header[] headers, String responseString) {
response = responseString;
Log.i(TAG,responseString);
Log.i(TAG,BASE_URL+relativeURL);
}
});
return response;
}
UPDATE:
Or u can get Response String by Method:
public String makeServiceCall(String url, int method,
List<NameValuePair> params) {
try {
// http client
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
// Checking http request method type
if (method == POST) {
HttpPost httpPost = new HttpPost(url);
// adding post params
if (params != null) {
httpPost.setEntity(new UrlEncodedFormEntity(params));
}
httpResponse = httpClient.execute(httpPost);
} else if (method == GET) {
// appending params to url
if (params != null) {
String paramString = URLEncodedUtils
.format(params, "utf-8");
url += "?" + paramString;
}
HttpGet httpGet = new HttpGet(url);
httpResponse = httpClient.execute(httpGet);
}
httpEntity = httpResponse.getEntity();
response = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}

Android failed to upload multiple type of files to PHP server

I'm trying to upload an image file and an audio file from Android to the Php server at the same time, this is the upload method on Android part:
public String postFile(File image,File audio) throws Exception {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(uploadUrl);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
FileBody fbImage = new FileBody(image);
FileBody fbAudio = new FileBody(audio);
builder.addPart("image", fbImage);
builder.addPart("audio", fbAudio);
final HttpEntity yourEntity = builder.build();
class ProgressiveEntity implements HttpEntity {
#Override
public void consumeContent() throws IOException {
yourEntity.consumeContent();
}
#Override
public InputStream getContent() throws IOException,
IllegalStateException {
return yourEntity.getContent();
}
#Override
public Header getContentEncoding() {
return yourEntity.getContentEncoding();
}
#Override
public long getContentLength() {
return yourEntity.getContentLength();
}
#Override
public Header getContentType() {
return yourEntity.getContentType();
}
#Override
public boolean isChunked() {
return yourEntity.isChunked();
}
#Override
public boolean isRepeatable() {
return yourEntity.isRepeatable();
}
#Override
public boolean isStreaming() {
return yourEntity.isStreaming();
} // CONSIDER put a _real_ delegator into here!
#Override
public void writeTo(OutputStream outstream) throws IOException {
class ProxyOutputStream extends FilterOutputStream {
public ProxyOutputStream(OutputStream proxy) {
super(proxy);
}
public void write(int idx) throws IOException {
out.write(idx);
}
public void write(byte[] bts) throws IOException {
out.write(bts);
}
public void write(byte[] bts, int st, int end) throws IOException {
out.write(bts, st, end);
}
public void flush() throws IOException {
out.flush();
}
public void close() throws IOException {
out.close();
}
} // CONSIDER import this class (and risk more Jar File Hell)
class ProgressiveOutputStream extends ProxyOutputStream {
public ProgressiveOutputStream(OutputStream proxy) {
super(proxy);
}
public void write(byte[] bts, int st, int end) throws IOException {
// FIXME Put your progress bar stuff here!
out.write(bts, st, end);
if(end==bts.length-1){
dialog.dismiss();
Toast.makeText(TakePhotoActivity.this, "File Upload Complete.", Toast.LENGTH_SHORT).show();
}
}
}
yourEntity.writeTo(new ProgressiveOutputStream(outstream));
}
};
ProgressiveEntity myEntity = new ProgressiveEntity();
post.setEntity(myEntity);
HttpResponse response = client.execute(post);
System.out.println("UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU "+getContent(response));
return getContent(response);
}
public static String getContent(HttpResponse response) throws IOException {
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String body = "";
String content = "";
while ((body = rd.readLine()) != null)
{
content += body + "\n";
}
return content.trim();
}
And this is the Php part:
<?php
$file_path = "uploads/";
$file_path = $file_path . basename( $_FILES['image']['name']);
if(move_uploaded_file($_FILES['image']['tmp_name'], $file_path)) {
echo "image success";
} else{
echo "image fail";
}
$file_path = $file_path . basename( $_FILES['audio']['name']);
if(move_uploaded_file($_FILES['audio']['tmp_name'], $file_path)) {
echo "audio success";
} else{
echo "audio fail";
}
?>
But on the server I can only see the audio file, the image file failed uploading, I also tried to upload two image files, it worked, but when one audio file and one image file, the image file usually failed, any suggestions about this? Thank you in advance.
I would suggest you follow up with this . as your MultipartEntity is different and this one works.I've tried it. Happy Coding!
try
{
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(URL);
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
entityBuilder.addTextBody(USER_ID, userId);
entityBuilder.addTextBody(NAME, name);
entityBuilder.addTextBody(TYPE, type);
entityBuilder.addTextBody(COMMENT, comment);
entityBuilder.addTextBody(LATITUDE, String.valueOf(User.Latitude));
entityBuilder.addTextBody(LONGITUDE, String.valueOf(User.Longitude));
if(file != null)
{
entityBuilder.addBinaryBody(IMAGE, file);
}
HttpEntity entity = entityBuilder.build();
post.setEntity(entity);
HttpResponse response = client.execute(post);
HttpEntity httpEntity = response.getEntity();
result = EntityUtils.toString(httpEntity);
Log.v("result", result);
}
catch(Exception e)
{
e.printStackTrace();
}

Listener not firing off callback

I have a class that implements a listener so that when another class that has an async tasks has been completed then the data can be returned with the use of this listener. The async task is being completed but the listener is not passing the data when it's obtained in the post execute function.
Async Task
Public class AdFetcher extends AsyncTask<String,Void,String>
{
private HTTPListener listener;
//sets the listeners
public AdFetcher(HTTPListener listener)
{
this.listener = listener;
}
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (IOException e) {
//TODO Handle problems..
}
return responseString;
}
#Override
protected void onPostExecute(String result)
{
//Tries to deserialization and if there is an exception then its added to the Stack Trace.
try
{
JSONObject data = new JSONObject(result);
if(listener==null)
throw new NullPointerException();
//Calls onComplete function in the class/Activity that implemented the listener.
listener.onComplete(data);
}
catch (JSONException e)
{
e.printStackTrace();
}
}
}
Listener
public interface HTTPListener{
/**
* Callback function that must be implemented
* to get result from HTTP worker thread.
* #param result
*/
public void onComplete (JSONObject result);
}//end HttpListener interface
Class Implementing the listener
public class AdManager implements HTTPListener
{
//will store the current context of the application.
private Context context;
private Utility utils;
private String url;
private WebView client;
public AdManager(Context context,WebView client)
{
this.client = client;
this.context = context;
}
public void getAd()
{
utils = new Utility();
url = utils.BuildUrl();
new AdFetcher(this).execute(url);
}
public void onComplete(JSONObject result)
{
try
{ Log.e("RESULTS",result.getString("adtype"));
if(result.getString("error") == "null")
{
if(result.getString("adtype") == "banner")
{ //loads the banner image in the webview.
String html = "<img src=\""+result.getString("adimage")+"\">";
String mime = "text/html";
String encoding = "utf-8";
client.setVisibility(View.VISIBLE);
client.getSettings().setJavaScriptEnabled(true);
client.loadDataWithBaseURL(null, html, mime, encoding, null);
}
}
}
catch (JSONException e)
{
e.printStackTrace();
}
}
}

Categories

Resources