I am using MultipartEntity upload image with data, but I am unable to post. I have to post some details along with image. I don't know where is the problem, and also debug my code when hitting the post it not working. I don't know how to solve this problem.
File file1 = new File(selectedPath1);
String urlString = "url";
try
{
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(urlString);
FileBody bin1 = new FileBody(file1);
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("uploadedfile", bin1);
reqEntity.addPart("Firstname", new StringBody("Firstname"));
reqEntity.addPart("Mobilenumber", new StringBody("Mobilenumber"));
post.setEntity(reqEntity);
HttpResponse response = client.execute(post);
resEntity = response.getEntity();
final String response_str = EntityUtils.toString(resEntity);
if (resEntity != null) {
Log.i("RESPONSE",response_str);
runOnUiThread(new Runnable(){
public void run() {
try {
res.setTextColor(Color.GREEN);
res.setText("n Response from server : n " + response_str);
Toast.makeText(getApplicationContext(),"Upload Complete. Check the server uploads directory.", Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
catch (Exception ex){
Log.e("Debug", "error: " + ex.getMessage(), ex);
}
After a long time research, i was able to post image with data to the server.I am follow the below link and modify as my requirement.I think this is helpful to anyone.It is very useful to capture a picture and also i am able to post image with data by using this link
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(urlString);
try {
CustomMultiPartEntity entity=new CustomMultiPartEntity(new CustomMultiPartEntity.ProgressListener() {
#Override
public void transferred(long num) {
publishProgress((int) ((num / (float) totalSize) * 100));
}
});
entity.addPart("FirstName", new StringBody(Person.getFirstName()));
entity.addPart("LastName", new StringBody(Person.getLastName()));
entity.addPart("Email", new StringBody(Person.getEmail()));
entity.addPart("Password", new StringBody(Person.getPassword()));
entity.addPart("Mobilenumber", new StringBody(Person.getMobilenumber()));
entity.addPart("uploadedfile", new FileBody(sourceFile));
totalSize = entity.getContentLength();
httppost.setEntity(entity);
HttpResponse response = httpclient.execute(httppost);
HttpEntity r_entity = response.getEntity();
responseString = EntityUtils.toString(r_entity);
} catch (ClientProtocolException e) {
responseString = e.toString();
} catch (IOException e) {
responseString = e.toString();
}
I'm trying to use Microsoft Face API. For that I have the following code that was given by Microsoft as a sample (at the end of this page https://dev.projectoxford.ai/docs/services/563879b61984550e40cbbe8d/operations/563879b61984550f30395236):
HttpClient httpclient = HttpClients.createDefault();
try {
URIBuilder builder = new URIBuilder("https://api.projectoxford.ai/face/v1.0/detect");
builder.setParameter("returnFaceId", "false");
builder.setParameter("returnFaceLandmarks", "false");
builder.setParameter("returnFaceAttributes", "age,gender");
URI uri = builder.build();
HttpPost request = new HttpPost(uri);
request.setHeader("Content-Type", "application/octet-stream");
request.setHeader("Ocp-Apim-Subscription-Key", "...");
String body = Base64.encodeBase64String(img);
StringEntity reqEntity = new StringEntity(body);
request.setEntity(reqEntity);
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null) {
System.out.println(EntityUtils.toString(entity));
return JsonParser.parse(EntityUtils.toString(entity));
}
} catch (URISyntaxException | IOException | ParseException e) {
System.out.println(e.getMessage());
}
return null;
but I get the following error:
{"error":{"code":"InvalidImage","message":"Decoding error, image format unsupported."}}
The image that I am using for tests is this one:
http://www.huntresearchgroup.org.uk/images/group/group_photo_2010.jpg
(found it on the internet in a quick search)
It respect all the requisits set by Microsoft, size and format... If I use it in the site it works https://www.projectoxford.ai/demo/face#detection
The String body from the convertion of my array of bytes to a string in base64 is also ok, I test it in this website: http://codebeautify.org/base64-to-image-converter
The error message it's quite simple, but I fail to see where I am worng. Anyone might know whats the problem?
UPDATE
The variable img:
img = Files.readAllBytes(Paths.get(imgPath));
I managed to discover the problem... Instead of:
String body = Base64.encodeBase64String(img);
StringEntity reqEntity = new StringEntity(body);
request.setEntity(reqEntity);
I needed to do:
ByteArrayEntity reqEntity = new ByteArrayEntity(img, ContentType.APPLICATION_OCTET_STREAM);
request.setEntity(reqEntity);
I think that the Documentation is outdated...
I made the following change. Instead of sending an encoded image, I am sending the URL for the image.
request.setHeader("Content-Type", "application/json");
request.setHeader("Ocp-Apim-Subscription-Key", "{YOUR_FACES_API_KEY}");
StringEntity reqEntity = new StringEntity("{ \"url\":\"http://www.huntresearchgroup.org.uk/images/group/group_photo_2010.jpg\" }");
request.setEntity(reqEntity);
This gets the response:
[{"faceRectangle":{"top":878,"left":2718,"width":312,"height":312},"faceAttributes":{"gender":"male","age":28.5}},{"faceRectangle":{"top":593,"left":573,"width":310,"height":310},"faceAttributes":{"gender":"male","age":27.5}},{"faceRectangle":{"top":1122,"left":1014,"width":294,"height":294},"faceAttributes":{"gender":"female","age":27.7}},{"faceRectangle":{"top":915,"left":1773,"width":277,"height":277},"faceAttributes":{"gender":"female","age":36.7}},{"faceRectangle":{"top":566,"left":1276,"width":269,"height":269},"faceAttributes":{"gender":"male","age":40.7}},{"faceRectangle":{"top":677,"left":2134,"width":257,"height":257},"faceAttributes":{"gender":"female","age":35.2}}]
Will work on sending an encoded image soon. Will update this post accordingly.
EDIT:
Downloading image from URL
String base64Img = null;
byte[] bytes = null;
String imgBinaryString = null;
String base64ImgBinaryString = null;
try {
URL url = new URL("http://www.businessstudynotes.com/wp-content/uploads/2015/09/Role-of-Group.jpg");
//"http://www.huntresearchgroup.org.uk/images/group/group_photo_2010.jpg");
BufferedImage image = ImageIO.read(url);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", baos);
bytes = baos.toByteArray();
StringBuilder sb = new StringBuilder();
for (byte by: bytes)
sb.append(Integer.toBinaryString(by & 0xFF));
imgBinaryString = sb.toString();
base64Img = Base64.getEncoder().encodeToString(bytes);
byte[] base64Bytes = base64Img.getBytes("UTF-8");
sb = new StringBuilder();
for (byte by: base64Bytes) {
sb.append(Integer.toBinaryString(by & 0xFF));
}
base64ImgBinaryString = sb.toString();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
System.out.println("Download issue");
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("ImageIO issue");
e.printStackTrace();
}
imgBinaryString contains a binary representation of the image; base64ImgBinaryString contains a binary representation of the Base 64 representation of the image.
To upload this image...
URI uri = builder.build(); // builder = new URIBuilder("https://api.projectoxford.ai/face/v1.0/detect");
HttpPost request = new HttpPost(uri);
request.setHeader("Content-Type", "application/octet-stream");
request.setHeader("Ocp-Apim-Subscription-Key", "{YOUR_FACES_API_KEY");
StringEntity reqEntity = new StringEntity(base64ImgBinaryString);
request.setEntity(reqEntity);
HttpResponse response = httpclient.execute(request);
Setting the StringEntity to both imgBinaryString and base64ImgBinaryString results in the same response...
{"error":{"code":"InvalidImage","message":"Decoding error, image format unsupported."}}
Now, the good stuff. This works...
ByteArrayEntity reqEntity = new ByteArrayEntity(bytes, ContentType.APPLICATION_OCTET_STREAM);
request.setEntity(reqEntity);
where bytes is the byte-array for the image; but a Base64 representation of this doesn't work. Someone really needs to update the documentation.
You could take a look at CognitiveJ, an open source library that will handle the communications & interactions with the MS faces API. If you don't want to use the library then you can have a look at the code to see what the REST API expects.
(disclosure - I'm the author of the library).
import okhttp3.*;
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
doRequest();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void doRequest() throws IOException {
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(MediaType.parse("application/octet-stream"),
new File(".//src//main//java//Archivo_001.png"));
Request request = new Request.Builder()
.url("https://westcentralus.api.cognitive.microsoft.com/face/v1.0/detect?returnFaceId=true&returnFaceLandmarks=false&returnFaceAttributes=age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise")
.post(body)
.addHeader("Ocp-Apim-Subscription-Key", "1d88f949af3443ea8cc16b7146bd7501")
.addHeader("Content-Type", "application/json")
.addHeader("cache-control", "no-cache")
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
}
}
Hoping that this answer would be helpful to someone in the future, since I struggled with this quite a bit before finding this thread and realising the issue was on the documentation.
I managed to get the octet-stream type request working with HttpClient and RestTemplate.
HttpClient version:
HttpClient httpclient = HttpClients.createDefault();
try
{
URIBuilder builder = new URIBuilder(String.format("https://%s.api.cognitive.microsoft.com/face/v1.0/detect", region));
List<String> faceAttributes = Arrays.asList("age","gender","headPose","smile","facialHair","glasses","emotion","hair","makeup","occlusion","accessories","blur","exposure","noise");
String faceAttributesCommaSeparated = String.join(",", faceAttributes);
builder.setParameter("returnFaceId", "true");
builder.setParameter("returnFaceLandmarks", "false");
builder.setParameter("returnFaceAttributes", faceAttributesCommaSeparated);
URI uri = builder.build();
HttpPost request = new HttpPost(uri);
request.setHeader("Content-Type", "application/octet-stream");
request.setHeader("Ocp-Apim-Subscription-Key", subscriptionKey);
ByteArrayEntity reqEntity = new ByteArrayEntity(fileContentBytes, ContentType.APPLICATION_OCTET_STREAM);
request.setEntity(reqEntity);
HttpResponse response = httpclient.execute(request);
HttpEntity entity = (HttpEntity) response.getEntity();
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
RestTemplate:
private RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.add("Ocp-Apim-Subscription-Key", subscriptionKey);
List<String> faceAttributes = Arrays.asList("age","gender","headPose","smile","facialHair","glasses","emotion","hair","makeup","occlusion","accessories","blur","exposure","noise");
String faceAttributesCommaSeparated = String.join(",", faceAttributes);
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("returnFaceId", "true");
paramsMap.add("returnFaceLandmarks", "false");
paramsMap.add("returnFaceAttributes", faceAttributesCommaSeparated);
HttpEntity<byte[]> requestEntity = new HttpEntity<>(fileContentBytes, headers);
ResponseEntity<String> response = null;
try {
response = restTemplate.exchange(
String.format("%s/face/v1.0/detect", endpoint),
HttpMethod.POST,
requestEntity,
String.class,
paramsMap
);
} catch (HttpClientErrorException e) {
e.printStackTrace();
}
I left some specific values as variables but the gist of it should be clear. I will be using the restTemplate version in production code with a few minor changes.
I have doubt for MultipartEntity.
First it is deprecated or not.
Second how to import MultipartEntity in my project.where to find jars.
I did add jars from Apache httpclient-4.4.1,httpcore-4.4.1,httpmime-4.4.1 into my project libs folder.
But i did not use multipartEntity any mistakes in my side please help me?
I want to upload image from android to spring controller.
Android code is:
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); // Timeout
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("userMO", jsonUserMo));
HttpPost post = new HttpPost(Constants.ROOTURL+"/media/uploadUserImage");
post.setHeader("Content-type", "multipart/form-data; boundary=***");
post.setEntity(new FileEntity(profileImage,"image/jpeg"));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
contactLists.append(rd.readLine());
} catch (Exception e) {
e.printStackTrace();
}
My Spring Controller :
#RequestMapping(value = { "/uploadUserImage" }, method = RequestMethod.POST)
public #ResponseBody
String uploadUserImage(#RequestParam(value = "uploadImg") MultipartFile file, #RequestParam("userMO") String userBO, HttpSession session, HttpServletRequest httpServletRequest) {
log.info("hitting image");
UserBO userBo = gson.fromJson(userBO, UserBO.class);
// jboss file location to store images
String filePath = httpServletRequest.getSession().getServletContext().getRealPath("/") + "\\resources\\userImages\\" + userBo.getRingeeUserId() + ".png";
String fileName = file.getOriginalFilename();
try {
if (!file.isEmpty() && file.getBytes().length >= 5242880) {
log.info("file size is "+file.getBytes());
}
if (!file.isEmpty()) {
BufferedImage originalImage = ImageIO.read(new ByteArrayInputStream(file.getBytes()));
BufferedImage resizedImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
// resizedImage = originalImage.getSubimage(x1, y1, w, h);
File destination = new File(filePath);
// save cropped image
ImageIO.write(resizedImage, "jpeg", destination);
}
} catch (Exception Exp) {
log.info("Upload image failure");
}
return "";
}
I got error in android "http status 400-RequiredMultipartFile parameter 'uploadImg' is not present"
How to solve this?
try {
MultipartEntity entity = new MultipartEntity();
entity.addPart("type", new StringBody("uploadImg"));
httppost.setEntity(entity);
HttpResponse response = httpclient.execute(httppost);
}
You should add the addPart property with your multipart entity in order to get the additional parameter which your servlet is expecting on the server end. uploadImg in your case is the additional parameter expecting by the server in your request. Hope it will resolve your problem.
In CKAN, I am trying to upload a file using java client.But getting error code "400" but not showing any error log. I have done CKAN setup locally on Centos7 system. Please help if any suggestion, thanks :)
protected String MultiPartPost(String path, String data)
throws CKANException {
String body = "";
String CKANrepos = "http://172.21.9.118:5000";
String CKANapiHeader="X-CKAN-API-Key";
String CKANapi = "api key";
//1st part
String generatedFilename=null;
HttpClient httpclient = new DefaultHttpClient();
String filename = "test.txt";
try {
// create new identifier for every file, use time
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyyMMMddHHmmss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
String date=dateFormatGmt.format(new Date());
generatedFilename=date +"/"+filename;
HttpGet getRequest = new HttpGet(this.CKANrepos+ "/api/storage/auth/form/"+generatedFilename);
getRequest.setHeader(CKANapiHeader, this.CKANapi);
HttpResponse response = httpclient.execute(getRequest);
int statusCode = response.getStatusLine().getStatusCode();
if(statusCode!=200){
throw new IllegalStateException("File reservation failed, server responded with code: "+statusCode+
"\n\nThe message was: "+body);
}
}catch (IOException ioe) {
System.out.println(ioe);
} finally {
httpclient.getConnectionManager().shutdown();
}
//2nd part
File file = new File("D:\\test.txt");
httpclient = new DefaultHttpClient();
try {
FileBody bin = new FileBody(file,"text/html");
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("file", bin);
reqEntity.addPart("key", new StringBody(generatedFilename));
HttpPost postRequest = new HttpPost(this.CKANrepos+"/storage/upload_handle");
postRequest.setEntity(reqEntity);
postRequest.setHeader(CKANapiHeader, this.CKANapi);
HttpResponse response = httpclient.execute(postRequest);
int statusCode = response.getStatusLine().getStatusCode();
BufferedReader br = new BufferedReader(
new InputStreamReader((response.getEntity().getContent())));
String line;
while ((line = br.readLine()) != null) {
body += line;
}
if(statusCode!=200){
System.out.println("statusCode ==" +statusCode);
}
}catch (IOException ioe) {
System.out.println(ioe);
} finally {
httpclient.getConnectionManager().shutdown();
}
return body;
}
}
I'm trying to upload an image to a server.
Here is the code I wrote in Android to send the image file along with some other parameters to the server:
static String imagePath = "/storage/sdcard0/Pictures/image.jpg";
static String url = "http://example.com/api";
static String user_id = "99401";
public static void executeMultipartPost() 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);
FileBody fb = new FileBody(file);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addPart("user_id", new StringBody(user_id));
builder.addPart("type", new StringBody("single"));
builder.addPart("userfile", fb);
final HttpEntity entity = builder.build();
httppost.setEntity(entity);
Log.i(TAG, "Executing request: " + httppost.getRequestLine());
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
Log.i(TAG, ""+response.getStatusLine());
if (resEntity != null) {
Log.i(TAG, EntityUtils.toString(resEntity));
}
if (resEntity != null) {
resEntity.consumeContent();
}
httpclient.getConnectionManager().shutdown();
}
Everything works fine, except when it uploads to the server, the server receives an empty image. All I can see is a 0 byte image file. I guess something in the client code is not properly set.
The response I got in Logcat after executing the code is this, (from Laravel error Log):
<html><h2>Unhandled Exception</h2>
<h3>Message:</h3>
<pre>copy(): The first argument to copy() function cannot be a directory</pre>
<h3>Location:</h3>
<pre>/home/ked.ai/www/laravel/file.php on line 92</pre>
<h3>Stack Trace:</h3>
<pre>#0 /home/ked.ai/www/laravel/laravel.php(42): Laravel\Error::native(2, 'copy(): The fir...', '/home/ked.ai/ww...', 92)
#1 [internal function]: Laravel\{closure}(2, 'copy(): The fir...', '/home/ked.ai/ww...', 92, Array)
#2 /home/ked.ai/www/laravel/file.php(92): copy('/', '/home/ked.ai/ww...')
#3 /home/ked.ai/www/application/controllers/api2/item.php(190): Laravel\File::copy('/', '/home/ked.ai/ww...')
#4 [internal function]: Api2_Item_Controller->post_new()
#5 /home/ked.ai/www/laravel/routing/controller.php(325): call_user_func_array(Array, Array)
#6 /home/ked.ai/www/laravel/routing/controller.php(285): Laravel\Routing\Controller->response('new', Array)
#7 /home/ked.ai/www/laravel/routing/controller.php(165): Laravel\Routing\Controller->execute('new', Array)
#8 /home/ked.ai/www/laravel/routing/route.php(153): Laravel\Routing\Controller::call('api2.item#new', Array)
#9 /home/ked.ai/www/laravel/routing/route.php(124): Laravel\Routing\Route->response()
#10 /home/ked.ai/www/laravel/laravel.php(167): Laravel\Routing\Route->call()
#11 /home/ked.ai/www/public/index.php(34): require('/home/ked.ai/ww...')
#12 {main}</pre></html>
It seems like it passes a directory instead of a file. Any workaround?
I've managed to find the solution.
I only have to change this line
builder.addPart("userfile", fb);
to
builder.addPart("userfile[]", fb);
because on the server side, $_FILES['userfile'] receives array type.
Thank you.
You can use this method to pass the images to php server.
convert the image to base64 string using Base64.encodeBytes(byte_data).
In the server side php code convert that base64 string to image by base64_decode(str).
Its Working code :
public void executeMultipartPost() throws Exception {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bm.compress(CompressFormat.JPEG, 75, bos);
byte[] data = bos.toByteArray();
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost(url_path);
ByteArrayBody bab = new ByteArrayBody(data, "forest.jpg");
// File file= new File("/mnt/sdcard/forest.png");
// FileBody bin = new FileBody(file);
MultipartEntity reqEntity = new MultipartEntity(
HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("file", bab);
reqEntity.addPart("category ", new StringBody("1"));
reqEntity.addPart("user_id ", new StringBody("55"));
postRequest.setEntity(reqEntity);
HttpResponse response = httpClient.execute(postRequest);
String my_response = convertStreamToString(response.getEntity()
.getContent());
Toast.makeText(getApplicationContext(), my_response,
Toast.LENGTH_LONG).show();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
public static String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
Try it .