【问题标题】:Android Multipart file upload with access token使用访问令牌上传 Android 多部分文件
【发布时间】:2016-05-12 13:22:05
【问题描述】:

我想将访问令牌作为多部分数据连同文件一起发送到 php 服务器。我编写了以下代码,但它给出了 401 Unauthorized 错误。我想我没有通过 access_token。怎么做?

public class UploadToServer extends Activity {

    TextView messageText;
    TLConstants tlConstants;

    Button uploadButton;
    int serverResponseCode = 0;
    ProgressDialog dialog = null;

    String upLoadServerUri = null;

    /**********  File Path *************/
    final String uploadFilePath = "/mnt/sdcard/";
    final String uploadFileName = "service_lifecycle.png";

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_upload_to_server);

        uploadButton = (Button)findViewById(R.id.uploadButton);
        messageText  = (TextView)findViewById(R.id.messageText);

        tlConstants=new TLConstants();

        messageText.setText("Uploading file path :- '/mnt/sdcard/"+uploadFileName+"'");

        /************* Php script path ****************/

        upLoadServerUri = tlConstants.getURL(tlConstants.uploadFile);

        uploadButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                dialog = ProgressDialog.show(UploadToServer.this, "", "Uploading file...", true);

                new Thread(new Runnable() {
                    public void run() {
                        runOnUiThread(new Runnable() {
                            public void run() {
                                messageText.setText("uploading started.....");
                            }
                        });

                        uploadFile(uploadFilePath + "" + uploadFileName);

                    }
                }).start();
            }
        });
    }

    public int uploadFile(String sourceFileUri) {

        String fileName = sourceFileUri;

        HttpURLConnection conn = null;
        DataOutputStream dos = null;
        String lineEnd = "\r\n";
        String twoHyphens = "--";
        String boundary = "*****";
        int bytesRead, bytesAvailable, bufferSize;
        byte[] buffer;
        int maxBufferSize = 1 * 1024 * 1024;
        File sourceFile = new File(sourceFileUri);

        if (!sourceFile.isFile()) {

            dialog.dismiss();

            Log.e("uploadFile", "Source File not exist :"
                    +uploadFilePath + "" + uploadFileName);

            runOnUiThread(new Runnable() {
                public void run() {
                    messageText.setText("Source File not exist :"
                            +uploadFilePath + "" + uploadFileName);
                }
            });

            return 0;

        }
        else
        {
            try {

                // open a URL connection to the Servlet
                FileInputStream fileInputStream = new FileInputStream(sourceFile);
                URL url = new URL(upLoadServerUri);

                DatabaseHandler databaseHandler = new DatabaseHandler(getApplicationContext());
                HashMap<String, String> databaseMap = databaseHandler.getUserLoginAuthDetails();

                // Open a HTTP  connection to  the URL
                conn = (HttpURLConnection) url.openConnection();
                conn.setDoInput(true); // Allow Inputs
                conn.setDoOutput(true); // Allow Outputs
                conn.setUseCaches(false); // Don't use a Cached Copy
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Connection", "Keep-Alive");
                conn.setRequestProperty("ENCTYPE", "multipart/form-data");
                conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
                conn.setRequestProperty("file", fileName);


                String access_token= databaseMap.get("accesstoken");
                dos = new DataOutputStream(conn.getOutputStream());

                dos.writeBytes(twoHyphens + boundary + lineEnd);

                dos.write( ("Content-Disposition: form-data; name=\"" + "access_token" + "\"\r\n").getBytes());
                dos.write( ("\r\n" + access_token + "\r\n").getBytes());



                // create a buffer of  maximum size
                bytesAvailable = fileInputStream.available();

                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                buffer = new byte[bufferSize];

                // read file and write it into form...
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);

                while (bytesRead > 0) {

                    dos.write(buffer, 0, bufferSize);
                    bytesAvailable = fileInputStream.available();
                    bufferSize = Math.min(bytesAvailable, maxBufferSize);
                    bytesRead = fileInputStream.read(buffer, 0, bufferSize);

                }

                // send multipart form data necesssary after file data...
                dos.writeBytes(lineEnd);
                dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

                // Responses from the server (code and message)
                serverResponseCode = conn.getResponseCode();
                String serverResponseMessage = conn.getResponseMessage();


                Log.i("uploadFile", "HTTP Response is : "
                        + serverResponseMessage + ": " + serverResponseCode);

                if(serverResponseCode == 200){

                    runOnUiThread(new Runnable() {
                        public void run() {

                            String msg = "File Upload Completed.\n\n See uploaded file here : \n\n"
                                    +"../media/uploads/"
                                    +uploadFileName;

                            messageText.setText(msg);
                            Toast.makeText(UploadToServer.this, "File Upload Complete.",
                                    Toast.LENGTH_SHORT).show();
                        }
                    });
                }

                //close the streams //
                fileInputStream.close();
                dos.flush();
                dos.close();

            } catch (MalformedURLException ex) {

                dialog.dismiss();
                ex.printStackTrace();

                runOnUiThread(new Runnable() {
                    public void run() {
                        messageText.setText("MalformedURLException Exception : check script url.");
                        Toast.makeText(UploadToServer.this, "MalformedURLException",
                                Toast.LENGTH_SHORT).show();
                    }
                });

                Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
            } catch (Exception e) {

                dialog.dismiss();
                e.printStackTrace();

                runOnUiThread(new Runnable() {
                    public void run() {
                        messageText.setText("Got Exception : see logcat ");
                        Toast.makeText(UploadToServer.this, "Got Exception : see logcat ",
                                Toast.LENGTH_SHORT).show();
                    }
                });
                Log.e("Upload Exception", "Exception : "
                        + e.getMessage(), e);
            }
            dialog.dismiss();
            return serverResponseCode;

        } // End else block
    }
}

【问题讨论】:

    标签: java android file-upload multipart android-file


    【解决方案1】:

    这取决于服务器配置。通常,如果您需要通过 Http POST 传递授权令牌,则它会与带有 setHeader 的标头一起传递。这是我用于多部分文件上传的工作代码 sn-p。

    HttpClient client = new DefaultHttpClient();
    File file = new File(selectedImagePath);
    HttpPost post = new HttpPost(uploadUrl);
    
    post.setHeader("token", myAuthToken);
    post.setHeader("Content-type", "multipart/form-data; boundary=" + boundary);
    MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE,
                        Constants.BOUNDARY, Charset.defaultCharset());
    
    entity.addPart(Constants.MULTIPART_FORM_DATA_NAME, new FileBody(file));
    post.setHeader("Accept", "application/json");
    post.setHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
    
    post.setEntity(entity);
    
    HttpResponse response = client.execute(post);
    HttpEntity httpEntity = response.getEntity();
    Log.d("Response", EntityUtils.toString(httpEntity));
    

    【讨论】:

    • 感谢 Reaz 的帮助。你能告诉我如何在这里阅读回复吗?将不胜感激。提前致谢。
    • 请查看编辑后的答案。如果答案有帮助,请采纳并点赞。
    • 我尝试了您的代码并阅读了响应。服务器说它没有收到 access_token 参数。这是来自服务器的响应: { "error": "invalid_request", "error_description": "请求缺少必需的参数,包含无效的参数值,包含不止一次的参数,或者格式错误。检查\"访问令牌\" 参数。"我在您的代码中更改了这一行: post.setHeader("access_token", myAuthToken);
    • 看起来令牌应该作为参数而不是在标头中传递。
    【解决方案2】:

    使用服务上传多部分图片的工作副本:

    private MutipartImageUploadModel handleUploadAction(int tileId) {
            String imageName = getTilesInUploadPath(this, fileId);
            if (imageName == null) {
                return null;
            }
            InputStream responseInputStream;
            try {
                File filesDir = getApplicationContext().getFilesDir();
                File imageFile = new File(filesDir, imageName);
                HttpClient httpClient = new DefaultHttpClient();
                HttpContext localContext = new BasicHttpContext();
                double bytes = imageFile.length();
                HttpPost httpPost = new HttpPost(ServiceConstantInterface.URL_UPLOAD_IMAGE);            httpPost.setHeader(ServiceConstantInterface.Authorization_KEY, ServiceConstantInterface.Authorization_KEY_VALUE);
                httpPost.setHeader("SessionKey", new SharedPrefDataSupplier(this).getmSessionKey());
                MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
                entityBuilder.addPart("file_name", new FileBody(imageFile));
                entityBuilder.addPart("file_id", new StringBody(String.valueOf(fileId)));
                entityBuilder.addPart("SessionKey", new StringBody(new SharedPrefDataSupplier(getApplicationContext()).getmSessionKey()));
                HttpEntity entity = entityBuilder.build();
                httpPost.setEntity(entity);
                HttpResponse response = httpClient.execute(httpPost, localContext);
                StatusLine statusLine = response.getStatusLine();
                if (statusLine.getStatusCode() == 200) {
                    responseInputStream = response.getEntity().getContent();
                    if (responseInputStream != null) {
                        Reader reader = new InputStreamReader(responseInputStream);
                        Gson gson = new GsonBuilder().create();
                        MutipartImageUploadModel wResponse = gson.fromJson(reader, MutipartImageUploadModel.class);
                        Log.i(TAG, "Response " + wResponse);
                        try {
                            reader.close();
                            responseInputStream.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        return wResponse;
                    }
                } else {
                    Log.i(TAG, "Server responded with status code: " + statusLine.getStatusCode());
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
    
            }
            return null;
        }
    

    【讨论】:

      【解决方案3】:

      如果您打算发送一些标头、访问令牌、cookie,那么您应该在请求属性部分中进行设置,例如:

      // Open a HTTP  connection to  the URL
                  conn = (HttpURLConnection) url.openConnection();
                  conn.setDoInput(true); // Allow Inputs
                  conn.setDoOutput(true); // Allow Outputs
                  conn.setUseCaches(false); // Don't use a Cached Copy
                  conn.setRequestMethod("POST");
                  conn.setRequestProperty("Connection", "Keep-Alive");
                  conn.setRequestProperty("ENCTYPE", "multipart/form-data");
                  conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
                  conn.setRequestProperty("file", fileName);
                  **conn.setRequestProperty("COOKIE_NAME_OR_TOKEN", mToken);**
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-19
        • 2011-03-23
        • 2014-10-29
        • 2018-10-15
        • 2019-07-05
        • 1970-01-01
        • 2012-01-25
        • 1970-01-01
        相关资源
        最近更新 更多