Android 上的 HttpURLConnection 失败

2024-03-04

(已解决 - 请参阅下面的评论)

我有一个实现分段文件上传的类。该代码适用于我尝试过的每个 Java 客户端(Android 除外),并且它是我的 Android 应用程序中唯一不能与我的后端服务很好地配合的 HTTP 请求代码。

连接响应代码是“-1”,所以这里发生了一些非常令人讨厌的事情。 Apache 访问或错误日志中没有显示任何条目,似乎请求从未离开 Android 平台。代码通过连接写入正确执行,但在连接读取时挂起,超时然后返回。真实手机和模拟器的行为是相同的。

有谁知道在 Android 中发布多部分文件时需要注意的问题吗?

我包括下面的课程(做了一些小的卫生修改),这样你就可以看到我在做什么

import java.io.ByteArrayOutputStream;
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;

public class GeoPictureUploader
{
    static String serviceDomain = "http://staging.abaqus.net";
    static String postUrl = serviceDomain + "/geo/upl/wupload/pictures";
    static String CRLF = "\r\n"; 
    static String twoHyphens = "--"; 
    static String boundary = "*****mgd*****"; 

    private String pictureFileName = null;
    private String name = null;
    private String password = null;
    private DataOutputStream dataStream = null;

    enum ReturnCode { noPicture, unknown, http201, http400, http401, http403, http404, http500};

    public GeoPictureUploader(String name, String password) 
    {
        this.name = name;
        this.password = password;
    }

    public static void setServiceDomain(String domainName)
    {
        serviceDomain = domainName;
    }

    public static String getServiceDomain()
    {
        return serviceDomain;
    }

    public ReturnCode uploadPicture(String pictureFileName)
    {
        this.pictureFileName = pictureFileName;
        File uploadFile = new File(pictureFileName); 

        if (uploadFile.exists())
            try 
            { 
                FileInputStream fileInputStream = new FileInputStream(uploadFile); 
                URL connectURL = new URL(postUrl);
                HttpURLConnection conn = (HttpURLConnection)connectURL.openConnection(); 

                conn.setDoInput(true); 
                conn.setDoOutput(true); 
                conn.setUseCaches(false); 
                conn.setRequestMethod("POST"); 

                conn.setRequestProperty("User-Agent", "myGeodiary-V1");
                conn.setRequestProperty("Connection","Keep-Alive"); 
                conn.setRequestProperty("Content-Type","multipart/form-data;boundary="+boundary); 

                conn.connect();

                dataStream = new DataOutputStream(conn.getOutputStream()); 

                writeFormField("login", name);
                writeFormField("password", password);
                writeFileField("photo1", pictureFileName, "image/jpg", fileInputStream);

                // final closing boundary line
                dataStream.writeBytes(twoHyphens + boundary + twoHyphens + CRLF); 

                fileInputStream.close(); 
                dataStream.flush(); 
                dataStream.close();
                dataStream = null;

                String response = getResponse(conn);
                int responseCode = conn.getResponseCode();

                if (response.contains("uploaded successfully"))
                    return ReturnCode.http201;
                else 
                    // for now assume bad name/password
                    return ReturnCode.http401; 
            } 
            catch (MalformedURLException mue) { 
                // Log.e(Tag, "error: " + mue.getMessage(), mue); 
                System.out.println("GeoPictureUploader.uploadPicture: Malformed URL: " + mue.getMessage());
                return ReturnCode.http400;
            } 
            catch (IOException ioe) { 
                // Log.e(Tag, "error: " + ioe.getMessage(), ioe); 
                System.out.println("GeoPictureUploader.uploadPicture: IOE: " + ioe.getMessage());
                return ReturnCode.http500;
            } 
            catch (Exception e) { 
                // Log.e(Tag, "error: " + ioe.getMessage(), ioe); 
                System.out.println("GeoPictureUploader.uploadPicture: unknown: " + e.getMessage());
                return ReturnCode.unknown;
            } 
        else 
        {
            return ReturnCode.noPicture;  
        }
    }

    /**
     * @param conn
     * @return
     */
    private String getResponse(HttpURLConnection conn)
    {
        try 
        {
            DataInputStream dis = new DataInputStream(conn.getInputStream()); 
            byte []        data = new byte[1024];
            int             len = dis.read(data, 0, 1024);

            dis.close();
            int responseCode = conn.getResponseCode();

            if (len > 0)
                return new String(data, 0, len);
            else
                return "";
        }
        catch(Exception e)
        {
            System.out.println("GeoPictureUploader: biffed it getting HTTPResponse");
            //Log.e(TAG, "GeoPictureUploader: biffed it getting HTTPResponse");
            return "";
        }
    }

    /**
     *  this mode of reading response no good either
     */
    private String getResponseOrig(HttpURLConnection conn)
    {
        InputStream is = null;
        try 
        {
            is = conn.getInputStream(); 
            // scoop up the reply from the server
            int ch; 
            StringBuffer sb = new StringBuffer(); 
            while( ( ch = is.read() ) != -1 ) { 
                sb.append( (char)ch ); 
            } 
            return sb.toString();   // TODO Auto-generated method stub
        }
        catch(Exception e)
        {
            System.out.println("GeoPictureUploader: biffed it getting HTTPResponse");
            //Log.e(TAG, "GeoPictureUploader: biffed it getting HTTPResponse");
        }
        finally 
        {
            try {
            if (is != null)
                is.close();
            } catch (Exception e) {}
        }

        return "";
    }

    /**
     * write one form field to dataSream
     * @param fieldName
     * @param fieldValue
     */
    private void writeFormField(String fieldName, String fieldValue)
    {
        try
        {
            dataStream.writeBytes(twoHyphens + boundary + CRLF);    
            dataStream.writeBytes("Content-Disposition: form-data; name=\"" + fieldName + "\"" + CRLF);
            dataStream.writeBytes(CRLF);
            dataStream.writeBytes(fieldValue);
            dataStream.writeBytes(CRLF);
        }
        catch(Exception e)
        {
            System.out.println("GeoPictureUploader.writeFormField: got: " + e.getMessage());
            //Log.e(TAG, "GeoPictureUploader.writeFormField: got: " + e.getMessage());
        }
    }

    /**
     * write one file field to dataSream
     * @param fieldName - name of file field
     * @param fieldValue - file name
     * @param type - mime type
     * @param fileInputStream - stream of bytes that get sent up
     */
    private void writeFileField(
        String fieldName,
        String fieldValue,
        String type,
        FileInputStream fis)
    {
        try
        {
            // opening boundary line
            dataStream.writeBytes(twoHyphens + boundary + CRLF);    
            dataStream.writeBytes("Content-Disposition: form-data; name=\""
                                  + fieldName
                                  + "\";filename=\"" 
                                  + fieldValue
                                  + "\"" 
                                  + CRLF);
            dataStream.writeBytes("Content-Type: " + type +  CRLF);
            dataStream.writeBytes(CRLF); 

            // create a buffer of maximum size 
            int bytesAvailable = fis.available(); 
            int maxBufferSize = 1024; 
            int bufferSize = Math.min(bytesAvailable, maxBufferSize); 
            byte[] buffer = new byte[bufferSize]; 
            // read file and write it into form... 
            int bytesRead = fis.read(buffer, 0, bufferSize); 
            while (bytesRead > 0) 
            { 
                dataStream.write(buffer, 0, bufferSize); 
                bytesAvailable = fis.available(); 
                bufferSize = Math.min(bytesAvailable, maxBufferSize); 
                bytesRead = fis.read(buffer, 0, bufferSize); 
            } 

            // closing CRLF
            dataStream.writeBytes(CRLF);
        }
        catch(Exception e)
        {
            System.out.println("GeoPictureUploader.writeFormField: got: " + e.getMessage());
            //Log.e(TAG, "GeoPictureUploader.writeFormField: got: " + e.getMessage());
        }
    }


    /**
     * @param args
     */
    public static void main(String[] args)
    {
        if (args.length >= 0)
        {
            GeoPictureUploader gpu = new GeoPictureUploader("john", "notmyrealpassword");
            String picName = args[0];

            ReturnCode rc = gpu.uploadPicture(picName);
            System.out.printf("done");
        }
    }

}

你设置了互联网权限吗?在尝试调试帖子之前,我会确保简单的获取(使用 HTTPUrl 获取 google)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 上的 HttpURLConnection 失败 的相关文章

  • 让协程等待之前的调用

    我还没有完全掌握 Kotlin 协程 基本上我希望协程在执行之前等待任何先前的调用完成 下面的代码似乎可以工作 但它正在做我认为它正在做的事情吗 private var saveJob Job null fun save saveJob s
  • 从历史堆栈中删除活动

    我的应用程序在用户第一次运行应用程序时显示注册活动 如下所示 活动启动画面 欢迎来到游戏 注册帐户 ActivitySplashScreenSignUp 很好 填写此信息 ActivityGameMain 游戏主屏幕 因此 当用户单击每个屏
  • API29 上不推荐使用 setColorFilter

    我使用以下行来更改 VectorDrawable 的颜色 mydrawable getBackground setColorFilter color PorterDuff Mode SRC ATOP 这很好用 尽管它现在已被弃用 文档建议我
  • onScale 事件后触发奇怪的 onScroll 事件

    我有一个同时使用 SimpleOnScaleGestureListener 和 SimpleOnGestureListener 的应用程序 每当我进行捏缩放时 我都会得到预期的 onScale 但是当我抬起时 我会看到一个奇怪的 onScr
  • 位图内存不足错误

    我对这个错误有疑问 我从 URL 制作网站图标解析器 我这样做是这样的 public class GrabIconsFromWebPage public static String replaceUrl String url StringB
  • Google 地图删除标记路线上下文菜单

    我使用 Android Studio 的 Google 地图模板启动了一个新项目 并在地图上添加了一个标记 LatLng location new LatLng lat lng Marker marker mMap addMarker ne
  • 如何向开发人员发送崩溃报告?

    我开发 Android 应用程序 但在某些情况下我的应用程序force close 如果出现以下情况 我如何向开发人员发送包含详细信息的电子邮件force close随时发生 The ACRA https github com ACRA a
  • Android 版 jTwitter 授权错误

    我在我的 Android 应用程序中使用 jTwitter 库 直到前天一切都运转良好 但今天遇到异常 服务提供商响应错误 301 请帮助我 这是堆栈跟踪 02 21 21 07 27 258 E AndroidRuntime 4013 F
  • 使用 Android Studio 进行调试永远停留在“等待调试器”状态

    UPDATE The supposed重复是一个关于陷入 等待调试器 执行时Run 而这个问题就陷入了 等待调试器 执行时Debug 产生问题的步骤不同 解决方案也不同 每当我尝试使用Android Studio的调试功能时 运行状态总是停
  • 像 WhatsApp 一样发送图片

    我做了一个聊天应用程序 我想添加照片 文件共享我的应用程序中的概念与 WhatsApp 相同 我已经使用该应用程序制作了Xmpp Openfire目前我正在使用此功能进行照片共享 但它并不完全可靠 public void sendFile
  • 具有代理设置的 Android 模拟器 - 致命错误:.//android/base/sockets/ 检查失败:isValidFd(fd)。 FD 1404 最大1024

    需要使用代理设置运行模拟器 我在命令提示符中使用以下命令来启动模拟器 emulator avd AVD for 3 7 WVGA Nexus One http proxy http username password IP Port 如果没
  • android中listview显示数据库中的数据

    我是安卓新手 我想知道如何在列表视图中显示数据库中的数据 它不会向数据库添加数据 我只是显示我们存储在数据库中的任何内容 请帮助我实现这一目标 提前致谢 使用这些课程可能会对您有所帮助 用于数据库创建 package com example
  • TextInputLayout 对于在 EditText 中以编程方式给出提示没有效果

    我有一个 EditText 它的父级是 TextInputLayout 我试图以编程方式为 EditText 提供提示 不在布局中 在这种情况下 文本输入提示动画不起作用 它像简单的 EditText 一样工作 有人可以建议如何处理它吗 下
  • 屏幕开/关检测

    在这里 我试图确定屏幕是否打开 但按下电源锁定 解锁按钮时它似乎不起作用 应用程序运行没有错误 但 if else 中的代码似乎没有效果 Edited现在代码可以工作了 谢谢Olgun 但媒体播放器播放不会停止 并且每次在屏幕上 离屏时都会
  • Glass 语音命令给定列表中最接近的匹配项

    使用 Glass 您可以通过 确定 Glass 菜单启动应用程序 它似乎会选择最接近的匹配项 除非命令相距数英里 并且您可以明显看到命令列表 无论如何 是否可以从应用程序内或从语音提示 在初始应用程序触发后 给出类似的列表并返回最接近的匹配
  • 使用 WCF 支持“application/x-www-form-urlencoded”发布数据的最佳方式?

    我正在基于 W3C 规范构建 WCF 服务 该规范定义了接受 application x www form urlencoded 发布数据的 RESTful Web 服务端点 默认情况下 WCF 不支持这种类型的消息编码 我发现了许多创建如
  • 注册期间现有电子邮件的 422 或 409 状态代码

    我正在构建 RESTful API 遇到了一种情况 在用户注册期间 如果电子邮件已存在 则在422 and 409哪个http响应代码有意义 我浏览过类似的one https stackoverflow com questions 9269
  • 无法使用文件提供程序从内部存储打开 PDF 以便在 Android 8 和 9 上查看

    仅适用于 Android 8 和 9 我这里有一个 PDF 文件管理器 String url file storage emulated 0 Android data com verna poc files Download mypdf p
  • 在 Android 手机中通过耳机插孔发送数据

    我目前正在处理一个新项目 我必须通过具有特定电压的耳机插孔发送数据 然后我可以在该电压上工作 所以这里我需要根据我的数据来编程具体电压 我是否可以在android中访问耳机的输出电压 然后创建一个应用程序来控制该电压 这是一篇讨论此问题的
  • R.java是手动修改的!恢复到生成的版本

    我在布局中添加了一个 xml 文件 之后这个错误就来了 但问题是我还没有接触过 R java 文件 现在 在我的新活动中 我要将其内容视图设置为我新创建的 xml 文件 但是当我执行 R layout 时 新创建的 xml 不会出现在建议中

随机推荐