Google App Engine — Обновление blobstore с помощью массива байтов с использованием имитации POST

#java #google-app-engine #post #blobstore #simulate

#java #google-app-engine #Публикация #blobstore #имитировать

Вопрос:

Я получаю следующее исключение, когда пытаюсь имитировать post-запрос для загрузки в blobstore app engine с использованием Java:

 WARNING: /_ah/login
java.lang.NullPointerException
  at com.google.appengine.api.users.dev.LoginCookieUtils.encodeEmailAsUserId(LoginCookieUtils.java:89)
  at com.google.appengine.api.users.dev.LoginCookieUtils.createCookie(LoginCookieUtils.java:41)
  at com.google.appengine.api.users.dev.LocalLoginServlet.doPost(LocalLoginServlet.java:90)
  

Вот код, который выполняет запрос POST:

 byte[] htmlData = // ...I already have the byte array I want to store/update)

    BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
            String uploadURL = blobstoreService.createUploadUrl("/upload");

                         //add host if in dev mode
             if(uploadURL.indexOf("http") == -1)
             {
                 uploadURL = "http://localhost:8888"   uploadURL;
             }
             URL url = new URL(uploadURL);
             // create a boundary string
             String boundary = MultiPartFormOutputStream.createBoundary();
             URLConnection urlConn = MultiPartFormOutputStream.createConnection(url);
             urlConn.setReadTimeout(15000);
             urlConn.setRequestProperty("Accept", "*/*");
             urlConn.setRequestProperty("Content-Type", MultiPartFormOutputStream.getContentType(boundary));
             // set some other request headers...
             urlConn.setRequestProperty("Connection", "Keep-Alive");
             urlConn.setRequestProperty("Cache-Control", "no-cache");
             // no need to connect because getOutputStream() does it
             MultiPartFormOutputStream out = new MultiPartFormOutputStream(urlConn.getOutputStream(), boundary);
out.writeField("param", "value")
out.writeFile("myFile", "multipart/form-data", "content.html", htmlData);
         out.close();
  

Затем в upload.java

 public class Upload extends HttpServlet 
{

    private BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();

    public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException 
    {
        UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();
        Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(req);
        BlobKey blobKey = blobs.get("myFile");
        String value = req.getParameter("param");
        Topic t = pm.getObjectById(Topic.class, key);
        t.setParam("value");
    try
    {
        pm.makePersistent(t);
    }
  

….

Почему я получаю исключение для encodeEmailAsUserId?

P.S. Поля записи сохраняются и отлично обновляются в хранилище данных, но я все еще получаю это исключение.

Ответ №1:

Я нашел решение для этого. Проблема в том, что в примере, из которого я извлек код MultiPartStream, не был установлен заголовок для файла cookie аутентификации.

Я просто добавил следующее в свой сервлет-посредник, который передает данные Post сервлету загрузки.

     Cookie [] cookies = req.getCookies();
    String name = cookies[0].getName();
    String value = cookies[0].getValue();
  

  urlConn.setRequestProperty("Cookie", name   "="   value);
  

Комментарии:

1. Обратите внимание, что в недавнем обновлении SDK можно создавать большие двоичные объекты программно, без получения такого запроса. Для этого вы можете использовать Files API, как описано в code.google.com/intl/pl/appengine/docs/java/blobstore/… (для Java).