The problem of uploading files from Android app to spingMVC server

Keywords: Java encoding JSON Android

First, upload the code. The encapsulation tool class of the uploaded file is as follows:

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.UUID;


/**
 * Created by wishes on 2018/7/16.
 */

public class UploadUtil {


    public static final String TAG = UploadUtil.class.getName();

    private static final String CHARSET = "utf-8"; // Set encoding
    private static final int TIME_OUT = 8*1000;
    public static String result = null;
    /**
     * Android Upload files to the server
     *
     * @param file Files to upload
     * @param RequestURL Requested rul
     * @return Return the content of the response
     */
    public static String uploadFile(final File file, final String RequestURL) {

//        Thread thread = new Thread(new Runnable() {
//            @Override
//            public void run() {
                String result = null;
                String BOUNDARY = UUID.randomUUID().toString(); // Random generation of boundary markers
                String PREFIX = "--", LINE_END = "\r\n";
                String CONTENT_TYPE = "multipart/form-data"; // Content type
                try {
                    URL url = new URL(RequestURL);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();

                    conn.setReadTimeout(TIME_OUT);
                    conn.setConnectTimeout(TIME_OUT);
                    conn.setDoInput(true); // Allow input stream
                    conn.setDoOutput(true); // Allow output stream
                    conn.setUseCaches(false); // Cache not allowed
                    conn.setRequestMethod("POST"); // Request mode
                    conn.setRequestProperty("Charset", CHARSET); // Set encoding
                    conn.setRequestProperty("connection", "keep-alive");
                    conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY);


                    if (file != null) {
                        /**
                         * When the file is not empty, package and upload the file
                         */
                        DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
                        StringBuffer sb = new StringBuffer();
                        sb.append(PREFIX);
                        sb.append(BOUNDARY);
                        sb.append(LINE_END);
                        /**
                         * Note here: the value in name is the key required by the server. Only this key can get the corresponding file
                         * filename Is the name of the file, including the suffix, for example: abc.png
                         */

                        sb.append("Content-Disposition: form-data; name=\"upload\"; filename=\""
                                + file.getName() + "\"" + LINE_END);
                        sb.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINE_END);
                        sb.append(LINE_END);
                        dos.write(sb.toString().getBytes());
                        InputStream is = new FileInputStream(file);
                        byte[] bytes = new byte[1024];
                        int len = 0;
                        while ((len = is.read(bytes)) != -1) {
                            dos.write(bytes, 0, len);
                        }
                        is.close();
                        dos.write(LINE_END.getBytes());
                        byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes();
                        dos.write(end_data);
                        dos.flush();
                        /**
                         * Get response code 200 = success when the response is successful, get the flow of the response
                         */
                        int res = conn.getResponseCode();
                        LOG.i(TAG, "response code:" + res);
                        if(res==200)
                        {
                        LOG.i(TAG, "request success");
                        InputStream input = conn.getInputStream();
                        StringBuffer sb1 = new StringBuffer();
                        int ss;
                        while ((ss = input.read()) != -1) {
                            sb1.append((char) ss);
                        }
                        result = sb1.toString();
                        UploadUtil.result = new String(result.getBytes("iso-8859-1"),"utf-8");
                        LOG.i(TAG, "result : " + UploadUtil.result);
                            input.close();
                        }
                        else{
                             LOG.e(TAG, "request error");
                        }

                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

//            }
//        });
//        thread.start();
        LOG.i(TAG, "---"+UploadUtil.result+"---");
        return  UploadUtil.result;
    }


    /**
     * The request content is constructed by splicing to realize parameter transmission and file transmission
     *
     * @param url Service net address
     * @param params text content
     * @param files pictures
     * @return String result of Service response
     * @throws IOException
     */
    public static String post(String url, Map<String, String> params, Map<String, File> files)
            throws IOException {
        String BOUNDARY = java.util.UUID.randomUUID().toString();
        String PREFIX = "--", LINEND = "\r\n";
        String MULTIPART_FROM_DATA = "multipart/form-data";
        String CHARSET = "UTF-8";


        URL uri = new URL(url);
        HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
        conn.setReadTimeout(10 * 1000); // Maximum cache time
        conn.setDoInput(true);// Permissible input
        conn.setDoOutput(true);// Permissible output
        conn.setUseCaches(false); // Cache not allowed
        conn.setRequestMethod("POST");
        conn.setRequestProperty("connection", "keep-alive");
        conn.setRequestProperty("Charsert", "UTF-8");
        conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA + ";boundary=" + BOUNDARY);


        // First group the parameters of the text type
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            sb.append(PREFIX);
            sb.append(BOUNDARY);
            sb.append(LINEND);
            sb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINEND);
            sb.append("Content-Type: text/plain; charset=" + CHARSET + LINEND);
            sb.append("Content-Transfer-Encoding: 8bit" + LINEND);
            sb.append(LINEND);
            sb.append(entry.getValue());
            sb.append(LINEND);
        }


        DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
        outStream.write(sb.toString().getBytes());
        // Send file data
        if (files != null)
            for (Map.Entry<String, File> file : files.entrySet()) {
                StringBuilder sb1 = new StringBuilder();
                sb1.append(PREFIX);
                sb1.append(BOUNDARY);
                sb1.append(LINEND);
                sb1.append("Content-Disposition: form-data; name=\"upload\"; filename=\""
                        + file.getValue().getName() + "\"" + LINEND);
                sb1.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINEND);
                sb1.append(LINEND);
                outStream.write(sb1.toString().getBytes());


                InputStream is = new FileInputStream(file.getValue());
                byte[] buffer = new byte[1024];
                int len = 0;
                while ((len = is.read(buffer)) != -1) {
                    outStream.write(buffer, 0, len);
                }


                is.close();
                outStream.write(LINEND.getBytes());
            }


        // Request end flag
        byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
        outStream.write(end_data);
        outStream.flush();
        // Get response code
        int res = conn.getResponseCode();
        InputStream in = conn.getInputStream();
        StringBuilder sb2 = new StringBuilder();
        if (res == 200) {
            int ch;
            while ((ch = in.read()) != -1) {
                sb2.append((char) ch);
            }
        }
        outStream.close();
        conn.disconnect();
        return sb2.toString();
    }

}

This discussion is about the first method, the uploadFile method. When I first used this method to upload pictures, I used a thread to execute the network request operation (upload the file to the server) with most of the contents of this method body (the upper and lower codes were removed later). When I got the request result, I used a static variable result in this class to accept it and return it as the method return value. Here is the problem. The static variable result is assigned to the inner part of the process body, but it is a null value before returning. It is found that it is a thread problem later. Even if the static variables in this class are assigned in another thread, they will be cleared after the thread ends. (my guess) the solution is to remove the thread from this method. Add a thread to the call to this method. The code is as follows:

  new Thread(){

                      @Override
                      public void run() {
                          //Upload the picture to the server
                          try {
                              File appDir = new File(Environment.getExternalStorageDirectory(), Constants.APP_LOCAL_STORE);
                              if (!appDir.exists()) {
                                  appDir.mkdir();
                              }

                              File file = new File(appDir, "/portrait.jpg");
                              LOG.i(TAG,file.getName());

                              String requestURL = Constants.HOME_URL+"/app/user/uploadFile.htm";

                              String result = UploadUtil.uploadFile(file,requestURL);


                              JSONObject json = new JSONObject(result);
                              JSONObject json1 = json.getJSONObject("result");
                              LOG.i(TAG,json1.getString("url"));

                          }catch (Exception e){
                              e.printStackTrace();
                          }

                      }
                  }.start();

The above code is a common method written in activity. The above thread is a sub thread, which can be handled with Handle in the main thread, that is, after listening to the status of the sub thread, do the corresponding processing in Handle

Posted by jfdutcher on Thu, 13 Feb 2020 12:20:50 -0800