Get response from the web service for HttpResponse - java

In my application, the User can upload images to a PHP server, the iOS version is working 100%, the Android version used for this tutorial to upload image:
tutorial example
And the function I'm using is this:
public static String sendPost(String url, String imagePath)
throws IOException, ClientProtocolException {
HttpClient httpclient = new DefaultHttpClient();
httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION,
HttpVersion.HTTP_1_1);
HttpPost httppost = new HttpPost(url);
File file = new File(imagePath);
MultipartEntity mpEntity = new MultipartEntity();
ContentBody cbFile = new FileBody(file, "image/jpeg");
mpEntity.addPart("userfile", cbFile);
httppost.setEntity(mpEntity);
//Log.e("executing request " + httppost.getRequestLine());
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
//Log.e(""+response.getStatusLine());
if (resEntity != null) {
//Log.e(EntityUtils.toString(resEntity));
}
if (resEntity != null) {
resEntity.consumeContent();
}
httpclient.getConnectionManager().shutdown();
return response.toString();
}
return response.toString(); get it in org.apache.http.message.BasicHttpResponse # 406dc148
But the return of the web service is the URL where the image was saved, I need to have a string in the return of the PHP server, rather than the return I mentioned above how can I have it?
I wanted something like this (HttpURLConnection):
HttpURLConnection conn;
...
String response= "";
Scanner inStream = new Scanner(conn.getInputStream());
while(inStream.hasNextLine())
response+=(inStream.nextLine());
Log.e("resp", response);
After one hour onsegui trying to get the response from the Web service as follows:
...
byte [] responseBody = httppost.getMethod().getBytes();
Log.e("RESPONSE BODY",""+(new String(responseBody)));
...

If you want the content returned by the HTTP server, you shouldn't do this:
if (resEntity != null) {
resEntity.consumeContent();
}
... because that says "throw away the content".

Try this if the response is of type String
ResponseHandler<String> responseHandler = new BasicResponseHandler();
HttpResponse httpResponse = httpClient.execute(post, new BasicHttpContext()); // new BasicHttpContext() not necessary
// verify connection response status using httpResponse.getStatusLine().getStatusCode() then
String response = responseHandler.handleResponse(httpResponse);
if(response != mull){
Log.e("Response : "+response);
}else{
// Handle exception
}
return response;

Related

MultipartEntity Files not uploading through device

Possibly this is a duplicate question but I have already tried all answer of this site but none of this working!
I am using MultipartEntity for image upload. It's working completely fine in Emulator but When I check in device its not working.
Below my code
HttpParams params = new BasicHttpParams();
params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP);
HttpClient httpClient = new DefaultHttpClient(params);
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost("http://url.com/webservice_uploadvideo.php");
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.STRICT);
FileBody filebodyVideopre = new FileBody(new File(videoUploadpathPre)); //pre
entity.addPart("fin_detail", filebodyVideopre);
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost, localContext);
Here's my working code for multi-part image uploading. Yes it works in real device.
private int uploadImage(String selectedImagePath) {
try {
HttpClient client = new DefaultHttpClient();
File file = new File(selectedImagePath);
HttpPost post = new HttpPost(Constants.URL);
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE,
Constants.BOUNDARY, Charset.defaultCharset());
entity.addPart(Constants.MULTIPART_FORM_DATA_NAME, new FileBody(file));
post.setHeader("Accept", "application/json");
post.setHeader("Content-Type", "multipart/form-data; boundary=" + Constants.BOUNDARY);
post.setEntity(entity);
HttpResponse response = client.execute(post);
HttpEntity httpEntity = response.getEntity();
int status = response.getStatusLine().getStatusCode();
return status;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

How do I use the apache httpClient API to send file + api key and other parameters as a single request?

I have started to test http client apache API. I need it because I would like to send requests and to receive responses to virustotal API. Virus total API requires to parameters in the post request:
the api key value (a unique value for each user)
the file itself as I understood from their website.
For example:
>>> url = "https://www.virustotal.com/vtapi/v2/url/scan"
>>> parameters = {"url": "http://www.virustotal.com",
... "apikey": "-- YOUR API KEY --"}
>>> data = urllib.urlencode(parameters)
>>> req = urllib2.Request(url, data)
At the moment, I am trying to do the same thing in Java instead of Python. Here is a part of my source code commented to guide throughout the steps:
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
//create post request
HttpPost request = new HttpPost("https://www.virustotal.com/vtapi/v2/file/scan");
//http json header
request.addHeader("content-type", "application/json");
String str = gson.toJson(param);
String fileName = UUID.randomUUID().toString() + ".txt";
try {
//API key
StringEntity entity = new StringEntity(str);
Writer writer = new BufferedWriter(new FileWriter(fileName));
writer.write(VirusDefinitionTest.malware());
request.setEntity(entity);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
FileBody fileBody = new FileBody(new File(fileName));
builder.addTextBody("my_file", fileName);
HttpEntity entity = builder.build();
request.setEntity(entity);
HttpResponse response;
try {
response = httpClient.execute(request);
...
Unfortunately, I receive HTTP/1.1 403 Forbidden. Obviously, the error is somewhere in the entities but I cannot find how to do it. Any help would be deeply welcomed.
This worked for me with Apache 4.5.2 HttpClient:
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
HttpPost httppost = new HttpPost("https://www.virustotal.com/vtapi/v2/file/scan");
FileBody bin = new FileBody(new File("... the file here ..."));
// the API key here
StringBody comment = new StringBody("5ec8de.....", ContentType.TEXT_PLAIN);
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addPart("apikey", comment)
.addPart("file", bin)
.build();
httppost.setEntity(reqEntity);
System.out.println("executing request " + httppost.getRequestLine());
CloseableHttpResponse response = httpclient.execute(httppost);
try {
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
System.out.println("ToString:" + EntityUtils.toString(resEntity));
}
EntityUtils.consume(resEntity);
} finally {
response.close();
}
} finally {
httpclient.close();
}
The important part was the reqEntity which had to have two specifically named fields, "apikey", and "file". Running this with a valid API key gives me the expected response from the API.
The problem seems to be that first you add explicit "content-type" header which is "application/json" and at the end you send the Muiltipart entity. You need to add all the parameters and the file to the Muiltipart entity. Now the parameters are not send, because they are overwritten by Muiltipart entity:
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
//create post request
HttpPost request = new HttpPost("https://www.virustotal.com/vtapi/v2/file/scan");
//http json header
request.addHeader("content-type", "application/json");
String str = gson.toJson(param);
String fileName = UUID.randomUUID().toString() + ".txt";
try {
//API key
StringEntity entity = new StringEntity(str);
Writer writer = new BufferedWriter(new FileWriter(fileName));
writer.write(VirusDefinitionTest.malware());
// --> You set parameters here !!!
request.setEntity(entity);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
FileBody fileBody = new FileBody(new File(fileName));
builder.addTextBody("my_file", fileName);
HttpEntity entity = builder.build();
// --> You overwrite the parameters here !!!
request.setEntity(entity);
HttpResponse response;
try {
response = httpClient.execute(request);

Problems connecting with a PHP: withg java.lang.Exception: HTTP error: 401

I have this code, who should connect to a php remote file and should get a String representing a XML file. But something is wrong, it is giving me error 401.
The variable url is the direction of the php:
String response=getXML("http://ficticiousweb.com/scripts/getMagazinesList.php");
If i paste the real direction (that is a ficticious direction) on the webbrowser, it works and gives me the XML.
This is my code:
public String getXML(String url){
try{
StringBuilder builder = new StringBuilder();
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
HttpResponse response = httpclient.execute(httpget);
int statuscode = response.getStatusLine().getStatusCode();
if(statuscode == 200)
{
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = reader.readLine()) != null) builder.append(line);
}
else throw new Exception("HTTP error: " + String.valueOf(statuscode));
return builder.toString();
}catch(Exception e){e.printStackTrace();}
return null;
}
What is wrong with the code?
thanks
You need to login to the requested site in order to download or access the xml. This can be done by authenticated schema based upon what is supported. Normally, there are 2 types of schemas where used. Basic and Digest. Below code will help you for BASIC AUTH.
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String _username = "username";
String _password = "password";
try {
((AbstractHttpClient) httpclient).getCredentialsProvider().setCredentials(
new org.apache.http.auth.AuthScope(webhostname, webport)),
new org.apache.http.auth.UsernamePasswordCredentials(_username, _password));
response = httpclient.execute(new HttpGet(completeurlhere));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK) {
try {
InputStream is = response.getEntity().getContent();
this._data = is;
} catch(Exception ex) {
Log.e("DBF Error",ex.toString());
}
} else {
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch(ClientProtocolException cpe) {
Log.e("ClientProtocolException # at FPT",cpe.toString());
} catch(Exception ex) {
Log.e("Exception at FETCHPROJECTASK",ex.toString());
}
Well a 401 means you aren't Authorized to do the GET request. You should ask the website how to Authenticate the request...
Authorization happens through the Authorization Header in the HTTP request. You should look into that and probably fill that header yourself with your credentials... (if the server accepts that)

Can I upload Images AND text using UrlEncodedFormEntity for multi part?

Images often requires special HTTP headers like:
Content-disposition: attachment; filename="file2.jpeg"
Content-type: image/jpeg
Content-Transfer-Encoding: binary
I'm building my POST using:
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(formparams);
urlEncodedFormEntity allows setContentType, but I don't see how I can MIX both images and text ??
try {
File file = new File(Environment.getExternalStorageDirectory(),"FMS_photo.jpg");
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://homepage.com/path");
FileBody bin = new FileBody(file);
Charset chars = Charset.forName("UTF-8");
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("problem[photos_attributes][0][image]", bin);
reqEntity.addPart("myString", new StringBody("17", chars));
post.setEntity(reqEntity);
HttpResponse response = client.execute(post);
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
resEntity.consumeContent();
}
return true;
} catch (Exception ex) {
globalStatus = UPLOAD_ERROR;
serverResponse = "";
return false;
} finally {
}
in this the problem attribute will carry the image and myString carry the string...

Handling HttpClient Redirects

I'm POSTing some data to a server that is answering a 302 Moved Temporarily.
I want HttpClient to follow the redirect and automatically GET the new location, as I believe it's the default behaviour of HttpClient. However, I'm getting an exception and not following the redirect :(
Here's the relevant piece of code, any ideas will be appreciated:
HttpParams httpParams = new BasicHttpParams();
HttpClientParams.setRedirecting(httpParams, true);
SchemeRegistry schemeRegistry = registerFactories();
ClientConnectionManager clientConnectionManager = new ThreadSafeClientConnManager(httpParams, schemeRegistry);
HttpClient httpClient = new DefaultHttpClient(clientConnectionManager, httpParams)
HttpPost postRequest = new HttpPost(url);
postRequest.setHeader(HTTP.CONTENT_TYPE, contentType);
postRequest.setHeader(ACCEPT, contentType);
if (requestBodyString != null) {
postRequest.setEntity(new StringEntity(requestBodyString));
}
return httpClient.execute(postRequest, responseHandler);
For HttpClient 4.3:
HttpClient instance = HttpClientBuilder.create()
.setRedirectStrategy(new LaxRedirectStrategy()).build();
For HttpClient 4.2:
DefaultHttpClient client = new DefaultHttpClient();
client.setRedirectStrategy(new LaxRedirectStrategy());
For HttpClient < 4.2:
DefaultHttpClient client = new DefaultHttpClient();
client.setRedirectStrategy(new DefaultRedirectStrategy() {
/** Redirectable methods. */
private String[] REDIRECT_METHODS = new String[] {
HttpGet.METHOD_NAME, HttpPost.METHOD_NAME, HttpHead.METHOD_NAME
};
#Override
protected boolean isRedirectable(String method) {
for (String m : REDIRECT_METHODS) {
if (m.equalsIgnoreCase(method)) {
return true;
}
}
return false;
}
});
The default behaviour of HttpClient is compliant with the requirements of the HTTP specification (RFC 2616)
10.3.3 302 Found
...
If the 302 status code is received in response to a request other
than GET or HEAD, the user agent MUST NOT automatically redirect the
request unless it can be confirmed by the user, since this might
change the conditions under which the request was issued.
You can override the default behaviour of HttpClient by sub-classing DefaultRedirectStrategy and overriding its #isRedirected() method.
It seem http redirect is disable by default. I try to enable, it work but I'm still got error with my problem. But we still can handle redirection pragmatically. I think your problem can solve:
So old code:
AndroidHttpClient httpClient = AndroidHttpClient.newInstance("User-Agent");
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
long contentSize = httpResponse.getEntity().getContentLength();
This code will return contentSize = -1 if http redirect happend
And then I handle redirect by myself after trying enable default follow redirection
AndroidHttpClient client;
HttpGet httpGet;
HttpResponse response;
HttpHeader httpHeader;
private void handleHTTPRedirect(String url) throws IOException {
if (client != null)
client.close();
client = AndroidHttpClient.newInstance("User-Agent");
httpGet = new HttpGet(Network.encodeUrl(url));
response = client.execute(httpGet);
httpHeader = response.getHeaders("Location");
while (httpHeader.length > 0) {
client.close();
client = AndroidHttpClient.newInstance("User-Agent");
httpGet = new HttpGet(Network.encodeUrl(httpHeader[0].getValue()));
response = client.execute(httpGet);
httpHeader = response.getHeaders("Location");
}
}
In use
handleHTTPRedirect(url);
long contentSize = httpResponse.getEntity().getContentLength();
Thanks
Nguyen
My solution is using HttClient. I had to send the response back to the caller. This is my solution
CloseableHttpClient httpClient = HttpClients.custom()
.setRedirectStrategy(new LaxRedirectStrategy())
.build();
//this reads the input stream from POST
ServletInputStream str = request.getInputStream();
HttpPost httpPost = new HttpPost(path);
HttpEntity postParams = new InputStreamEntity(str);
httpPost.setEntity(postParams);
HttpResponse httpResponse = null ;
int responseCode = -1 ;
StringBuffer response = new StringBuffer();
try {
httpResponse = httpClient.execute(httpPost);
responseCode = httpResponse.getStatusLine().getStatusCode();
logger.info("POST Response Status:: {} for file {} ", responseCode, request.getQueryString());
//return httpResponse ;
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpResponse.getEntity().getContent()));
String inputLine;
while ((inputLine = reader.readLine()) != null) {
response.append(inputLine);
}
reader.close();
logger.info(" Final Complete Response {} " + response.toString());
httpClient.close();
} catch (Exception e) {
logger.error("Exception ", e);
} finally {
IOUtils.closeQuietly(httpClient);
}
// Return the response back to caller
return new ResponseEntity<String>(response.toString(), HttpStatus.ACCEPTED);
For HttpClient v5, just use the below:
httpClient = HttpClientBuilder.create()
.setRedirectStrategy(new DefaultRedirectStrategy() {
#Override
public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context)
throws ProtocolException {
return false;
}
}).build();

Categories

Resources