Google App Engine Blobstore хранит BLOB-объекты, но генерирует недействительные ключи !? Что не так в моем кодексе? - PullRequest
2 голосов
/ 06 июля 2011

Я хочу загрузить файл, сохранить его в 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> из почтового запроса.

Теперь я хочу получить доступ к этому 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 "";
}

Я был бы очень очень рад, если бы кто-то мог понять, в чем проблема ....

1 Ответ

0 голосов
/ 25 июля 2011

Следующее работает для меня, ему нужен только один вспомогательный класс, называемый 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();
    }
...