2

我想上传一个文件,将其存储在 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....
}

这行得通!意味着文件存储在 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 "";
}

如果有人能找出问题所在,我会非常高兴....

4

1 回答 1

0

以下对我有用,它只需要一个名为 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();
    }
于 2011-07-25T16:11:30.170 回答