gpt4 book ai didi

java - Base64 从 Android/Java 上传到 RoR Carrierwave

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:52:43 26 4
gpt4 key购买 nike

我添加了来自 use base64 image with Carrierwave 的解决方案努力从 java 类上传图像。这就是我的 FileUploader 类现在的样子——我相信这就是问题所在:

# 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

图片模型:

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

现在,当进行 Post 调用时,保存在数据库中的文件路径为 nil —— 但其他所有内容都已保存。这是 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);
}

}

有人有什么想法吗?我整天都被困在这个问题上。我认为因为我对 Ruby 了解不多,所以我要么 (1) 使请求变形;或 (2) 我错误地使用 Carrierwave 实现了 base64 图像。

最佳答案

终于解决问题了!我希望这个答案能帮助其他试图解决这个问题的人,因为没有好的资源。这令人惊讶,因为我认为其他人也会想这样做。我对 Carrierwave 初始化文件的原始更改似乎已进入死胡同。

归结为在 Controller 中创建上传的图像对象,然后将其注入(inject)回参数中。

对于这个具体的例子,我们正在获取一个 base64 文件(我假设你有,因为 JSON 不支持嵌入文件)并将其保存为系统中的临时文件,然后我们创建该 UploadedFile 对象并最终重新注入(inject)它进入参数。

我的 json/params 是什么样的:

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

这是我的 Controller 现在的样子:

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

此时唯一剩下要做的就是删除临时文件,我相信可以使用 tempfile.delete

希望对您的问题有所帮助!我昨天花了一整天的时间寻找解决方案,我看到的一切都是死胡同。但是,这适用于我的测试用例。

关于java - Base64 从 Android/Java 上传到 RoR Carrierwave,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9854916/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com