1

I'm creating a spring boot rest API which should accept xml. Once i get the data to be accepted by the controller i can jiggle my way forward. So basically my question is, how do i get the controller to accept the data?

My understanding is that i can use either jaxb or jackson for this, and jackson is to be preferred(?)

The controller will look something like

    package com.example.rest;

    import org.springframework.http.HttpStatus;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseStatus;
    import org.springframework.web.bind.annotation.RestController;

    @RestController
    @RequestMapping("/myapi")
    public class myController {

        @RequestMapping(method = RequestMethod.POST, path = "/xmlentry", consumes = "application/xml")
        public void doStuff() {// do stuff  }

    }

The input i get (which i feed into postman) is

    <Game>
        <numberOfBalls>8</numberOfBalls>
        <players>
            <human>
                <id>1001</id>
                <name>John</name>
                <skill>40</skill>
            </human>
            <human>
                <id>2001</id>
                <name>Jake</name>
                <skill>58</skill>
            </human>
            <human>
                <id>3001</id>
                <name>Jane</name>
                <skill>50</skill>
            </human>
        </players>
        <bonus>
            <round nr="1">
                <id number="1001">1</id>
                <id number="2001">1</id>
                <id number="3001">4</id>
            </round>
            <round nr="2">
                <id number="1001">6</id>
                <id number="2001">0</id>
                <id number="3001">1</id>
            </round>
        </bonus>
    </Game>

So, my instinct is to add

    <dependency>
     <groupId>com.fasterxml.jackson.dataformat</groupId>
     <artifactId>jackson-dataformat-xml</artifactId>
    </dependency>

to the pom file and set doStuff() as

    public void doStuff(@RequestBody Game game) {}

where i create a pojo Game class (containing numberOfBalls (int), players (list of humans) , bonus (list of rounds)) and then creating humans etc. Is this the easy way of doing it? A little confused here.

Appreciate any help.

2 Answers 2

3

Update and solution.

Couldn´t make Jackson work (spent many hours).

Couldn´t make my own POJOs with annotation work (spent many hours and followed many tutorials). Almost worked but couldn´t get all data from the xml.

Turned out i had the .XSD-file and from that one i could auto-generate the necessary POJOs. Here is how i did that. (Edit: Eclipse Spring Tool Suite 4.)

I had java 13 installed, but removed that and downloaded and installed java 8 instead.

I set the path to jdk under installed JREs (Window->Preferences->Java->Installed JREs). Name: jre1.8.... Location C:\Prog...\jdk1.8...

To be able to genreate pojos i followed https://www.consulting-bolte.de/index.php/java-se-ee/jaxb/123-setup-eclipse-for-jaxb (select Help -> Install New Software, work with: http://download.eclipse.org/releases/luna). Install everything.

Right click on the .xsd-file, generate and pojos was created along with the ObjectFactory.java.

Made services and created my own response myResponse which shold be returned as Json. Jackson is included in POM and takes care of it.

This is how my Controller looks like.

package com.example.rest;

import java.io.StringReader;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/myapi")
public class myController  {

    @Autowired
    private MyService myService;

    @RequestMapping(method = RequestMethod.POST, path = "/xmlentry", consumes = "application/xml", produces = "application/json")
    public MyResponse doStuff(@RequestBody String xmlString) {

        try {

            JAXBContext jc = JAXBContext.newInstance("com.example.rest");
            Unmarshaller um = jc.createUnmarshaller();

            //GameType: Generated pojo, root element
            JAXBElement<GameType> gameType = (JAXBElement<GameType>) um.unmarshal(new StringReader(xmlString));

            //gameType is now populated with xml data

            return myService.getMyResponse(gameType);


        } catch (JAXBException e) {
        }

        return null;

    }

}

Hope this was helpful.

Sign up to request clarification or add additional context in comments.

Comments

-1

Add the parameter to your method.

public void doStuff(@RequestBody Game game){...}

I believe you won't be needing the additional dependencies since you have already mentioned that your endpoint will consume xml. Just make sure you have a model defined in your project in the same structure as the input xml.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.