Каков правильный подход к загрузке файлов в Blobstore Google App Engine без браузера?

Я работаю над функцией загрузки файлов в веб-приложении Java, работающем в Google App Engine (GAE). Приложение использует API Blobstore для обработки загрузки файлов. Однако при попытке загрузить файл я сталкиваюсь с NullPointerException (NPE), который не могу отладить из-за отсутствия исходного кода для класса com.google.appengine.api.blobstore.dev.UploadBlobServlet в версии appengine-api-stubs 1.9.88.

Сообщение об ошибке:

java.lang.NullPointerException
    at com.google.appengine.api.blobstore.dev.UploadBlobServlet.handleUpload(UploadBlobServlet.java:432)

NPE указывает на строку 432 в UploadBlobServlet, поскольку у меня нет доступа к точному исходному коду, я делаю выводы на основе общей структуры сервлета.

Соответствующие фрагменты кода:

Эта строка 432 из https://github.com/GoogleCloudPlatform/appengine-java-standard/blob/8380dd6b475a49b45112e6c4a20acbb922c28c5e/api_dev/src/main/java/com/google/appengine/api/blobstore/dev/UploadBlobServlet.java# L432 предложите этот блок кода:

Загрузите фрагмент метода сервлета:

public final class UploadBlobServlet extends HttpServlet {
    @Override
    public Enumeration<String> getParameterNames() {
        List<String> allNames = new ArrayList<>();
        Enumeration<String> names = super.getParameterNames();
        while (names.hasMoreElements()) {
            allNames.add(names.nextElement());
        }
        // Additional code for handling other parameters
        return Collections.enumeration(allNames);
    }
}

Хотя это кажется нелогичным, поскольку метод, который бросает, должен быть handleUpload

Клиентский код загрузки файлов:

public class FileUploader {
    public String getUploadUrl(String callbackPath) throws URISyntaxException, IOException {
        // Setup Remote API
        BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
        String uploadUrl = blobstoreService.createUploadUrl(callbackPath);
        return uploadUrl;
    }

    public String uploadFile(String url, String partName, String filename, String mimeType, byte[] contents) throws IOException {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost post = new HttpPost(url);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            ByteArrayBody contentBody = new ByteArrayBody(contents, ContentType.create(mimeType), filename);
            builder.addPart(partName, contentBody);
            post.setEntity(builder.build());
            HttpResponse response = httpClient.execute(post);
            return EntityUtils.toString(response.getEntity());
        }
    }
}

Метод испытания:

@Test
public void shouldBeAbleToUpload) throws Exception {
    FileUploader fileUploader = new FileUploader();
    String uploadUrl = fileUploader.getUploadUrl("path/to/some/blob");
    InputStream sample = getClass().getResourceAsStream("/100mb.bin");
    byte[] fileContent = readFileToByteArray(sample);
    fileUploader.uploadFile(uploadUrl, "file", "sample.html", "application/octet-stream", fileContent);
}

Главная проблема: Основная проблема — NPE во время процесса загрузки файла. Я подозреваю, что проблема может быть связана с тем, как обрабатываются параметры, или, возможно, с неправильной настройкой в ​​моей логике загрузки. Однако, не имея доступа к исходному коду UploadBlobServlet, я не знаю, как продолжить отладку.

Вопросы:

  1. Сталкивался ли кто-нибудь с подобной проблемой при загрузке файлов в GAE Blobstore и может ли он объяснить, что может пойти не так?
  2. Известны ли проблемы с обработкой данных многочастных форм UploadBlobServlet, которые могут привести к NPE?
  3. Есть какие-нибудь предложения о том, как отладить или обойти эту проблему, особенно учитывая отсутствие исходного кода сервлета?

Я подтвердил, что созданный URL-адрес загрузки правильный и доступный, а приложение работает на локальном сервере разработки, предоставленном GAE.

Любая помощь или руководство будут очень признательны. Спасибо!

Пробовали решения из этой темы?

Roopa M 09.04.2024 09:59

@RoopaM да, я сделал

quarks 09.04.2024 10:55

Я считаю, что вам следует сообщить об этом в github appengine-java-standard, так как может быть вероятность, что проблема связана с UploadBlobServlet обработкой данных многочастной формы.

Roopa M 09.04.2024 12:22
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
3
59
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ошибка NPE выдается UploadBlobServlet, если URL-адрес обратного вызова не имеет косой черты "/". Чтобы избежать этой ошибки, убедитесь, что URL-адрес обратного вызова имеет косую черту.

Это приведет к:

String uploadUrl = fileUploader.getUploadUrl("callback");

И это не будет:

String uploadUrl = fileUploader.getUploadUrl("/callback");

Другие вопросы по теме

Рабочие Gunicorn в Google App Engine случайным образом отправляют SIGKILL, что приводит к TIMEOUT. Что происходит?
Развертывание GCP App Engine с помощью действий GitHub с использованием (предпочтительно) прямой федерации идентификации рабочей нагрузки
Обработка формы запроса POST с помощью приложения Flask и Google App Engine
Gcloud.app.deploy Ответ на ошибку: [13] Не удалось создать облачную сборку: недопустимый сегмент
Gcloud.app.deploy Ответ на ошибку: [13] учетная запись службы Cloud Build по умолчанию или указанная пользователем учетная запись службы не имеют доступа к корзине
Как мне подключиться к Google Cloud MySQL из App Engine с помощью Django-Environ?
Невозможно отправить сборки gcloud из-за ошибки разрешений tempfile file.tgz в Windows
Ошибка при развертывании приложения Java Spring Boot в Google App Engine: истекло время загрузки модуля (Ответ на ошибку: [4])
Ошибка подключения GCP Cloud Sql к GCP App Engine
Как развернуть приложение Nextjs на движке приложений Google?