You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Codename One上传图片至S3 Bucket失败:遇301错误与空指针异常

Codename One上传S3 Bucket遇301错误及空指针异常的解决

问题背景

参考Stack Overflow帖子在Codename One项目中上传图片到S3 Bucket,操作失败,出现301连接错误码和java.lang.NullPointerException异常。已通过Postman和JavaScript SDK成功上传,确认Bucket配置无问题,想知道是否需要AccessKey、SecretKey、AWS Region这类额外凭证。

代码示例

try {
        String strImage = Capture.capturePhoto(300, -1);              
        String s3Bucket = "https://s3.amazonaws.com/mybucketname/";
        String fileName = "testimg1.jpg";
        
        MultipartRequest request = new MultipartRequest();
        request.setUrl(s3Bucket);            
        request.addRequestHeader("Content-Type", "image/jpeg");
        request.addArgumentNoEncoding("key", fileName);            
        request.addArgument("acl", "bucket-owner-full-control");
        request.addData("file", strImage, "image/jpeg");            
        NetworkManager.getInstance().addToQueueAndWait(request);
                 
        int http_code = request.getResponseCode();
        
        Dialog.show("Ok", String.valueOf(http_code), "Ok", null);      
        
    } catch (Exception ex) {
        
        String err = ex.toString();
        Dialog.show("Err", err, "Ok", null);
    }

控制台报错信息

java.lang.NullPointerException
at com.codename1.io.ConnectionRequest.performOperationComplete(ConnectionRequest.java:935)
at com.codename1.io.NetworkManager$NetworkThread.runCurrentRequest(NetworkManager.java:314)
at com.codename1.io.NetworkManager$NetworkThread.run(NetworkManager.java:390)
at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)
[Network Thread] 0:0:6,656 - Exception: java.io.IOException - Stream closed
java.io.IOException: Stream closed
at com.codename1.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:140)
at com.codename1.io.BufferedInputStream.read1(BufferedInputStream.java:338)
at com.codename1.io.BufferedInputStream.read(BufferedInputStream.java:445)
at com.codename1.io.BufferedInputStream.read(BufferedInputStream.java:668)
at com.codename1.io.Util.copyNoClose(Util.java:149)
at com.codename1.io.Util.copyNoClose(Util.java:135)
at com.codename1.io.Util.copy(Util.java:170)
at com.codename1.io.Util.copy(Util.java:124)
at com.codename1.io.Util.readInputStream(Util.java:303)
at com.codename1.io.ConnectionRequest.readResponse(ConnectionRequest.java:1543)
at com.codename1.io.ConnectionRequest.performOperationComplete(ConnectionRequest.java:1003)
at com.codename1.io.NetworkManager$NetworkThread.runCurrentRequest(NetworkManager.java:314)
at com.codename1.io.NetworkManager$NetworkThread.run(NetworkManager.java:390)
at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)

问题分析与解决

1. 301错误的根源

你使用的S3全局端点https://s3.amazonaws.com/mybucketname/已被AWS逐步淘汰,现在要求使用区域专属端点(如https://mybucketname.s3.us-east-1.amazonaws.com),全局端点会返回301重定向。而Codename One的MultipartRequest默认不自动处理重定向,导致请求中断,进而引发后续的空指针和流关闭异常。

2. 凭证的必要性

必须提供AccessKey、SecretKey和AWS Region,除非你的Bucket配置了完全公开的匿名上传(生产环境不建议)。Postman和JS SDK能成功上传,是因为它们自动处理了AWS签名和重定向逻辑,而你的Codename One代码缺少签名步骤。

3. 修复步骤

步骤1:修正S3端点URL

将Bucket URL改为区域专属格式,例如Bucket在us-east-1区域时:

String s3Bucket = "https://mybucketname.s3.us-east-1.amazonaws.com/";

步骤2:添加AWS签名逻辑

S3要求请求携带AWS v4签名,你需要在请求头中添加Authorization字段(包含签名后的凭证信息),同时添加X-Amz-Date等必要头信息。可以手动实现签名,或使用Codename One第三方AWS集成库简化开发。

步骤3:处理重定向(可选)

若坚持使用旧端点,可开启请求的重定向支持:

request.setFollowRedirects(true);

但优先推荐使用区域端点,避免重定向带来的额外异常。

步骤4:空指针异常排查

空指针是重定向后流未正确处理导致的,修复端点和签名后该异常会自动消失。也可添加错误监听获取更详细日志:

NetworkManager.getInstance().addErrorListener((e) -> {
    Log.p("Request error: " + e.getError());
});

内容的提问来源于stack exchange,提问作者user22676753

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 12:26:20