java - Google App Engine Blobstore 存储 Blob 但生成无效 key !?我的代码有什么问题?

标签 java google-app-engine file-upload blobstore

我想上传一个文件,将其存储在 Blobstore 中,然后再访问它(通过 BlobKey),但这行不通。

这是我的代码:

public class CsvToBlobstoreUploadServlet extends HttpServlet {

private final BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();

@Override
public void doPost(final HttpServletRequest request, final HttpServletResponse res) throws ServletException, IOException {

    final Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(request);
    final BlobKey blobKey = blobs.get("upload");

    final BlobInfo info = new BlobInfoFactory().loadBlobInfo(blobstoreService.getUploadedBlobs(request).get("upload"));

    if (blobKey == null) {
        res.sendRedirect("/");
    } else {
        res.sendRedirect("/csvupload?blob-key=" + blobKey.getKeyString());
    }

}

@Override
protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
    final BlobInfo blobInfo = new BlobInfoFactory().loadBlobInfo(new BlobKey(req.getParameter("blob-key")));
    resp.setContentType("text/html");
    resp.setHeader("Content-Language", "en");
    resp.getWriter().println("<blob-key>" + blobInfo.getBlobKey().getKeyString() + "</blob-key>"); // Here I get no NullPointerException, blobInfo is NOT null, everything es as expected....
}

这行得通!意味着 File ist 存储在 Blobstore 中,我得到类似 <blob-key>jA_W_jiKoTpXAe9QjeFlrg</blob-key> 的信息从 Post 请求返回。

现在我想用这个键访问这个 Blob,但是下面的代码导致 NullPointerException,因为 blobInfo 是 null....但是为什么???

// A method from another Servlet....    
private String getData(final String blobKey) {
    //at this point blobKey is exactly that one returned previously for example jA_W_jiKoTpXAe9QjeFlrg
    try {
        final BlobInfo blobInfo = new BlobInfoFactory().loadBlobInfo(new BlobKey(blobKey));

        final BlobstoreInputStream bis = new BlobstoreInputStream(blobInfo.getBlobKey()); // Here I got NullPointerException, because BlobInfo is null
        final InputStreamReader isr = new InputStreamReader(bis);
        final BufferedReader br = new BufferedReader(isr);
        final StringBuffer sb = new StringBuffer();
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        return sb.toString();
    } catch (final IOException e) {
        e.printStackTrace();
    }
    return "";
}

如果有人能弄清楚问题出在哪里,我会非常非常高兴......

最佳答案

以下对我有用,它只需要一个辅助类,称为 FileObject,它是一个命名的动态字节缓冲区,用于附加字节数组:

public class FileObject {
    private String name;
    byte [] bufferArray = null;

    public FileObject(String name, byte[] data) {
        this.name = name;
        this.bufferArray = data;
    }

    public FileObject(String name) {
        this.name = name;
        }

    public void appendData(byte[] data, int numberOfBytes) {

        if (bufferArray == null)
        {
            this.bufferArray = new byte [numberOfBytes];
            System.arraycopy(data, 0, bufferArray, 0, numberOfBytes);
        }
        else
        {
            byte[] tempArray = new byte[bufferArray.length + numberOfBytes];
            System.arraycopy(bufferArray, 0, tempArray, 0, bufferArray.length);
            System.arraycopy(data, 0, tempArray, bufferArray.length, numb    erOfBytes);    
            bufferArray = tempArray;
        }
    }

    public byte[] getData() {
        return bufferArray;
    }

    public void setData(byte[] data) {
        this.bufferArray = data;
    }

    public String getName() {
        return name;
    }
}

这是写入文件对象的核心方法:

public synchronized static byte[] readBlob(BlobKey blobKey) throws BlobServiceException{
        int bufferSize = MAX_READ_BUFFER_SIZE;
        FileObject fileObject = new FileObject("");
        try{
            AppEngineFile file = fileService.getBlobFile(blobKey);
            FileReadChannel readChannel = fileService.openReadChannel(file, false);
            // write the files to the disk
            ByteBuffer byteBuffer = ByteBuffer.allocate(bufferSize);
            int numberOfBytes;
            while ((numberOfBytes = readChannel.read(byteBuffer)) != -1) {
                fileObject.appendData(byteBuffer.array(), numberOfBytes);
                byteBuffer = ByteBuffer.allocate(bufferSize);
            }

            readChannel.close();
        }catch(Exception e){
            BlobServiceException blobIoException = new BlobServiceException("Failure while reading blob.\n" + e.getMessage());
            blobIoException.setStackTrace(e.getStackTrace());
            throw blobIoException;
        }
        return fileObject.getData();
    }

关于java - Google App Engine Blobstore 存储 Blob 但生成无效 key !?我的代码有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6600675/

相关文章:

java - 桌面应用程序的对象持久化策略

python - DJANGO_SETTINGS_MODULE 未定义

html - 单击文件输入标签的解决方法 (Firefox)

django rest 框架不接受 blob 图片文件(不允许文件扩展名 “”)

ios - Dropbox Core API - 上传前出现 1021 错误 - 仅适用于 iOS 5 及以下版本

Java 十六进制浮点字面量歧义

java - 从 python 调用 java 类

java - 是否可以将 spring rest 文档与 spock 一起使用

python - 如何使用 google-app-engine-django 验证包含 App Engine 上文件的 Django 表单?

python - 在没有 App Engine 的情况下运行谷歌云端点