douluan5444 2016-08-19 12:53
浏览 72
已采纳

将图像从android上传到golang服务器并将其保存在mongodb中

I'm trying to upload an image from android device to my golang server and save it in db. If I understood correctly, first I need to deserialize bytes from request into Image{} struct, then persist it into db (I use mongodb) But i've got a panic with "image: unknown format"

Here are my code snippets:

client:

private File createImageFile() throws IOException {
    String imageFileName = "avatar";
    File storageDir = mViewManager.getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpeg",         /* suffix */
            storageDir      /* directory */
    );

    mCurrentPhotoPath = "file:" + image.getAbsolutePath();
    return image;
}

...

public void uploadAvatar(File avatar) {
    RequestBody avBody = RequestBody.create(MediaType.parse("image/*"), avatar);
    Call<Boolean> call = service.uploadAvatar(avBody);
    call.enqueue(new Callback<Boolean>() {
        @Override
        public void onResponse(Call<Boolean> call, Response<Boolean> response) {
        }

        @Override
        public void onFailure(Call<Boolean> call, Throwable t) {
        }
    });
}

...

@Multipart
@POST("profile/avatar/save")
Call<Boolean> uploadAvatar(@Part("file\"; filename=\"avatar.jpeg\" ") RequestBody avatar);

server:

func HandleAvatarSave(w http.ResponseWriter, r *http.Request) {
    data, err := ioutil.ReadAll(r.Body)
    if err != nil {
        panic(err)
    } else {
        //fmt.Println("data", data)
        buf := bytes.NewBuffer(data)
        if img, _, err := image.Decode(buf); err != nil {
            panic(err)
        } else {
            // persist data, not implemented yet
        }
    }
}

Thanks in advance!

  • 写回答

1条回答 默认 最新

  • dps123456789 2016-08-21 07:31
    关注

    I dont do Android, so cant assure you much. But I use the below golang implementation to upload a file.

    package main
    
    import (
        "io"
        "net/http"
        "os"
    )
    
    //Display the named template
    func display(w http.ResponseWriter, tmpl string, data interface{}) {
        templates.ExecuteTemplate(w, tmpl+".html", data)
    }
    
    //This is where the action happens.
    func uploadHandler(w http.ResponseWriter, r *http.Request) {
        switch r.Method {
        //POST takes the uploaded file(s) and saves it to disk.
        case "POST":
            //parse the multipart form in the request
            err := r.ParseMultipartForm(100000)
            if err != nil {
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
            }
    
            //get a ref to the parsed multipart form
            m := r.MultipartForm
    
            //get the *fileheaders
            files := m.File["myfiles"]
            for i, _ := range files {
                //for each fileheader, get a handle to the actual file
                file, err := files[i].Open()
                defer file.Close()
                if err != nil {
                    http.Error(w, err.Error(), http.StatusInternalServerError)
                    return
                }
                //create destination file making sure the path is writeable.
                dst, err := os.Create("/home/sanat/" + files[i].Filename)
                defer dst.Close()
                if err != nil {
                    http.Error(w, err.Error(), http.StatusInternalServerError)
                    return
                }
                //copy the uploaded file to the destination file
                if _, err := io.Copy(dst, file); err != nil {
                    http.Error(w, err.Error(), http.StatusInternalServerError)
                    return
                }
    
            }
            //display success message.
            display(w, "upload", "Upload successful.")
        default:
            w.WriteHeader(http.StatusMethodNotAllowed)
        }
    }
    
    func main() {
        http.HandleFunc("/upload", uploadHandler)
    
        //static file handler.
        http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("assets"))))
    
        //Listen on port 8080
        http.ListenAndServe(":8080", nil)
    }
    

    I quick google took me to this android snippet. You will need httpClient 4 or higher

    package com.isummation.fileupload;
    
    import java.io.BufferedReader;
    import java.io.ByteArrayOutputStream;
    import java.io.InputStreamReader;
    
    import org.apache.http.HttpResponse;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.mime.HttpMultipartMode;
    import org.apache.http.entity.mime.MultipartEntity;
    import org.apache.http.entity.mime.content.ByteArrayBody;
    import org.apache.http.entity.mime.content.StringBody;
    import org.apache.http.impl.client.DefaultHttpClient;
    
    import android.app.Activity;
    import android.graphics.Bitmap;
    import android.graphics.Bitmap.CompressFormat;
    import android.graphics.BitmapFactory;
    import android.os.Bundle;
    import android.util.Log;
    
    public class FileUpload extends Activity {
        Bitmap bm;
    
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            try {
                // bm = BitmapFactory.decodeResource(getResources(),
                // R.drawable.forest);
                bm = BitmapFactory.decodeFile("/sdcard/DCIM/forest.png");
                executeMultipartPost();
            } catch (Exception e) {
                Log.e(e.getClass().getName(), e.getMessage());
            }
        }
    
        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(
                        "http://10.0.2.2/cfc/iphoneWebservice.cfc?returnformat=json&amp;method=testUpload");
                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("uploaded", bab);
                reqEntity.addPart("photoCaption", new StringBody("sfsdfsdf"));
                postRequest.setEntity(reqEntity);
                HttpResponse response = httpClient.execute(postRequest);
                BufferedReader reader = new BufferedReader(new InputStreamReader(
                        response.getEntity().getContent(), "UTF-8"));
                String sResponse;
                StringBuilder s = new StringBuilder();
    
                while ((sResponse = reader.readLine()) != null) {
                    s = s.append(sResponse);
                }
                System.out.println("Response: " + s);
            } catch (Exception e) {
                // handle exception here
                Log.e(e.getClass().getName(), e.getMessage());
            }
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 oracle集群安装出bug
  • ¥15 关于#python#的问题:自动化测试
  • ¥20 问题请教!vue项目关于Nginx配置nonce安全策略的问题
  • ¥15 教务系统账号被盗号如何追溯设备
  • ¥20 delta降尺度方法,未来数据怎么降尺度
  • ¥15 c# 使用NPOI快速将datatable数据导入excel中指定sheet,要求快速高效
  • ¥15 再不同版本的系统上,TCP传输速度不一致
  • ¥15 高德地图点聚合中Marker的位置无法实时更新
  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题