Не удается получить дескриптор для тела запроса POST, состоящего из нескольких частей / данных формы, в XPage ServiceBean

#java #xpages #lotus-domino #xpages-extlib

#java #xpages #lotus-domino #xpages-extlib

Вопрос:

У меня есть xpage, основанная на платформе bootstrap, которая использует jQuery $ post для отправки форм, содержащихся на странице. Они публикуются с использованием типа содержимого multipart / form-data, поэтому я не могу это контролировать. Я настроил REST.xsp, содержащий RestService, который вызывает java ServiceBean. Последний метод, который я пробовал, заключается в следующем:

 private void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
    // TODO Auto-generated method stub
    
    try{
        ServletFileUpload upload = new ServletFileUpload();
        FileItemIterator iterator = upload.getItemIterator(request);
        System.out.println("test");
        while (iterator.hasNext()) {
             System.out.println("test2");
            FileItemStream item = iterator.next();
            InputStream stream = item.openStream();

            if (item.isFormField()) {
                byte[] str = new byte[stream.available()];
                stream.read(str);
                String pFieldValue = new String(str,"UTF8");
                
                
                System.out.println("text Value : " pFieldValue);
                

                if(item.getFieldName().equals("textBoxFormElement")){
                    System.out.println("text Value : " pFieldValue);
                }
              }
            }
    }catch (Exception e) {
        e.printStackTrace();
    }
    
}
  

но, похоже, я просто не могу заставить сервер получать отправленные данные формы. Я вижу «test» на консоли, но он не нажимает «test2».

Я перепробовал все предложения, которые смог найти, включая:

     try {
         
            InputStream inputStream = request.getInputStream(); 
            Reader inputStreamReader = new InputStreamReader(inputStream);
            String allChars = "";
            System.out.println("test");
            int data = inputStreamReader.read();
            while(data != -1){
                System.out.println("test2");
                char theChar = (char) data;
                System.out.println(theChar);
                allChars = allChars   theChar;
                data = inputStreamReader.read();
            }

            inputStreamReader.close();
            
            
              
          }
         catch (IOException e) {
          System.out.println("No body data readable: "   e.getMessage() );
        }
  

(по-прежнему нет «test2») … и:

     String requestBody = extractPostRequestBody(request);
    System.out.println(requestBody);


  private static String extractPostRequestBody(HttpServletRequest request) {
    Scanner s = null;

    try {
        s = new Scanner(request.getInputStream(), "UTF-8").useDelimiter("\A");
    } catch (IOException e) {
        e.printStackTrace();
    }
    return s.hasNext() ? s.next() : "";
}
  

(ничего не выводится на консоль).

Я также пытался использовать REST-клиент для отправки некоторых значений данных из нескольких частей формы в URL, но снова ничего не возвращается. Однако, если я попытаюсь опубликовать некоторый json с использованием application / json content-type и использую последний метод, показанный выше, я вижу, что json выводится на консоль.

Возможно, есть какая-то проблема с использованием элемента управления ExtLib REST и java servicebean с составными записями? Я знаю, что вы можете прочитать поток запроса только один раз, так что предыдущее использование, например, request.properties, после этого сделает поток пустым, но это не так, и, по-видимому, json также не отображался бы, если бы это было так.

Большое спасибо

Ответ №1:

Если это multipart / formdata, который отправляется с запросом POST в элемент управления ExtLib Rest, вы можете получить дескриптор для отправленных данных следующим образом:

 for (Object e : req.getParameterMap().entrySet()) {
                
    Map.Entry entry = (Map.Entry) e;                
    System.out.println("got "   entry.getKey()   "/"   entry.getValue().getClass().getCanonicalName());
                
}
  

Записи на карте могут быть либо полями формы, либо загруженным файлом.

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

1. Блестяще — большое спасибо, Марк — это работает отлично! Я все еще не могу понять, почему ни одна из моих попыток не сработала или это просто из-за того, что ни одна из них не совместима с multipart / formdata? Я предполагаю, что этот метод не будет работать, когда дело доходит до обработки сообщений о загрузке файлов, для обработки которых предназначался мой первый пример? В любом случае, я, очевидно, приму ваш ответ, но буду признателен за любые предложения по захвату файлов. Еще раз спасибо.

2. Извините, Марк пропустил бит внизу .. «… или загруженный файл». Отлично! Спасибо.

3. @crispy235 — Я не знаю, почему ваш код не будет работать, но вы могли бы попробовать вызвать ServletFileUpload.isMultipartContent(request) , чтобы проверить, действительно ли запрос состоит из нескольких частей. Кроме того, я успешно использовал следующий код с тем же ServletFileUpload классом в приложениях, отличных от Domino, чтобы получить список полей формы вместо итератора: List items=upload.parseRequest(request);