Получение GlassX's MOXy для конвертации JSON в POJO - PullRequest
0 голосов
/ 17 января 2019

У меня есть веб-приложение, которое загружает файлы через POST MULTIPART_FORM_DATA, в котором есть как двоичные данные, так и строки JSON. (Строки JSON создаются с помощью функции браузера JSON.stringify (obj)).

Согласно документации Glassfish начиная с 4.0.1 использует MOXy для демаршаллинга объектов JSON и XML.

Мой метод выглядит так:

@POST
@Path("put")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response put(@FormDataParam("file") List<FormDataBodyPart> bodyParts,
                    @FormDataParam("metadata") List<String> metaParts) throws JAXBException {

    JAXBContext jbc = JAXBContext.newInstance(MetaData.class);

    for (int index = 0; index < metaParts.size(); index += 1) {

        MetaData meta = null;
        String metaString = metaParts.get(index);
        if (metaString != null && !metaString.isEmpty()) {
            Unmarshaller um = jbc.createUnmarshaller();
            // um.setProperty(???, "application/json");
            meta = (MetaData) um.unmarshal(new StreamSource(new StringReader(metaString)));
        }

Код, подобный этому, попытается проанализировать данные в metaString как XML-документ, поэтому он выдаст исключение.

Просматривая доступную документацию, я обнаружил, что решение этой проблемы для реализации EclipseLink MOXy, по-видимому, заключается в

um.setProperty("eclipselink.media-type", "application/json");

Это не работает, потому что реализация MOXy для Glassfish 5 взята из com.sun.xml. *, А не из Eclipse. При трассировке кода кажется, что эта реализация вызовет исключение при любом вызове setProperty, поскольку она не поддерживает какие-либо специфические для реализации свойства.

И все же я знаю, что MOXy от Sun может это сделать, потому что он отлично обрабатывает мои HTTP-запросы / ответы. Тем не менее, я нигде не могу найти ни примеров, ни документации - все пути ведут к реализации EclipseLink.

Кто-нибудь знает, как это сделать?

1 Ответ

0 голосов
/ 01 февраля 2019

Вам не нужно анализировать данные вручную. То, что вы можете сделать, это получить часть тела как FormDataBodyPart, как вы уже сделали для части "file". Начиная с FormDataBodyPart, вам нужно будет установить тип носителя на application/json 1 , а затем просто получить POJO, используя bodyPart.getValueAs(POJO.class).

public Response put(@FormDataBodyPart("metadata") FormDataBodyPart metaDataPart) {
    metaDataPart.setMediaType(MediaType.APPLICATION_JSON_TYPE);
    MetaData metaData = metaDataPart.getValueAs(MetaData.class);
}

Подробнее об этом можно узнать в Загрузка файла вместе с другим объектом в веб-сервисе отдыха Джерси


1 - В составном запросе каждая часть тела имеет собственный заголовок Content-Type. Если вы не установите его, он будет автоматически считаться text/plain по умолчанию. С Javascript у вас нет возможности установить тип содержимого отдельных частей, поэтому по умолчанию он будет text/plain. Но нам нужно, чтобы он был application/json, чтобы поставщик JSON JSX-RS использовался для десериализации.

...