passing InputStream as parameter to web service - java

I am trying to upload file but i am not doing it through html form. QueryParam and PathParam can't be used. So can anyone tell how to pass stream.
My HttPClient looks like:
try
{
HttpClient httpclient = new DefaultHttpClient();
InputStream stream=new FileInputStream(new File("C:/localstore/ankita/Desert.jpg"));
String url="http://localhost:8080/Cloud/webresources/fileupload";
HttpPost httppost = new HttpPost(url);
HttpResponse response = httpclient.execute(httppost);
}
catch(Exception e){}
and my web service class looks somewhat like:
#Path("/fileupload")
public class UploadFileService {
#POST
#Consumes(MediaType.APPLICATION_OCTET_STREAM)
public Response uploadFile(InputStream in) throws IOException
{
String uploadedFileLocation = "c://filestore/Desert.jpg" ;
// save it
saveToFile(in, uploadedFileLocation);
String output = "File uploaded via Jersey based RESTFul Webservice to: " + uploadedFileLocation;
return Response.status(200).entity(output).build();
}
// save uploaded file to new location
private void saveToFile(InputStream uploadedInputStream,String uploadedFileLocation)
{
try {
OutputStream out = null;
int read = 0;
byte[] bytes = new byte[1024];
out = new FileOutputStream(new File(uploadedFileLocation));
while ((read = uploadedInputStream.read(bytes)) != -1)
{
out.write(bytes, 0, read);
}
out.flush();
out.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
Can anyone help??
String url="http://localhost:8080/Cloud/webresources/fileupload";
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
InputStreamEntity reqEntity = new InputStreamEntity(new FileInputStream(new File("C:/localstore/ankita/Desert.jpg")), -1);
reqEntity.setContentType("binary/octet-stream");
reqEntity.setChunked(true); // Send in multiple parts if needed
httppost.setEntity(reqEntity);
HttpResponse response = httpclient.execute(httppost);
How web service will look like?

You can't do it that way. You can't pass a stream in an HTTP request, because streams are not serializable.
The way to do this is to is create an HttpEntity to wrap the stream (e.g. an InputStreamEntity) then attach it to the HttpPOST object using setEntity. Then the POST is sent, the client will read from your stream and send the bytes as the request's "POST data".

Related

Upload image to Spring Server API in Android

i'm traying to upload a image in Android App to my api, but i have this menssage:
"The current request is not a multipart request"
I've this code in my app android:
#Override
protected String doInBackground(String... uri) {
// url where the data will be posted
String postReceiverUrl = "http://...";
Log.v("TEST", "postURL: " + postReceiverUrl);
// HttpClient
HttpClient httpClient = new DefaultHttpClient();
// post header
HttpPost httpPost = new HttpPost(postReceiverUrl);
try {
// the URL where the file will be posted
File file = new File(mCurrentPhotoPath);
FileBody fileBody = new FileBody(file);
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("file", fileBody);
httpPost.setEntity(reqEntity);
// execute HTTP post request
HttpResponse response = httpClient.execute(httpPost);
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
String responseStr = EntityUtils.toString(resEntity).trim();
Log.v("TEST ", "Response: " + responseStr);
// you can add an if statement here and do other actions based on the response
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
And in my API i've this code:
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public
#ResponseBody
String handleFileUpload(#RequestParam(value = "file", required = false) MultipartFile file) {
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
File file1 = new File("test.jpg");
FileOutputStream fos = new FileOutputStream(file1);
BufferedOutputStream stream =
new BufferedOutputStream(fos);
stream.write(bytes);
stream.close();
System.out.println("The path is: ");
System.out.println(file1.getAbsolutePath());
System.out.println(file1.getPath());
return "You successfully uploaded \"test.jpg\"!";
} catch (Exception e) {
return "You failed to upload test.jpg => " + e.getMessage();
}
} else {
return "You failed to upload test.jpg because the file was empty.";
}
}
How can i do this?
May be the following code help to you to upload the image in server
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost(<server api url>);
MultipartEntity entity = new MultipartEntity();
File myFile = new File(<file_path>);
FileBody fileBody = new FileBody(myFile);
entity.addPart("upload_param_name",fileBody);
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost,
localContext);
HttpEntity r_entity = response.getEntity();
xmlString = EntityUtils.toString(r_entity);
Log.d("SOAP ", "Result : " + xmlString.toString());
Also for this, you have to use the .jar of apache-mine and httpmine in your apps libs folder.
Finally i convert the image in base64 and send to server how a String and in my Server reconvert to image.
Thanks!

Unsupported Media Type error while trying to upload image from Android client

I am learning Java REST web services and I am trying to upload an image file with Android. Below is the client and server code. I am getting Http Status code 415: The server refused this request because the request entity is in a format not supported by the requested resource for the requested method . What could be wrong? Thank you.
The Android client code looks like this:
HttpClient httpclient = new DefaultHttpClient();
FileBody fileContent = new FileBody(new File(
Environment.getExternalStorageDirectory() + File.separator
+ "Pictures/" + IMAGE_FILE_NAME));
MultipartEntity multipartEntity = new MultipartEntity();
multipartEntity.addPart("file", fileContent);
HttpResponse response = null;
try {
HttpPost httppost = new HttpPost(url);
httppost.setEntity(multipartEntity);
response = httpclient.execute(httppost);
} catch (Exception e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
and the server code looks like this:
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(
#FormDataParam("file") InputStream uploadedInputStream,
#FormDataParam("file") FormDataContentDisposition fileDetail) {
String uploadedFileLocation = "C://uploadedFiles/"
+ fileDetail.getFileName();
// save it
saveToFile(uploadedInputStream, uploadedFileLocation);
String output = "File uploaded via Jersey based RESTFul Webservice to: "
+ uploadedFileLocation;
return Response.status(200).entity(output).build();
}
I was finally able to resolve the issue. Below is the code that works. Thank you.
Bitmap bitmap = BitmapFactory.decodeFile(Environment
.getExternalStorageDirectory()
+ File.separator
+ "Pictures/" + IMAGE_FILE_NAME);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
byte[] byte_arr = stream.toByteArray();
ByteArrayBody fileBody = new ByteArrayBody(byte_arr,
"imageFileName.jpg");
MultipartEntity multipartEntity = new MultipartEntity(
HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntity.addPart("file", fileBody);
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = null;
try {
HttpPost httppost = new HttpPost(url);
httppost.setEntity(multipartEntity);
response = httpclient.execute(httppost);
} catch (Exception e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}

500 Internal server when trying to upload image to server

I am working on an application that allows the user to upload an image to server. I am getting 500 internal server error .I cant seem to find anything related to this error which would solve my problem. My code is as follows:
class RetreiveFeedTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... url){
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
Bitmap bitmap = drawable.getBitmap();
bitmap.compress(CompressFormat.JPEG, 50, bos);
byte[] data = bos.toByteArray();
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost("http://10.155.103.167:9090/RestServer/rest/todos");
String fileName = String.format("File_%d.jpg", new Date().getTime());
ByteArrayBody bab = new ByteArrayBody(data, fileName);
ContentBody mimePart = bab;
// File file= new File("/mnt/sdcard/forest.png");
// FileBody bin = new FileBody(file);
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("file", bab);
postRequest.setEntity(reqEntity);
postRequest.setHeader("Content-Type", "application/json");
int timeoutConnection = 60000;
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
int timeoutSocket = 60000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpConnectionParams.setTcpNoDelay(httpParameters, true);
HttpResponse response = httpClient.execute(postRequest);
BufferedReader reader = new BufferedReader(new InputStreamReader(
response.getEntity().getContent(), "UTF-8"));
String sResponse;
StringBuilder s = new StringBuilder();
System.out.println("Response: " + response.getStatusLine());
while ((sResponse = reader.readLine()) != null) {
s = s.append(sResponse);
}
txt.setText("NEW TEXT"+s);
} catch (Exception e) {
// handle exception here
e.printStackTrace();
System.out.println(e.toString());
}
return null;
}
}
All HTTP 5xx codes indicate a problem on the server side specifically; you're not getting a 4xx error like 400 Bad Request or 413 Request Entity Too Large that indicates that your client code is doing something wrong. Something on the server is going wrong (such as a misconfigured upload directory or a failed database connection), and you need to check your server logs to see what error messages are appearing.
Use this code to upload images It's working fine for me
public class UploadToServer extends AsyncTask<String, String, String>{
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... args){
String status="";
String URL = "";
try{
Log.d("Image Path ======",TakePicture.file.toString());
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(URL);
File file = new File(TakePicture.file.toString());
FileBody bin = new FileBody(file);
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("Content-Disposition", new StringBody("form-data"));
reqEntity.addPart("name", new StringBody("Test"));
reqEntity.addPart("filename", bin);
reqEntity.addPart("Content-Type", new StringBody("image/jpg"));
httppost.setEntity(reqEntity);
Log.d("Executing Request ", httppost.getRequestLine().toString());
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
Log.d("Response content length: ",resEntity.getContentLength()+"");
if(resEntity.getContentLength()>0) {
status= EntityUtils.toString(resEntity);
} else {
status= "No Response from Server";
Log.d("Status----->",status);
}
} else {
status = "No Response from Server";
Log.d("Status----->",status);
}
} catch (Exception e) {
e.printStackTrace();
status = "Unable to connect with server";
}
return status;
}
#Override
protected void onPostExecute(String status) {
super.onPostExecute(status);
}
}

How to upload a file using Apache Commons file upload from a servlet?

I need to upload a xml file from server side, where the contents of a file is in a string. How can I make this file content to be uploaded (basically save) on the server?
This is what I am trying, which works fine, If i give a file directly to FileBody but how to trick it to have filecontents going to another servlet as multipart request?
private def createConfiguration(def sessiontoken)
{
def xmlString=""
HttpClient httpclient = new DefaultHttpClient();
try {
HttpPost httppost = new HttpPost(fileParams.create);
//FileBody bin = new FileBody(new File("C:\\Simon\\myxml.xml"));
StringBody st = new StringBody(sessiontoken);
StringBody cfgname = new StringBody(reqParams.c_Cfgname[0]);
StringBody cfgdesc = new StringBody(reqParams.c_Cfgdesc[0]);
StringBody cfgtype = new StringBody(reqParams.c_Cfgtype[0]);
StringBody cfgfile = new StringBody(reqParams.CFGFILE[0]);
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("sessiontoken", st);
reqEntity.addPart("cfgname", cfgname);
reqEntity.addPart("cfgdesc", cfgdesc);
reqEntity.addPart("cfgenv", cfgtype);
//reqEntity.addPart("cfgfile", bin);
reqEntity.addPart("cfgfile", cfgfile);
httppost.setEntity(reqEntity);
System.out.println("executing request " + httppost.getRequestLine());
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
System.out.println("----------------------------------------");
//System.out.println(response.getStatusLine());
if (resEntity != null) {
//System.out.println("Response content length: " + resEntity.getContentLength());
xmlString=resEntity.getContent().getText()
}
EntityUtils.consume(resEntity);
} finally {
try { httpclient.getConnectionManager().shutdown(); } catch (Exception ignore) {}
}
xmlString
}
If I use the above code I get the below Exception
----------------------------------------
Exception while processing your Request.
No result defined for action com.abc.dc.actions.CreateConfiguration and
result input
Update
So now after checking the tomcat logs & the other server side code, I came to know that that internally dc is getting cfgfile and setting it to
public void setCfgfile(File cfgfile)
{
this.cfgfile = cfgfile
}
which gives me
java.lang.NoSuchMethodException: com.abc.dc.actions.CreateConfiguration.setCfgfile([Ljava.lang.String;)
So how can I overload setCfgfile method with public void setCfgfile(String cfgfile) and convert cfgfile into a File object here?
or Even better,
How can I convert this cfgfile string variable into a FileBody object?
Finally here is how I made it to work :)
private def sendRequest(def sessiontoken,def sendUrl)
{
logger.debug("Inside sendRequest to: "+sendUrl)
def xmlString=""
HttpClient httpclient = new DefaultHttpClient();
try {
HttpPost httppost = new HttpPost(sendUrl);
def filename=reqParams.filename
logger.debug("Filename: "+filename)
FileBody bin = new FileBody(writeToFile(filename,reqParams.cfgfile));
StringBody st = new StringBody(sessiontoken);
StringBody cfgid=new StringBody("")
if(reqParams.containsKey('cfgfile')&&reqParams.cfgid!=null)
{
cfgid= new StringBody(reqParams.cfgid);
}
StringBody cfgname = new StringBody(reqParams.cfgname);
StringBody cfgdesc = new StringBody(reqParams.cfgdesc);
StringBody cfgenv = new StringBody(reqParams.cfgenv);
logger.debug("attaching multipart")
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("sessiontoken", st);
reqEntity.addPart("cfgid", cfgid);
reqEntity.addPart("cfgname", cfgname);
reqEntity.addPart("cfgdesc", cfgdesc);
reqEntity.addPart("cfgenv", cfgenv);
reqEntity.addPart("cfgfile", bin);
httppost.setEntity(reqEntity);
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
xmlString=resEntity.getContent().getText()
}
EntityUtils.consume(resEntity);
} finally {
try { httpclient.getConnectionManager().shutdown(); } catch (Exception ignore) {}
}
xmlString
}

android/rails multipart upload problem

My problem is that I try to upload an image and some text values to an rails server, and the text values end up as files, insted of just param values.
How the post looks on the server
Parameters: {"action"=>"create", "controller"=>"problems",
"problem"=>{"lon"=>#File:/tmp/RackMultipart20100404-598-8pi1vj-0>,
"photos_attributes"=>{"0"=>{"image"=>#File:/tmp/RackMultipart20100404-598-pak6jk-0>}},
"subject"=>#File:/tmp/RackMultipart20100404-598-nje11p-0>,
"category_id"=>#File:/tmp/RackMultipart20100404-598-ijy1oo-0>,
"lat"=>#File:/tmp/RackMultipart20100404-598-1a7140w-0>,
"email"=>#File:/tmp/RackMultipart20100404-598-1b7w6jp-0>}}
part of the android code
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("problem[category_id]", 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 {
}
That's just the way Rails does multipart form data.
For convenience I added this before_filter in my ApplicationController:
def read_and_parse_json_file_params
file_params = params.select { |name,value| value.is_a?(File) || value.is_a?(Tempfile) }
file_params.reject! { |name,file| file.content_type !~ %r{^application/json} }
file_params.each do |name,file|
file.rewind
params[name] = ActiveSupport::JSON.decode(file.read)
end
end
which parses each part into a JSON hash.

Categories