I'm dealing with the following problem: when trying to upload an image through MultiPart Entity and it seems that the several updates on HttpClient/MIME are cracking everything. I'm trying the following code, but it fails with a NoClassDefFoundError:
public static void executeMultipartPost(File image, ArrayList<Cookie> cookies, String myUrlToPost) {
try {
// my post instance
HttpPost httppost = new HttpPost(myUrlToPost);
// setting cookies for the connection session
if (cookies != null && cookies.size() > 0) {
String cookieString = "";
for (int i=0; i<cookies.size(); ++i) {
cookieString += cookies.get(i).getName()+"="+cookies.get(i).getValue()+";";
}
cookieString += "domain=" + BaseUrl + "; " + "path=/";
httppost.addHeader("Cookie", cookieString);
}
// creating the http client
HttpClient httpclient = new DefaultHttpClient();
// creating the multientity part [ERROR OCCURS IN THIS BELLOW LINE]
MultipartEntity multipartEntity = new MultipartEntity();
multipartEntity.addPart("photoupload", new FileBody(image));
httppost.setEntity(multipartEntity);
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
} catch (Exception e) {}
}
This method is fully compilable and uses the httpclient-4.0.1.jar and httpmime-4.2.jar libs, but again, it crashes on the commented line for me.
Am I missing something?
Ok, here you have libraries needed for Multipart post, all credits to Satya Komatineni and David Maclean, writers of Pro Android 3 and now 4 and I quote from their book
To do multipart POST calls, you need to get three additional Apache
open source projects: Apache Commons IO, Mime4j, and HttpMime. You
can download these projects from the following web sites: Commons
IO: http://commons.apache.org/io/ Mime4j:
http://james.apache.org/mime4j/ HttpMime:
http://hc.apache.org/downloads.cgi (inside of HttpClient)
I have the same problem and it was fixed by moving jars files into 'libs' directory in your android project.
Make sure the jar is checked in the projects build path. (Project -> Properties)
Related
I'm trying to set a cookie in a Http Request, but I can't figure out how to implement it:
HttpGet getReq = new HttpGet("https://www.myexample.com");
getReq.setHeader("mycookie", "customvalue123");
HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(getReq);
result = EntityUtils.toString(response.getEntity());
Log.e("RESPONSE", "GET RESPONSE: " + result);
My library is specificly this:
android {
useLibrary 'org.apache.http.legacy'
}
When it comes to make get or post requests, to get responses, no problem for me, but sending a simple cookie seems to be a very weird matter (considering that nothing about org.apache.http.legacy is on the internet about cookies). Thanks!
Ok I found out the problem.
I post it here so it can be useful to those who will encounter the same topic.
The right way to set a cookie using org.apache.http.legacy library is this:
HttpGet getReq = new HttpGet("https://www.myexample.com");
getReq.setHeader("Cookie", "mycookie = customvalue123; mycookie2 = custom2");
HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(getReq);
result = EntityUtils.toString(response.getEntity());
Log.e("RESPONSE", "GET RESPONSE: " + result);
I've been struggling a bit on sending JSON objects from an application on android to a php file (hosted locally). The php bit is irrelevant to my issue as wireshark isn't recording any activity from my application (emulation in eclipse/ADK) and it's almost certainly to do with my method of sending:
try {
JSONObject json = new JSONObject();
json.put("id", "5");
json.put("time", "3:00");
json.put("date", "03.04.12");
HttpParams httpParams = new BasicHttpParams();
HttpClient client = new DefaultHttpClient(httpParams);
//
//String url = "http://10.0.2.2:8080/sample1/webservice2.php?" +
// "json={\"UserName\":1,\"FullName\":2}";
String url = "http://localhost/datarecieve.php";
HttpPost request = new HttpPost(url);
request.setEntity(new ByteArrayEntity(json.toString().getBytes(
"UTF8")));
request.setHeader("json", json.toString());
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
// If the response does not enclose an entity, there is no need
if (entity != null) {
InputStream instream = entity.getContent();
}
} catch (Throwable t) {
Toast.makeText(this, "Request failed: " + t.toString(),
Toast.LENGTH_LONG).show();
}
I've modified this from an example I found, so I'm sure I've taken some perfectly good code and mangled it. I understand the requirement for multi-threading so my application doesn't hang and die, but am unsure about the implementation of it. Would using Asynctask fix this issue, or have I missed something else important?
Thankyou for any help you can provide.
Assuming that you are using emulator to test the code, localhost refers to the emulated environment. If you need to access the php hosted on your computer, you need to use the IP 10.0.2.2 or the LAN IP such as 192.168.1.3. Check Referring to localhost from the emulated environment
You can refer to Keeping Your App Responsive to learn about running your long running operations in an AsyncTask
you should use asynctask or thread, because in higher versions of android it doesn't allow long running task like network operations from ui thread.
here is the link for more description
I have been trying to upload an image and data to Django server. I have included apache-mime4j.0.6.jar and httpmime4.0.1.jar libraries ( Project->build path->Add external jar files)
And here's the code to upload an image.
HttpResponse response = null;
try {
HttpPost httppost = new HttpPost("http://10.0.2.2:8000/mobile");
// HttpPost httppost = new HttpPost("some url");
MultipartEntity multipartEntity = new MultipartEntity(); //MultipartEntity multipartEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntity.addPart("name", new StringBody("nameText"));
multipartEntity.addPart("place", new StringBody("placeText"));
multipartEntity.addPart("tag", new StringBody("tagText"));
//multipartEntity.addPart("Description", new StringBody(Settings.SHARE.TEXT));
multipartEntity.addPart("Image", new FileBody(destination));
httppost.setEntity(multipartEntity);
httpclient.execute(httppost, new PhotoUploadResponseHandler());
} catch (Exception e) {
Log.e( "Error","error");
}
Error message:
Could not find class 'org.apache.http.entity.mime.MultipartEntity'
And I have tried manually creating libs folder and manually including jar files into /libs folder.
When I do that It fails to compile.
Error:
Conversion to Dalvik format failed with error 1 Unknown Android Packaging Problem
Tried creating fresh application including libraries. And I encountered the same error. I've tried everything possible. Can anyone tell me why this happens and how to fix it. Any help would be greatly appreciated!!
If you are using new android-sdk Try this.
Create folder named as libs
Paste your jar file in that folder.
And finally right click on your project > Build Path > Add External Archive.
That's it.This might help.Good Luck.
I upload an image from Android to a Django server using httpmime-4.2.1.jar. That is the only library that i have included and it works fine. Btw: libraries are supposed to be in the libs folder in Android projects.
this is the code that i am using for the upload.
private JSONObject uploadImage(String url, File img) throws Exception{
url = addAuthToken(url);
HttpPost post = new HttpPost(url);
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
FileBody fileBody = new FileBody(img, "images/jpeg");
reqEntity.addPart("image", fileBody);
post.setEntity(reqEntity);
JSONObject ret = baseRequest(post);
checkReturnStatus(ret, 201);
return ret;
}
private JSONObject baseRequest(HttpUriRequest request) throws Exception{
HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(request);
BufferedReader in = null;
try{
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer();
String line = null;
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
return new JSONObject(sb.toString());
}finally {
if(in != null) in.close();
}
}
I suggest you to use spring-android
It is a good rest api library for android and with spring-android, you can upload file easily like this.
HttpHeaders requestHeaders = ....
MultiValueMap<String, Object> message = new LinkedMultiValueMap<String, Object>();
message.add("qqfile", new FileSystemResource(filePath)); //attach file
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<MultiValueMap<String, Object>>(
message, requestHeaders);
RestTemplate restTemplate = RestUtil.getRestTemplate( context);
ResponseEntity<YourResultDTO> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity,YourResultDTO.class);
It is very easy to use and use Apache http client on pre gingerbread and java.net.urlconnection on gingerbread and higher api level as google suggests.
I had the same problem and I solved it this way: in the java build path window, click the Order and Export tab Highlight the library you want to add then click the up (upload lib to be first)
Click ok and everything is fine.
Here is a link with photos (Android Eclipse NoClassDefFoundError for external .jar files)
In my android application I am trying to cache the response of Http Client. I am testing this task using facebook graph api and have the following url: https://graph.facebook.com/riz.ahmed.52
For the first time I get the "first_name" and display it. Then I change the First Name of my facebook profile and call the same link again. I am expecting to get the old/cached "first_name" but I get the updated one. The console always shows the "The response came from an upstream server" message when I call the url.
My code for Http Client is as follows:
CacheConfig cacheConfig = new CacheConfig();
cacheConfig.setMaxCacheEntries(1000);
cacheConfig.setMaxObjectSizeBytes(8192);
//HttpClient httpclient = new CachingHttpClient(new DefaultHttpClient(), cacheConfig);
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
// Updated code [START]
httpclient.addResponseInterceptor(new HttpResponseInterceptor() {
public void process(
final HttpResponse response,
final HttpContext context) throws HttpException, IOException {
response.removeHeader(response.getFirstHeader("Pragma"));
response.removeHeader(response.getFirstHeader("Expires"));
}
});
// Updated code [END]
HttpGet httpget = new HttpGet(url);
// Execute HTTP Get Request
HttpResponse response = httpclient.execute(httpget, localContext);
HttpEntity entity = response.getEntity();
String res = EntityUtils.getContentCharSet(entity);
CacheResponseStatus responseStatus = (CacheResponseStatus) localContext.getAttribute(
CachingHttpClient.CACHE_RESPONSE_STATUS);
switch (responseStatus) {
case CACHE_HIT:
System.out.println("A response was generated from the cache with no requests " +
"sent upstream");
break;
case CACHE_MODULE_RESPONSE:
System.out.println("The response was generated directly by the caching module");
break;
case CACHE_MISS:
System.out.println("The response came from an upstream server");
break;
case VALIDATED:
System.out.println("The response was generated from the cache after validating " +
"the entry with the origin server");
break;
}
I am using Android 2.3.3. Please let me know what I am missing here
The page you are loading specifies a Expires:Sat, 01 Jan 2000 00:00:00 GMT header, i.e. it's always considered stale and must always be re-fetched.
Edit:
Also returns a Pragma: no-cache apparently. Basically, it's telling your HTTP client to never cache this page. You may be able to remove these headers with a HttpResponseInterceptor if you're dead-set on caching the response.
#2 Edit:
Using http-clientcache-4.2.jar is going to be problematic as it is not completely compatible with the version of the HTTP client packaged with the Android SDK - you're going to get NoClassDefFoundErrors and similar nonsense when using it.
However - if you "build-your-own" by downloading the source for clientcache-4.2 and strip out any unfulfilled references (such as refactoring the package name of the commons logging) & killing of all the annotations sprinkled throughout the code (etc.) you can probably get a working version. If you do, this worked:
class MakeCacheable implements HttpResponseInterceptor {
public static MakeCacheable INSTANCE = new MakeCacheable();
public void process(HttpResponse resp, HttpContext ctx) throws HttpException, IOException {
resp.removeHeaders("Expires");
resp.removeHeaders("Pragma");
resp.removeHeaders("Cache-Control");
}
}
Injected into the DefaultHttpClient used by the CachingHttpClient like so:
DefaultHttpClient realClient = new DefaultHttpClient();
realClient.addResponseInterceptor(MakeCacheable.INSTANCE, 0); // This goes first
CachingHttpClient httpClient = new CachingHttpClient(realClient, cacheConfig);
If an entry is cached or not is decided by the ResponseCachingPolicy which unfortunately is a final in the CachingHttpClient, but looking through it will show all the headers that need to go to make an un-cacheable entry cacheable.
As part of my Android app, I'd like to upload bitmaps to be remotely stored. I have simple HTTP GET and POST communication working perfectly, but documentation on how to do a multipart POST seems to be as rare as unicorns.
Furthermore, I'd like to transmit the image directly from memory, instead of working with a file. In the example code below, I'm getting a byte array from a file to be used later on with HttpClient and MultipartEntity.
File input = new File("climb.jpg");
byte[] data = new byte[(int)input.length()];
FileInputStream fis = new FileInputStream(input);
fis.read(data);
ByteArrayPartSource baps = new ByteArrayPartSource(input.getName(), data);
This all seems fairly clear to me, except that I can't for the life of me find out where to get this ByteArrayPartSource. I have linked to the httpclient and httpmime JAR files, but no dice. I hear that the package structure changed drastically between HttpClient 3.x and 4.x.
Is anyone using this ByteArrayPartSource in Android, and how did they import it?
After digging around in the documentation and scouring the Internet, I came up with something that fit my needs. To make a multipart request such as a form POST, the following code did the trick for me:
File input = new File("climb.jpg");
DefaultHttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://localhost:3000/routes");
MultipartEntity multi = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
String line;
multi.addPart("name", new StringBody("test"));
multi.addPart("grade", new StringBody("test"));
multi.addPart("quality", new StringBody("test"));
multi.addPart("latitude", new StringBody("40.74"));
multi.addPart("longitude", new StringBody("40.74"));
multi.addPart("photo", new FileBody(input));
post.setEntity(multi);
HttpResponse resp = client.execute(post);
The HTTPMultipartMode.BROWSER_COMPATIBLE bit is very important. Thanks to Radomir's blog on this one.
try this:
HttpClient httpClient = new DefaultHttpClient() ;
HttpPost httpPost = new HttpPost("http://example.com");
MultipartEntity entity = new MultipartEntity();
entity.addPart("file", new FileBody(file));
httpPost.setEntity(entity );
HttpResponse response = null;
try {
response = httpClient.execute(httpPost);
} catch (ClientProtocolException e) {
Log.e("ClientProtocolException : "+e, e.getMessage());
} catch (IOException e) {
Log.e("IOException : "+e, e.getMessage());
}
Perhaps you can do following step to import library into your Android.
requirement library
- apache-mime4j-0.6.jar
- httpmime-4.0.1.jar
Right click your project and click properties
select java build path
select tab called "Order and Export"
Apply it
Fully uninstall you apk file with the adb uninstall due to existing apk not cater for new library
install again your apk
run it
Thanks,
Jenz
I'm having the same problem. I'm trying to upload an image through MultiPart Entity and it seens that the several updates on HttpClient/MIME are cracking everything. I'm trying the following code, falling with an Error "NoClassDefFoundError":
public static void executeMultipartPost(File image, ArrayList<Cookie> cookies, String myUrlToPost) {
try {
// my post instance
HttpPost httppost = new HttpPost(myUrlToPost);
// setting cookies for the connection session
if (cookies != null && cookies.size() > 0) {
String cookieString = "";
for (int i=0; i<cookies.size(); ++i) {
cookieString += cookies.get(i).getName()+"="+cookies.get(i).getValue()+";";
}
cookieString += "domain=" + BaseUrl + "; " + "path=/";
httppost.addHeader("Cookie", cookieString);
}
// creating the http client
HttpClient httpclient = new DefaultHttpClient();
// creating the multientity part [ERROR OCCURS IN THIS BELLOW LINE]
MultipartEntity multipartEntity = new MultipartEntity();
multipartEntity.addPart("photoupload", new FileBody(image));
httppost.setEntity(multipartEntity);
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
} catch (Exception e) {}
}
This method is fully compilable and uses the httpclient-4.0.1.jar and httpmime-4.2.jar libs, but again, I remember that it crashs in the commented line for me.