I was having problem while saving picture in Django from Android app. I searched and finally solved the problem. I am sharing this so that it might help. Please see the answer below.
You will have to implement things according to your own specifications. I am just showing you as a generic example
I have used okHttp in my android app to send data on network (including pic)
Android AsyncTask Code (doInBackground Method)
RequestBody formBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("filename","filename",RequestBody.create(MediaType.parse("multipart/form-data"), new File(file.getPath())))
//.addFormDataPart("other_field", "other_field_value")
.build();
Request request = new Request.Builder()
.header("Authorization", "Token " + myToken)
.url(myUrl).post(formBody).build();
Response response = new OkHttpClient().newCall(request).execute();
return response.body().string();
My view.py Code
def rechargeapplication(request):
user=#get your own object
uploadpic = request.FILES['filename']
user.picture.save("image.jpg",uploadpic)
user.save()
return JsonResponse({'result':'Success'})
How I created imageField in models.py
picture=models.ImageField(upload_to="photos" , null=True, blank=True)
if you are using ImageField then you will have to install "Pillow"
Also make sure that you specify MEDIA_ROOT & MEDIA_URL in settings.py....I am showing you how I did it
MEDIA_ROOT=os.path.join(BASE_DIR,'media')
MEDIA_URL = '/media/'
and at the end of urls.py add this(as I was in debug mode that is why my implementation...)
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
Related
I sent image file and content (text) using retrofit from android client and tried to get them in the server side but can not do that and the error is always : it is null.
Please how can I send image and receive it using #Retrofit and Slim framework?
If anyone can help, I will appreciate.
..............................................
Tried to send the image from android client like a multipart file and receive it with slim using method (getUploadedFiles) and it didn't work.
#Multipart
#POST("createPostWithImage")
Call<DefaultResponse> uploadTestPost(
#Part("desc") RequestBody desc,
#Part MultipartBody.Part image
);
$app-> post('/createPostWithImage', function(Request $request, Response $response) {
$directory = __DIR__.'../photos/1';
$uploadedFiles = $request->getUploadedFiles();
$uploadedFile = $uploadedFiles['photo'];
$uploadedFile->moveTo($directory);
});
get the file which was sent from android client and save it into specific folder.
$app->post('/file', function($request,$response) {
try{
$directory = $this->get('upload_directory');
$uploadedFiles = $request->getUploadedFiles();
$uploadedFile = $uploadedFiles['example1'];
$extension = pathinfo($uploadedFile->getClientFilename(), PATHINFO_EXTENSION);
$basename = mt_rand(10000000, 99999999);
$uploadedFile->moveTo($directory . DIRECTORY_SEPARATOR . $basename.'.'.$extension);
return $response->withJson(array('message' =>$uploadedFile),200);
}
catch(\Exception $ex){
return $response->withJson(array('error' => $ex->getMessage()),422);
}
});
//minimal code to get started ...
I am using OKHttp to send multipart data. Here a piece is my code:
MultipartBody.Builder bodyBuilder = new MultipartBody.Builder();
bodyBuilder.setType(MultipartBody.FORM)
.addFormDataPart("arrival_to", object.optString("arrival_to"))
.addFormDataPart("centre_id", object.optString("centre_id"))
.addFormDataPart("departure_from", object.optString("departure_from"))
.addFormDataPart("expense_item_id", object.optString("expense_item_id"))
.addFormDataPart("expense_sub_item_id", object.getString("expense_sub_item_id"))
.addFormDataPart("file_list", object.optString("file_list"))
.addFormDataPart("journey_date", object.optString("journey_date"))
.addFormDataPart("passenger_age", object.optString("passenger_age"))
.addFormDataPart("passenger_gender", object.optString("passenger_gender"))
.addFormDataPart("passenger_name", object.optString("passenger_name"))
.addFormDataPart("personal_id", object.optString("personal_id"))
.addFormDataPart("remarks", object.optString("remarks"))
.addFormDataPart("request_amount", object.optString("request_amount"))
.addFormDataPart("request_status", object.optString("request_status"))
.addFormDataPart("travel_class", object.optString("travel_class"))
.addFormDataPart("vehicle_name_no", object.optString("vehicle_name_no"))
.addFormDataPart("vendor_id", object.optString("vendor_id"))
.addFormDataPart("vendor_type_id", object.optString("vendor_type_id"))
.addFormDataPart("within_budget", object.optString("within_budget"))
.addFormDataPart("file_list", attach_file, RequestBody.create(MediaType.parse(type), file))
.build();
The problem here is that I am adding the form data parts one by one which is ok here but I wanted to use a loop to add the form data part in case the dataset increased. Also I am making a seperate class containing the code to upload the data, how do I pass the key value pairs to that class should I use a Map?
Maybe something like this works?
MultipartBody.Builder bodyBuilder = new MultipartBody.Builder();
MultipartBody.Builder builder = bodyBuilder.setType(MultipartBody.FORM);
String[] keys = new String[]{
"arrival_to",
"centre_id",
"departure_from",
"expense_item_id",
"...."
};
Arrays.stream(keys)
.forEach(key -> {
builder.addFormDataPart(key, object.optString(key));
});
}
I'd like to send image from android app to node.js server to save into MongoDB on server side. I use AsyncHttpClient to post request.
My code is like this:
Android ->
RequestParams param = new RequestParams();
param.put("email", email);
param.put("image", file, "image/jpg");
System.out.println("Param : " + param);
HttpClient.post("uploadImg_Profile/", param, new AsyncHttpResponseHandler() {
Node.js ->
app.js->
app.post('/uploadImg_Profile/', function(req, res){
uploadImg_Profile.uploadImg_Profile(req, res);
})
uploadImg_Profile.js->
exports.uploadImg_Profile= function(req, res){
var User = new user({
email : req.body.email,
img : req.body.image
});
//
console.log("req : " + req);
console.log("email : "+ User.email);
console.log("image : " + User.img);
But console.log result is undefined. I respect that this is seen jhgdsfejdi734634jdhfdf like this BSON type result.
How can I get img data?
There is a way to get file's type from File object dynamically?
You need to use the right type of body parser in your node.js code - from the result you are getting, it looks as if you're not interpreting it as a multipart form.
You need to register the middleware to use to interpret the POST, for example, using the multer parser:
app.js:
var multer = require('multer');
app.use(bodyparser.json());
app.use(multer({ inMemory: true, putSingleFilesInArray: true }));
app.post('/uploadImg_Profile/', function(req, res){
uploadImg_Profile.uploadImg_Profile(req, res);
});
uploadImg_Profile.js:
exports.uploadImg_Profile= function(req, res){
var User = new user({
email : req.body.email,
img : req.files['image'][0].buffer
});
console.log("req : " + req);
console.log("email : "+ User.email);
console.log("image : " + User.img);
}
Multer will also populate various other properties about the file, so you should be able to retrieve the type of the image from that using:
req.files['image'][0].mimetype
See the multer page on github for all the goodness.
EDIT: Added bodyparser.json as well as multer.
It is solved.
It is possible that both app.use(bodyparser) and app.use(multer) are used simultaneously.
app.use(bodyparser.json())
app.use(multer())
Like this.
And my previous problem is another points.
I don't know exactly what make it doing. I just change express version from 3.x to 4.x and test various situation. In this progress, I find out that req has image buffer properly, and can get buffer data.
Thanks Mark and all of you intereted in my question.
I am posting the data from Android to the Node.js. I am successfully able to call the Node.js post method and using restify able to get the Post data.
But when doing through express I am not able to get the post body in Node.js. I tried for many approaches from SO post but it seems none are working may be I am missing something.
The snippets are like:
Node.js
var express = require('express')
var request = require('request')
var http = require('http')
var bodyParser = require('body-parser')
var app = express();
app.set('port', (process.env.PORT || 5000))
app.use(express.static(__dirname + '/public'))
app.use(bodyParser.urlencoded())
app.use(bodyParser.json())
app.post('/search/addcomplaint',addComplaint)
function addComplaint(req,res,next){
console.log(req.body);
if (!req.body) return res.sendStatus(400)
res.send(201,user)
}
app.listen(app.get('port'), function() {
console.log("Node app is running at localhost:" + app.get('port'))
})
at Android Site I am making a retrofit call like this:
#Multipart
#POST("/search/addcomplaint")
public User search(#Part("complaint") String complaint);
when I used restify in Node.js I was able to get req.body but using express I am not getting the request body.
I'm having an issue with a Multipart-form-data POST request using the Jersey Client API on Android. I've been following various examples on the web and they are all fairly similar in regards to the implementation.
Client client = createClientInstance();
WebResource r = client.resource(BASEURL).path("DataUpload");
ClientResponse post;
try {
FormDataMultiPart multiPart = new FormDataMultiPart();
multiPart.field("account", account);
multiPart.field("checksum", checksum);
multiPart.bodyPart(new FileDataBodyPart("file", file, MediaType.APPLICATION_OCTET_STREAM_TYPE));
post = r.type(MediaType.MULTIPART_FORM_DATA)
.accept(MediaType.TEXT_PLAIN)
.post(ClientResponse.class, multiPart);
} catch (ClientHandlerException e) {
Log.e(TAG, e.getLocalizedMessage());
} finally {
client.destroy();
}
When I execute this code on my device, I am presented with an exception:
javax.ws.rs.WebApplicationException: java.lang.IllegalArgumentException: No MessageBodyWriter for body part of type 'java.io.File' and media type 'application/octet-stream'
I thought Jersey was supposed to handle File objects without any extra configuration. Removing the bodypart line will allow Jersey to make the request but that eliminates the point of this.
I have these libraries on my buildpath (which were pulled in with Maven):
jersey-client-1.14
jersey-core-1.14
jersey-multipart-1.14
mimepull-1-6
I can suggest two things to try:
remove the MIME type from the FileDataBodyPart construction to see if Jersey can find a mime type it is happy to default to :
multiPart.bodyPart(new FileDataBodyPart("file", file, MediaType.APPLICATION_OCTET_STREAM_TYPE));
tell your client config about the multipart body writer (presumably inside your createClientInstance() method) :
com.sun.jersey.api.client.config.ClientConfig config = new com.sun.jersey.api.client.config.DefaultClientConfig();
config.getClasses().add(MultiPartWriter.class);
client = Client.create(config);
Hope that helps.