服务器关闭连接时的Java HttpUrlConnection响应代码

服务器关闭连接时的Java HttpUrlConnection响应代码,java,file-upload,httprequest,httpurlconnection,http-response-codes,Java,File Upload,Httprequest,Httpurlconnection,Http Response Codes,我正在使用HttpUrlConnection将文件从android上传到服务器。在正常情况下,文件上载成功并正确捕获HTTP响应代码(200)和消息。但服务器也会验证正在上载的文件,并可以在上载时随时关闭连接,从而禁止客户端将不必要的数据上载到服务器 简言之,服务器具有以下验证: 1。文件模拟类型检查: 如果文件MimeType不是任何图像MimeType,则立即关闭连接,抛出HTTP响应代码415和消息“Unsupported Media Type”。此检查在请求到达服务器后立即完成 2。文件

我正在使用HttpUrlConnection将文件从android上传到服务器。在正常情况下,文件上载成功并正确捕获HTTP响应代码(200)和消息。但服务器也会验证正在上载的文件,并可以在上载时随时关闭连接,从而禁止客户端将不必要的数据上载到服务器

简言之,服务器具有以下验证:

1。文件模拟类型检查: 如果文件MimeType不是任何图像MimeType,则立即关闭连接,抛出HTTP响应代码415和消息“Unsupported Media Type”。此检查在请求到达服务器后立即完成

2。文件大小检查: 当上传以流方式进行时,如果文件大小超过5 MB,则服务器通过抛出HTTP响应代码413和消息“请求实体太大”来关闭连接

当前状态:

  • 如果文件为图像类型且小于5 MB,则上载成功
  • 如果文件不是映像类型或大于5 MB,则无法从HttpUrlConnection对象获取HTTP响应代码(413或415)和消息。SocketException或IOException发生,然后调用
    connection.getResponseCode()
    会引发另一个异常。为什么不
    connection
    对象保存从服务器发送的响应代码和消息
  • 代码:

    package com.example.mahbub.fileuploadrnd;
    导入android.util.Log;
    导入com.example.mahbub.fileuploadrnd.util.MimeTypesUtil;
    导入java.io.BufferedReader;
    导入java.io.DataOutputStream;
    导入java.io.File;
    导入java.io.FileInputStream;
    导入java.io.IOException;
    导入java.io.InputStream;
    导入java.io.InputStreamReader;
    导入java.net.HttpURLConnection;
    导入java.net.SocketException;
    导入java.net.URL;
    导入java.util.HashMap;
    导入java.util.Map;
    导入java.util.Random;
    公共类FileUploadRequest{
    私有静态最终字符串DEBUG_TAG=“FileUploadRequest”;
    公共静态最终整数错误\u OUT\u OF \u内存=0x00;
    公共静态最终整数错误\u未定义=0x01;
    公共静态最终整数错误\u HTTP\u错误=0x02;
    /**
    *用于生成多部分边界的ASCII字符池。
    */
    私有最终静态字符[]多部分字符=
    “-1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ”。tocharray();
    私有静态最终字符串行\u END=“\r\n”;
    私有静态最终字符串双连字符=“--”;
    字符串url;
    mStringParts地图;
    字符串filePartName;
    字符串文件路径;
    上传监听器;
    公共FileUploadRequest(字符串url、字符串filePartName、字符串filePath、UploadListener侦听器){
    this.url=url;
    this.mStringParts=new HashMap();
    this.filePartName=filePartName;
    this.filePath=filePath;
    this.mListener=侦听器;
    }
    public void execute(){
    新线程(newrunnable()){
    @凌驾
    公开募捐{
    executeRequest();
    }
    }).start();
    }
    public void addStringPart(字符串名称、字符串值){
    this.mStringParts.put(名称、值);
    }
    公共无效addStringParts(地图零件){
    此.mStringParts.putAll(部分);
    }
    公共接口上传侦听器{
    void onSuccess(int-responseCode,String-response);
    无效onError(内部错误代码);
    无效转移(长转移,双进度);
    }
    私有void executeRequest(){
    HttpURLConnection=null;
    DataOutputStream outputStream=null;
    字符串边界=generateBoundary();
    试一试{
    URL=新URL(this.URL);
    connection=(HttpURLConnection)url.openConnection();
    //允许输入和输出
    connection.setDoInput(true);
    connection.setDoOutput(真);
    connection.setUseCaches(false);
    connection.setChunkedStreamingMode(4*1024);
    //启用POST方法
    connection.setRequestMethod(“POST”);
    //设置标题字段值
    setRequestProperty(“连接”,“保持活动”);
    connection.setRequestProperty(“内容类型”、“多部分/表单数据;边界=“+boundary”);
    outputStream=新的DataOutputStream(connection.getOutputStream());
    outputStream.writeBytes(两个连字符+边界+行尾);
    //首先写下所有的字符串部分
    如果(mStringParts.size()>0){
    对于(Map.Entry:mStringParts.entrySet()){
    //entity.addTextBody(entry.getKey(),entry.getValue());
    String partData=String.format(“内容配置:表单数据;名称=\%s\”,entry.getKey())+LINE\u END+LINE\u END;
    partData+=entry.getValue()+行结束;
    partData+=(两个连字符+边界+线端);
    outputStream.writeBytes(partData);
    }
    }
    //写入文件数据
    文件文件=新文件(文件路径);
    FileInputStream FileInputStream=新的FileInputStream(文件);
    String partData=String.format(“内容处置:表单数据;名称=\%s\”文件名=\%s\”,filePartName,file.getName())+行结束;
    partData+=String.format(“内容类型:%s”,getMimeType(file.getName());
    partData+=行\端+行\端;
    outputStream.writeBytes(partData);
    //输入流读取缓冲区
    字节[]缓冲区;
    //最大可能缓冲区大小
    int maxBufferSize=5*1024;//5KB
    //可写入输入流的字节数
    int bytesavable=fileInputStream.available();
    Log.d(DEBUG_标记,“文件大小:”+bytesavable);
    //缓冲区大小
    int bufferSize=Math.min(b
    
    package com.example.mahbub.fileuploadrnd;
    
    import android.util.Log;
    
    import com.example.mahbub.fileuploadrnd.util.MimeTypesUtil;
    
    import java.io.BufferedReader;
    import java.io.DataOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.HttpURLConnection;
    import java.net.SocketException;
    import java.net.URL;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Random;
    
    public class FileUploadRequest {
        private static final String DEBUG_TAG = "FileUploadRequest";
    
        public static final int ERROR_OUT_OF_MEMORY = 0x00;
        public static final int ERROR_UNDEFINED = 0x01;
        public static final int ERROR_HTTP_ERROR = 0x02;
    
        /**
         * The pool of ASCII chars to be used for generating a multipart boundary.
         */
        private final static char[] MULTIPART_CHARS =
            "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
        private static final String LINE_END = "\r\n";
        private static final String TWO_HYPHENS = "--";
    
        String url;
        Map<String,String> mStringParts;
        String filePartName;
        String filePath;
        UploadListener mListener;
    
        public FileUploadRequest(String url, String filePartName, String filePath, UploadListener listener) {
            this.url = url;
            this.mStringParts = new HashMap<>();
            this.filePartName = filePartName;
            this.filePath = filePath;
            this.mListener = listener;
        }
    
        public void execute() {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    executeRequest();
                }
            }).start();
        }
    
        public void addStringPart(String name, String value) {
            this.mStringParts.put(name, value);
        }
    
        public void addStringParts(Map<String, String> parts) {
            this.mStringParts.putAll(parts);
        }
    
        public interface UploadListener {
            void onSuccess(int responseCode, String response);
            void onError(int errorCode);
            void transferred(long transferred, double progress);
        }
    
        private void executeRequest() {
            HttpURLConnection connection = null;
            DataOutputStream outputStream = null;
    
            String boundary = generateBoundary();
    
            try {
                URL url = new URL(this.url);
                connection = (HttpURLConnection) url.openConnection();
    
                // Allow Inputs & Outputs
                connection.setDoInput(true);
                connection.setDoOutput(true);
                connection.setUseCaches(false);
                connection.setChunkedStreamingMode(4 * 1024);
                // Enable POST method
                connection.setRequestMethod("POST");
    
                // Set header field value
                connection.setRequestProperty("Connection", "Keep-Alive");
                connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
    
                outputStream = new DataOutputStream(connection.getOutputStream());
                outputStream.writeBytes(TWO_HYPHENS + boundary + LINE_END);
    
                // At first write all string parts
                if(mStringParts.size() > 0) {
                    for (Map.Entry<String, String> entry : mStringParts.entrySet()) {
                        //entity.addTextBody(entry.getKey(), entry.getValue());
                        String partData = String.format("Content-Disposition: form-data; name=\"%s\"", entry.getKey()) + LINE_END + LINE_END;
                        partData += entry.getValue() + LINE_END;
                        partData += (TWO_HYPHENS + boundary + LINE_END);
                        outputStream.writeBytes(partData);
                    }
                }
    
                // Write file data
                File file = new File(filePath);
                FileInputStream fileInputStream = new FileInputStream(file);
    
                String partData = String.format("Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"", filePartName, file.getName()) + LINE_END;
                partData += String.format("Content-Type: %s", getMimeType(file.getName()));
                partData += LINE_END + LINE_END;
                outputStream.writeBytes(partData);
    
                // Input stream read buffer
                byte[] buffer;
                // Max possible buffer size
                int maxBufferSize = 5 * 1024;   // 5KB
    
                // Bytes available to write in input stream
                int bytesAvailable = fileInputStream.available();
                Log.d(DEBUG_TAG, "File size: " + bytesAvailable);
                // Buffer size
                int bufferSize = Math.min(bytesAvailable, maxBufferSize);
                // Number of bytes read per read operation
                int bytesRead;
    
                // Allocate buffer
                buffer = new byte[bufferSize];
    
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);
    
                boolean errorOccured = false;
    
                try {
                    while(bytesRead > 0) {
                        try {
                            outputStream.write(buffer, 0, bufferSize);
                        } catch (OutOfMemoryError e) {
                            Log.d(DEBUG_TAG, "OutOfMemoryError occurred");
                            errorOccured = true;
                            e.printStackTrace();
                            if(null != mListener) mListener.onError(ERROR_OUT_OF_MEMORY);
                            break;
                        } catch (SocketException e) {
                            Log.d(DEBUG_TAG, "SocketException occurred");
                            errorOccured = true;
                            e.printStackTrace();
                            if(null != mListener) mListener.onError(ERROR_OUT_OF_MEMORY);
                            break;
                        } catch (IOException e) {
                            Log.d(DEBUG_TAG, "IOException occurred");
                            errorOccured = true;
                            e.printStackTrace();
                            if(null != mListener) mListener.onError(ERROR_OUT_OF_MEMORY);
                            break;
                        }
    
                        bytesAvailable = fileInputStream.available();
                        bufferSize = Math.min(bytesAvailable, maxBufferSize);
                        bytesRead = fileInputStream.read(buffer, 0, bufferSize);
    
                        double progress = ((double)(file.length()-bytesAvailable) / file.length());
                        Log.d(DEBUG_TAG, "Progress: " + progress);
                        if(null != mListener) mListener.transferred(file.length()-bytesAvailable, progress);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    if(null != mListener) mListener.onError(ERROR_UNDEFINED);
                }
                if(!errorOccured) {
                    outputStream.writeBytes(LINE_END);
                    outputStream.writeBytes(TWO_HYPHENS + boundary + TWO_HYPHENS + LINE_END);
                }
    
                // Responses from the server (code and message)
                int responseCode = connection.getResponseCode();
                String response = connection.getResponseMessage();
    
                Log.d(DEBUG_TAG, "Server Response Code: "  + responseCode);
                Log.d(DEBUG_TAG, "Server Response Message: " + response);
    
                InputStream inStream = null;
                if(responseCode >= 200 && responseCode < 400) inStream = connection.getInputStream();
                else inStream = connection.getErrorStream();
                String responseString = readStream(inStream);
                Log.d(DEBUG_TAG, "responseString: " + responseString);
                if(responseCode >= 200 && responseCode < 400) {
                    if(null != mListener) mListener.onSuccess(responseCode, responseString);
                } else {
                    if(null != mListener) mListener.onError(ERROR_HTTP_ERROR);
                }
    
                fileInputStream.close();
                outputStream.flush();
                outputStream.close();
                outputStream = null;
                inStream.close();
            } catch (Exception e) {
                e.printStackTrace();
                if(null != mListener) mListener.onError(ERROR_UNDEFINED);
            }
        }
    
        private String readStream(InputStream iStream) throws IOException {
            //build a Stream Reader, it can read char by char
            InputStreamReader iStreamReader = new InputStreamReader(iStream);
            //build a buffered Reader, so that i can read whole line at once
            BufferedReader bReader = new BufferedReader(iStreamReader);
            String line = null;
            StringBuilder builder = new StringBuilder();
            while((line = bReader.readLine()) != null) {  //Read till end
                builder.append(line);
            }
            bReader.close();         //close all opened stuff
            iStreamReader.close();
            //iStream.close(); //EDIT: Let the creator of the stream close it!
            // some readers may auto close the inner stream
            return builder.toString();
        }
    
        private String generateBoundary() {
            final StringBuilder buffer = new StringBuilder();
            final Random rand = new Random();
            final int count = rand.nextInt(11) + 30; // a random size from 30 to 40
            for (int i = 0; i < count; i++) {
                buffer.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]);
            }
            return buffer.toString();
        }
    
    
        /**
         * Get mimeType based on file extension
         * @param fileName
         * @return
         */
        private String getMimeType(String fileName) {
            String[] parts = fileName.split("\\.");
            if(parts.length <= 1) return null;
    
            return MimeTypesUtil.getMimeType(parts[parts.length-1]);
        }
    }