Проблема преобразования из Java ответа ArrayList http на объект / список javaobj Python - PullRequest
1 голос
/ 19 февраля 2020

Моя python программа подключается к веб-сервису, который возвращает Java ArrayList (пользовательского класса с именем ObjectListEntry, который содержит 6 атрибутов). У меня возникают проблемы при создании списка Python с использованием javaobj из возвращенного потока. Я пытался с v1 и v2 и получаю разные исключения.

Windows 10, Eclipse 2019-12, PyDev 7.5 Python 3.8.1 javaobj-py3, установленный через pip (0.4.0.1?)

Я выполняю следующие шаги (код и трассировка исключений ниже)

  1. Получение ответа
  2. Проверка кода состояния
  3. Преобразование Строка response.text в байтовый поток (из UTF-8, строковое кодирование Python по умолчанию)
  4. Печать байтового массива (части распознаются как нужные мне данные :-))
  5. Pass массив байтов в функцию javaobj.loads, которая выдает исключение ...

Мне интересно, не происходит ли сбой программы, поскольку она получает данные, принадлежащие пользовательскому классу. Как бы я предоставил это определение класса или его Python эквивалент javaobj? Кажется, что есть довольно очевидный шаг, который я пропускаю и хотел бы вашей помощи. Спасибо за ответы!

Обновление: Я видел этот код о добавлении пользовательских tansformers в выпуске, а также страницах GitHub * javaobj GitHub page и добавил свой собственный преобразователь в v2 загружает вызов ... безрезультатно

# import javaobj
import javaobj.v2 as javaobj

# later, in a method
        response = requests.post( f'https://{self.fedora_server}{self.fedora_path}getObjectList',
                                  headers=headers, params=params)
        print("Response status: ", response.status_code) # displays 200

        data = bytearray( response.text, encoding='UTF-8')
        print("data from server is: ", data) # displays partially recognizable byte string

        pobj = javaobj.loads( data) # all hell breaks loose :-| --initial post
        pobj = javaobj.loads( data, Cm4fObjListEntryTransformer()) # all hell breaks loose :-| --after update

        print (pobj)

Трассировка исключений с javaobj.v1

Response status:  200
data from server is:  bytearray(b'\xc2\xac\xc3\xad\x00\x05sr\x00%org.emile.cm4f.models.ObjectListEntry\xe2\x80\xa1\x04\xe2\x80\xba\xe2\x80\x9e6\xc2\xb6\xc2\xb8\x18\x02\x00\x06L\x00\x0ccontentModelt\x00\x12Ljava/lang/String;L\x00\x06handleq\x00~\x00\x01L\x00\nlastUpdateq\x00~\x00\x01L\x00\x05ownerq\x00~\x00\x01L\x00\x03pidq\x00~\x00\x01L\x00\x05titleq\x00~\x00\x01xpt\x00\x13http://cm4f.org/TEIt\x00\x0ehdl:11471/1001t\x00\x182020-02-17T14:39:55.933Zt\x00\x07padawant\x00\x0bo:emile.teit\x00\x0bTest Objectsq\x00~\x00\x00t\x00\x13http://cm4f.org/PDFt\x00\x0ehdl:11471/1006t\x00\x182019-10-02T09:19:54.101Zt\x00\x07padawant\x00\x0bo:emile.pdft\x00\x0bTest Objectsq\x00~\x00\x00t\x00\x18http://cm4f.org/Resourcet\x00\x0ehdl:11471/1008t\x00\x182019-10-02T09:19:54.261Zt\x00\x07padawant\x00\x10o:emile.resourcet\x00\x0bTest Objectsq\x00~\x00\x00t\x00\x15http://cm4f.org/Storyt\x00\x0ehdl:11471/1010t\x00\x182019-10-02T09:19:54.381Zt\x00\x07padawant\x00\ro:emile.storyt\x00\x0bTest Objectsq\x00~\x00\x00t\x00\x14http://cm4f.org/SKOSt\x00\x0ehdl:11471/1009t\x00\x182020-02-17T14:39:56.769Zt\x00\x07padawant\x00\x0co:emile.skost\x00\x0bTest Object')
Exception in Tkinter callback
Traceback (most recent call last):
  File "path-redacted\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "path-redacted\dlgfcrepoconnect.py", line 156, in _connect_btn_clicked
    my_fed_con.stub_get_object_list(username, "filter(regex(str(?pid), '^o:'))", 5)
  File "path-redacted\fedoraapi\fedoraconnection.py", line 65, in stub_get_object_list
    pobj = javaobj.loads( data)
  File "path-redacted\lib\site-packages\javaobj\v1\core.py", line 112, in loads
    return load(
  File "path-redacted\lib\site-packages\javaobj\v1\core.py", line 87, in load
    marshaller = JavaObjectUnmarshaller(
  File "path-redacted\lib\site-packages\javaobj\v1\unmarshaller.py", line 144, in __init__
    self._readStreamHeader()
  File "path-redacted\lib\site-packages\javaobj\v1\unmarshaller.py", line 197, in _readStreamHeader
    raise IOError(
OSError: The stream is not java serialized object. Invalid stream header: C2ACC3AD

С javaobj.v2

Response status:  200
data from server is:  bytearray(b'\xc2\xac\xc3\xad\x00\x05sr\x00%org.emile.cm4f.models.ObjectListEntry\xe2\x80\xa1\x04\xe2\x80\xba\xe2\x80\x9e6\xc2\xb6\xc2\xb8\x18\x02\x00\x06L\x00\x0ccontentModelt\x00\x12Ljava/lang/String;L\x00\x06handleq\x00~\x00\x01L\x00\nlastUpdateq\x00~\x00\x01L\x00\x05ownerq\x00~\x00\x01L\x00\x03pidq\x00~\x00\x01L\x00\x05titleq\x00~\x00\x01xpt\x00\x13http://cm4f.org/TEIt\x00\x0ehdl:11471/1001t\x00\x182020-02-17T14:39:55.933Zt\x00\x07padawant\x00\x0bo:emile.teit\x00\x0bTest Objectsq\x00~\x00\x00t\x00\x13http://cm4f.org/PDFt\x00\x0ehdl:11471/1006t\x00\x182019-10-02T09:19:54.101Zt\x00\x07padawant\x00\x0bo:emile.pdft\x00\x0bTest Objectsq\x00~\x00\x00t\x00\x18http://cm4f.org/Resourcet\x00\x0ehdl:11471/1008t\x00\x182019-10-02T09:19:54.261Zt\x00\x07padawant\x00\x10o:emile.resourcet\x00\x0bTest Objectsq\x00~\x00\x00t\x00\x15http://cm4f.org/Storyt\x00\x0ehdl:11471/1010t\x00\x182019-10-02T09:19:54.381Zt\x00\x07padawant\x00\ro:emile.storyt\x00\x0bTest Objectsq\x00~\x00\x00t\x00\x14http://cm4f.org/SKOSt\x00\x0ehdl:11471/1009t\x00\x182020-02-17T14:39:56.769Zt\x00\x07padawant\x00\x0co:emile.skost\x00\x0bTest Object')
Exception in Tkinter callback
Traceback (most recent call last):
  File "path-redacted\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "path-redacted\src\gui\dlgfcrepoconnect.py", line 156, in _connect_btn_clicked
    my_fed_con.stub_get_object_list(username, "filter(regex(str(?pid), '^o:'))", 5)
  File "path-redacted\src\fedoraapi\fedoraconnection.py", line 65, in stub_get_object_list
    pobj = javaobj.loads( data)
  File "path-redacted\lib\site-packages\javaobj\v2\main.py", line 82, in loads
    return load(BytesIO(data), *transformers, **kwargs)
  File "path-redacted\lib\site-packages\javaobj\v2\main.py", line 57, in load
    contents = parser.run()
  File "path-redacted\lib\site-packages\javaobj\v2\core.py", line 128, in run
    raise ValueError("Invalid file magic: 0x{0:x}".format(magic))
ValueError: Invalid file magic: 0xc2ac

1 Ответ

0 голосов
/ 19 февраля 2020

После дополнительной отладки я понял, что должен использовать response.content, который отправляет фактический байтовый массив, полученный от сервера, а не responsest.text (и преобразовывает его в байты).

Теперь я вернуть количество объектов результата, которые я запрашиваю. Пустые объекты, но все же лучше, чем исключение.

Будет опубликован отдельный вопрос о пользовательской обработке javaobj.

...