Téléchargement Base64 depuis Android / Java vers RoR Carrierwave

J'ai ajouté la solution à partir de l' utilisation de l'image base64 avec Carrierwave afin de télécharger une image d'une classe java. C'est maintenant à quoi ressemble ma classe FileUploader – et je crois être là où le problème est:

# encoding: utf-8 class FileUploader < CarrierWave::Uploader::Base # Include RMagick or MiniMagick support: include CarrierWave::RMagick # include CarrierWave::MiniMagick # Choose what kind of storage to use for this uploader: storage :file # storage :fog #START FROM BASE64 POST LINKED ABOVE class FilelessIO < StringIO attr_accessor :original_filename attr_accessor :content_type end before :cache, :convert_base64 def convert_base64(file) if file.respond_to?(:original_filename) && file.original_filename.match(/^base64:/) fname = file.original_filename.gsub(/^base64:/, '') ctype = file.content_type decoded = Base64.decode64(file.read) file.file.tempfile.close! decoded = FilelessIO.new(decoded) decoded.original_filename = fname decoded.content_type = ctype file.__send__ :file=, decoded end file end #END FROM POST LINKED ABOVE # Override the directory where uploaded files will be stored. # This is a sensible default for uploaders that are meant to be mounted: def store_dir "uploads/#{model.class.to_s.underscore}/#{model.user_id}" end # Provide a default URL as a default if there hasn't been a file uploaded: # def default_url # "/images/fallback/" + [version_name, "default.png"].compact.join('_') # end # Process files as they are uploaded: # process :scale => [200, 300] # # def scale(width, height) # # do something # end # Create different versions of your uploaded files: version :thumb do process :resize_to_fit => [200, 300] end version :web do process :resize_to_fit => [1000, 1000] end # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: def extension_white_list %w(jpg jpeg gif png) end # Override the filename of the uploaded files: # Avoid using model.id or version_name here, see uploader/store.rb for details. def filename if original_filename Time.new.to_i.to_s+"_"+original_filename end end end 

Le modèle d'image:

 class Picture < ActiveRecord::Base belongs_to :user belongs_to :folders attr_accessible :user_id, :picture_name, :picture_description, :folder_id, :picture_path, :file_save mount_uploader :picture_path, FileUploader before_save :update_pictures_attributes def update_pictures_attributes self.file_size = picture_path.file.size end end 

En ce moment, lorsque l'appel Post est effectué, le chemin du fichier qui est enregistré dans le db est nul, mais tout le reste est sauvegardé. Voici la classe java / Android:

 import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.http.client.*; import org.apache.http.client.entity.*; import org.apache.http.client.methods.*; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.*; import org.apache.http.message.*; import org.apache.commons.io.FileUtils; import org.json.*; import android.util.Base64; import android.util.Log; public class Uploader { private String url; private String fileName; public Uploader(String url, String fileName){ this.url = url; this.fileName = fileName; } public Boolean upload() throws JSONException, ClientProtocolException, IOException { Boolean success = true; JSONObject jsonObject = constructPictureJson(); DefaultHttpClient httpClient = new DefaultHttpClient(); ResponseHandler <String> responseHandler = new BasicResponseHandler(); HttpPost postMethod = new HttpPost(url); postMethod.setEntity(new StringEntity(jsonObject.toString())); postMethod.setHeader("Accept", "application/json"); postMethod.setHeader("Content-type", "application/json"); postMethod.setHeader("Data-type", "json"); try{ httpClient.execute(postMethod, responseHandler); } catch (org.apache.http.client.HttpResponseException error){ Log.d("Uploader Class Error", "Error code: "+error.getStatusCode()); Log.d("Uploader Class Error", "Error message: "+error.getMessage()); success = false; } //Log.d("server resposne", response); return success; } public JSONObject constructPictureJson() throws JSONException, IOException{ String userId = "1"; String folderId = "1"; String[] file = fileName.split("/"); JSONObject pictureData = new JSONObject(); pictureData.put("user_id", userId); pictureData.put("folder_id", folderId); pictureData.put("picture_name", "picture name"); pictureData.put("picture_description", "1"); pictureData.put("content_type", "jpg"); pictureData.put("original_filename", "base64:"+file[file.length-1]); pictureData.put("filename", file[file.length-1]); pictureData.put("picture_path", encodePicture(fileName)); return pictureData; } public String encodePicture(String fileName) throws IOException{ File picture = new File(fileName); return Base64.encodeToString(FileUtils.readFileToByteArray(picture), Base64.DEFAULT); } } 

Quelqu'un a-t-il une idée? J'ai été coincé sur cette journée toute la journée. Je pense que parce que je ne connais pas beaucoup de Ruby, je suis soit (1) malformer la demande; Ou (2) J'ai implémenté l'image base64 avec Carrierwave de manière incorrecte.

One Solution collect form web for “Téléchargement Base64 depuis Android / Java vers RoR Carrierwave”

Finalement résolu le problème! J'espère que cette réponse aidera les autres qui tentent de résoudre ce problème car il n'y a pas de bonne ressource. C'était surprenant, car je pensais que d'autres auraient voulu faire de même. Mes modifications d'origine dans le fichier d'initialisation Carrierwave semblent avoir été une impasse.

Il s'agissait de créer cet objet d'image téléchargé dans le contrôleur puis de l'injecter dans les paramètres.

Pour cet exemple spécifique, nous prenons un fichier base64 (que je suppose que vous avez, car JSON ne prend pas en charge les fichiers intégrés) et en le sauvegardant en tant que fichier temporaire dans le système, nous créons cet objet UploadedFile et enfin le réintroduisons dans le Params.

À quoi ressemble mon json / params:

 picture {:user_id => "1", :folder_id => 1, etc., :picture_path {:file => "base64 awesomeness", :original_filename => "my file name", :filename => "my file name"}} 

Voici à présent mon contrôleur maintenant:

 40 # POST /pictures 41 # POST /pictures.json 42 def create 43 44 #check if file is within picture_path 45 if params[:picture][:picture_path]["file"] 46 picture_path_params = params[:picture][:picture_path] 47 #create a new tempfile named fileupload 48 tempfile = Tempfile.new("fileupload") 49 tempfile.binmode 50 #get the file and decode it with base64 then write it to the tempfile 51 tempfile.write(Base64.decode64(picture_path_params["file"])) 52 53 #create a new uploaded file 54 uploaded_file = ActionDispatch::Http::UploadedFile.new(:tempfile => tempfile, :filename => picture_path_params["filename"], :original_filename => picture_path_params["original_filename"]) 55 56 #replace picture_path with the new uploaded file 57 params[:picture][:picture_path] = uploaded_file 58 59 end 60 61 @picture = Picture.new(params[:picture]) 62 63 respond_to do |format| 64 if @picture.save 65 format.html { redirect_to @picture, notice: 'Picture was successfully created.' } 66 format.json { render json: @picture, status: :created, location: @picture } 67 else 68 format.html { render action: "new" } 69 format.json { render json: @picture.errors, status: :unprocessable_entity } 70 end 71 end 72 end 

La seule chose à faire à ce stade, c'est de supprimer le fichier temporaire, ce qui, je crois, peut se faire avec tempfile.delete

J'espère que cela vous aidera avec votre question! J'ai passé toute la journée à trouver une solution hier, et tout ce que j'ai vu est une impasse. Ceci, cependant, fonctionne sur mes cas de test.

coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.