user11609657
user11609657

Reputation: 11

Reading XML from REST post request using Springboot

I'm trying to consume XML received via REST webservice using Springboot, I'm new to this so hoping it's fairly trivial mistake I'm making.

I think the XML may be poorly structured but I have the following....

<ResultDetailsRequestModel>
<tournament>Premier League</tournament>
<fixture_date>2018-08-10</fixture_date>
<description>result</description>
<home_team>
    <team_name>Man Utd</team_name>
    <score>2</score>
    <ht_score>1</ht_score>
    <possession>46.3</possession>
    <shots_on_target>6</shots_on_target>
    <shots_off_target>1</shots_off_target>
    <corners>2</corners>
    <player gk="true" position="G" number="1">D de Gea</player>
    <player position="D" number="2">V Lindelof</player>
</home_team>
</ResultDetailsRequestModel>

But the player details are not being read, I get the following when I do a toString on the data I've received.

ResultDetailsRequestModel(tournament=Premier League, fixture_date=Fri Aug 10 01:00:00 BST 2018, description=result, home_team=TeamResultXML(team_name=Man Utd, score=2, ht_score=1, possession=46.3, shots_on_target=6, shots_off_target=1, corners=2, players=null))

I can get the information when I surround the player tags with

<players> ... </players> 

but changing the XML has a big impact elsewhere so hoping to fix with XML as is.

My code looks as follows...

@RestController
@RequestMapping("results") // http://localhost:8888/results
public class ResultsController {

    @PostMapping(
            consumes = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE },
            produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE }
    )
    public String createBets(@RequestBody ResultDetailsRequestModel resultDetails) {
        return "Received details: " + resultDetails.toString();
    }
}
@Data
@XmlRootElement(name="ResultDetailsRequestModel")
public class ResultDetailsRequestModel {
    private String tournament;
    private Date fixture_date;
    private String description;
    private TeamResultXML home_team;

}
@Data
@XmlRootElement(name="home_team")
public class TeamResultXML implements Serializable {
    private String team_name;
    private int score;
    private int ht_score;
    private double possession;
    private int shots_on_target;
    private int shots_off_target;
    private int corners;
    @XmlElement(name="player")
    private List<PlayerXML> players;

}
@Data
@XmlRootElement(name="player")
public class PlayerXML implements Serializable {
    @XmlAttribute(name="gk")
    private boolean goalkeeper;

    @XmlAttribute(name="position")
    private String position;

    @XmlAttribute(name="number")
    private int number;

    @XmlAttribute(name="sub")
    private String sub;

    @XmlValue
    private String value;
}

Data I receive....

ResultDetailsRequestModel(tournament=Premier League, fixture_date=Fri Aug 10 01:00:00 BST 2018, description=result, home_team=TeamResultXML(team_name=Man Utd, score=2, ht_score=1, possession=46.3, shots_on_target=6, shots_off_target=1, corners=2, players=null))

The @Data annotation is project Lombok so creates the getters, setters etc.

Upvotes: 1

Views: 193

Answers (1)

Andreas
Andreas

Reputation: 159086

When I try your code, I get errors:

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 7 counts of IllegalAnnotationExceptions
If a class has @XmlElement property, it cannot have @XmlValue property.
    this problem is related to the following location:
        at private java.lang.String PlayerXML.value
        at PlayerXML
        at private java.util.List TeamResultXML.players
        at TeamResultXML
        at public TeamResultXML ResultDetailsRequestModel.getHome_team()
        at ResultDetailsRequestModel
    this problem is related to the following location:
        at public java.lang.String PlayerXML.getValue()
        at PlayerXML
        at private java.util.List TeamResultXML.players
        at TeamResultXML
        at public TeamResultXML ResultDetailsRequestModel.getHome_team()
        at ResultDetailsRequestModel
Class has two properties of the same name "players"
    this problem is related to the following location:
        at public java.util.List TeamResultXML.getPlayers()
        at TeamResultXML
        at public TeamResultXML ResultDetailsRequestModel.getHome_team()
        at ResultDetailsRequestModel
    this problem is related to the following location:
        at private java.util.List TeamResultXML.players
        at TeamResultXML
        at public TeamResultXML ResultDetailsRequestModel.getHome_team()
        at ResultDetailsRequestModel
Class has two properties of the same name "goalkeeper"
    this problem is related to the following location:
        at public boolean PlayerXML.isGoalkeeper()
        at PlayerXML
        at private java.util.List TeamResultXML.players
        at TeamResultXML
        at public TeamResultXML ResultDetailsRequestModel.getHome_team()
        at ResultDetailsRequestModel
    this problem is related to the following location:
        at private boolean PlayerXML.goalkeeper
        at PlayerXML
        at private java.util.List TeamResultXML.players
        at TeamResultXML
        at public TeamResultXML ResultDetailsRequestModel.getHome_team()
        at ResultDetailsRequestModel
Class has two properties of the same name "number"
    this problem is related to the following location:
        at public int PlayerXML.getNumber()
        at PlayerXML
        at private java.util.List TeamResultXML.players
        at TeamResultXML
        at public TeamResultXML ResultDetailsRequestModel.getHome_team()
        at ResultDetailsRequestModel
    this problem is related to the following location:
        at private int PlayerXML.number
        at PlayerXML
        at private java.util.List TeamResultXML.players
        at TeamResultXML
        at public TeamResultXML ResultDetailsRequestModel.getHome_team()
        at ResultDetailsRequestModel
Class has two properties of the same name "position"
    this problem is related to the following location:
        at public java.lang.String PlayerXML.getPosition()
        at PlayerXML
        at private java.util.List TeamResultXML.players
        at TeamResultXML
        at public TeamResultXML ResultDetailsRequestModel.getHome_team()
        at ResultDetailsRequestModel
    this problem is related to the following location:
        at private java.lang.String PlayerXML.position
        at PlayerXML
        at private java.util.List TeamResultXML.players
        at TeamResultXML
        at public TeamResultXML ResultDetailsRequestModel.getHome_team()
        at ResultDetailsRequestModel
Class has two properties of the same name "sub"
    this problem is related to the following location:
        at public java.lang.String PlayerXML.getSub()
        at PlayerXML
        at private java.util.List TeamResultXML.players
        at TeamResultXML
        at public TeamResultXML ResultDetailsRequestModel.getHome_team()
        at ResultDetailsRequestModel
    this problem is related to the following location:
        at private java.lang.String PlayerXML.sub
        at PlayerXML
        at private java.util.List TeamResultXML.players
        at TeamResultXML
        at public TeamResultXML ResultDetailsRequestModel.getHome_team()
        at ResultDetailsRequestModel
Class has two properties of the same name "value"
    this problem is related to the following location:
        at public java.lang.String PlayerXML.getValue()
        at PlayerXML
        at private java.util.List TeamResultXML.players
        at TeamResultXML
        at public TeamResultXML ResultDetailsRequestModel.getHome_team()
        at ResultDetailsRequestModel
    this problem is related to the following location:
        at private java.lang.String PlayerXML.value
        at PlayerXML
        at private java.util.List TeamResultXML.players
        at TeamResultXML
        at public TeamResultXML ResultDetailsRequestModel.getHome_team()
        at ResultDetailsRequestModel

    at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:445)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:277)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:124)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1123)
    at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:147)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:247)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:234)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:462)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:641)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
    at Test8.main(Test8.java:17)

When I fix that by adding @XmlAccessorType(XmlAccessType.FIELD) to all 3 classes, I get expected output:

ResultDetailsRequestModel [tournament=Premier League, fixture_date=Fri Aug 10 00:00:00 EDT 2018, description=result, home_team=TeamResultXML [team_name=Man Utd, score=2, ht_score=1, possession=46.3, shots_on_target=6, shots_off_target=1, corners=2, players=[PlayerXML [goalkeeper=true, position=G, number=1, sub=null, value=D de Gea], PlayerXML [goalkeeper=false, position=D, number=2, sub=null, value=V Lindelof]]]]

Upvotes: 1

Related Questions