JAXB Unmarshal JSON HTTP POST Параметры - PullRequest
       11

JAXB Unmarshal JSON HTTP POST Параметры

0 голосов
/ 25 августа 2018

Я пытался получить параметры из JSON в запросе POST. Это кажется очень простым процессом, и я прочитал множество постов по этому поводу, но я что-то здесь упускаю, так как возвращаю объект, но поля в этом объекте пусты. В моем POST у меня есть следующий JSON ...

{
  "client": "1",
  "forTopic": "topic"
}

А вот мой метод POST внутри моего сервлета ...

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
{           
    String requestBody = RESTUtil.getRequestBody (request);
    log.debug (requestBody);

    try
    {
        JAXBContext context = JAXBContext.newInstance (ClientAndTopicParameters.class);

        Unmarshaller unmarshal = context.createUnmarshaller ();

        unmarshal.setProperty (UnmarshallerProperties.MEDIA_TYPE, "application/json");
        unmarshal.setProperty (UnmarshallerProperties.JSON_INCLUDE_ROOT, true);

        ClientAndTopicParameters params = (ClientAndTopicParameters) unmarshal.unmarshal (new StreamSource (new StringReader (requestBody)), ClientAndTopicParameters.class).getValue ();

        log.debug ("params = " + params);
        log.debug ("client = " + params.client);
        log.debug ("forTopic = " + params.forTopic);
    }
    catch (JAXBException e)
    {
        log.error ("Unable to get Client and Topic parameters from POST.", e);
    }
}

Наконец, вот мой класс ClientAndTopicParameters ...

@XmlRootElement
public class ClientAndTopicParameters
{
    @XmlElement public String                       client;
    @XmlElement public String                       forTopic;
}

В результате получается следующее ...

2018 Aug 24 17:44:55,806 DEBUG [MyServlet                        ] params = mypackage.ClientAndTopicParameters@2995a298
2018 Aug 24 17:44:55,806 DEBUG [MyServlet                        ] client = null
2018 Aug 24 17:44:55,806 DEBUG [MyServlet                        ] forTopic = null

Как видите, это довольно простые вещи. Я предполагаю, что упускаю что-то маленькое, чего просто не вижу. Приветствую любые мысли и идеи. Для справки я использую JAXB v2.3.0

1 Ответ

0 голосов
/ 28 августа 2018

Решение состоит в том, чтобы сериализовать нужный объект и поиграть с флагом includeRoot. Если вы установите значение false, вы получите желаемый результат.

import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.transform.stream.StreamSource;

import org.eclipse.persistence.jaxb.UnmarshallerProperties;

@XmlRootElement
public class ClientAndTopicParameters
{

    @XmlElement public String                       client;
    @XmlElement public String                       forTopic;


    public static void main(String[] args) {

        try
        {
            boolean includeRoot = true;

            JAXBContext context = JAXBContext.newInstance     (ClientAndTopicParameters.class);
            Unmarshaller unmarshal = context.createUnmarshaller ();
            unmarshal.setProperty (UnmarshallerProperties.MEDIA_TYPE,     "application/json");
            unmarshal.setProperty (UnmarshallerProperties.JSON_INCLUDE_ROOT,     includeRoot);

            parseAndPrint(unmarshal, "{ \"client\": \"1\",  \"forTopic\": \"topic\"}");
            StringWriter sw = marshallDesiredObject(context, includeRoot);
            parseAndPrint(unmarshal, sw.toString());
        }
        catch (JAXBException e)
        {
            System.out.println("Unable to get Client and Topic parameters from POST.");
            e.printStackTrace();
        }
    }

    private static StringWriter marshallDesiredObject(JAXBContext context, boolean includeRoot)
        throws JAXBException, PropertyException {
        Marshaller marshal = context.createMarshaller ();

        marshal.setProperty (UnmarshallerProperties.MEDIA_TYPE, "application/json");
        marshal.setProperty (UnmarshallerProperties.JSON_INCLUDE_ROOT, includeRoot);

        ClientAndTopicParameters cp = new ClientAndTopicParameters();
        cp.client = "1";
        cp.forTopic = "topic";

        StringWriter sw = new StringWriter();
        marshal.marshal(cp, sw);
        return sw;
    }

    private static void parseAndPrint(Unmarshaller unmarshal, String requestBody)
            throws JAXBException {
        System.out.println("requestBody to parse: " + requestBody);
        ClientAndTopicParameters params = unmarshal.unmarshal(new StreamSource (new     StringReader (requestBody )), ClientAndTopicParameters.class).getValue ();
        System.out.println("params = " + params);
        System.out.println("client = " + params.client);
        System.out.println("forTopic = " + params.forTopic);
    }
}

Я использовал эти зависимости:

        <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>org.eclipse.persistence.moxy</artifactId>
        <version>2.5.2</version>
    </dependency>
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.2.11</version>
    </dependency>

В вашем коде это единственное, что вы должны изменить:

unmarshal.setProperty (UnmarshallerProperties.JSON_INCLUDE_ROOT, false);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...