In Spring MVC, what is the correct configuration for using Jaxb annotations for request body?

问题: Currently I have a RESTful service, and I am trying to deserialize a POST request body, that is XML, that is not working. I've tried all solutions out there, but none seem...

问题:

Currently I have a RESTful service, and I am trying to deserialize a POST request body, that is XML, that is not working. I've tried all solutions out there, but none seem to work. JSON works perfectly with Spring MVC, but getting XML to work is such a pain..

I'm using Spring 5.1.5 version, and using Jaxb for the marshalling and unmarshalling.

The following is what I currently have:

This is my spring mvc configuration:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">


    <context:component-scan base-package="my.project.controllers" />

    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter">
                <property name="objectMapper" ref="xmlMapper"/>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <bean id="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
          p:indentOutput="true"
          p:simpleDateFormat="yyyy-MM-dd"
          p:modulesToInstall="com.fasterxml.jackson.module.paramnames.ParameterNamesModule"/>

    <bean id="xmlMapper" parent="objectMapper" p:createXmlMapper="true"/>
</beans>

These are my pom.xml dependencies:

        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.guice</groupId>
            <artifactId>spring-guice</artifactId>
            <version>${spring.guice.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>

        <!-- Logging -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>${sl4j-log4j.version}</version>
        </dependency>

        <!-- Other dependencies -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>${javax.annotation.version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.inject</groupId>
            <artifactId>guice</artifactId>
            <version>${guice.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>

This is my RestController:

@RestController
@RequestMapping("issuance")
public class ProtocolController {

    @Autowired
    private IssuerManager issuerManager;

    @PostMapping(value = "init", produces = "application/xml", consumes = "application/xml")
    public IssuanceMessageAndBoolean initializeIssuance(@RequestBody final IssuancePolicyAndAttributes ipaa) throws CryptoEngineException {
        IssuanceMessageAndBoolean imab = issuerManager.initializeIssuanceProtocol(ipaa);
        return imab;
    }

This is the object that I am trying to deserialize (IssuancePolicyAndAttributes):


@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(
    name = "IssuancePolicyAndAttributes",
    namespace = "http://abc4trust.eu/wp2/abcschemav1.0",
    propOrder = {"issuancePolicy", "attribute"}
)
@XmlRootElement(
    name = "IssuancePolicyAndAttributes"
)
public class IssuancePolicyAndAttributes implements Serializable {
    private static final long serialVersionUID = 6699648078303838561L;
    @XmlElement(
        name = "IssuancePolicy",
        namespace = "http://abc4trust.eu/wp2/abcschemav1.0",
        required = true
    )
    protected IssuancePolicy issuancePolicy;
    @XmlElement(
        name = "Attribute",
        namespace = "http://abc4trust.eu/wp2/abcschemav1.0"
    )
    protected List<Attribute> attribute;

    public IssuancePolicyAndAttributes() {
    }

    public IssuancePolicy getIssuancePolicy() {
        return this.issuancePolicy;
    }

    public void setIssuancePolicy(IssuancePolicy value) {
        this.issuancePolicy = value;
    }

    public List<Attribute> getAttribute() {
        if (this.attribute == null) {
            this.attribute = new ArrayList();
        }

        return this.attribute;
    }
}

And this is my XML that I am sending as the request body:

<abc:IssuancePolicyAndAttributes
        xmlns:abc="http://abc4trust.eu/wp2/abcschemav1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://abc4trust.eu/wp2/abcschemav1.0 ../../../../../../../../abc4trust-xml/src/main/resources/xsd/schema.xsd">

    <abc:IssuancePolicy Version="1.0">
        <abc:PresentationPolicy PolicyUID="http://ticketcompany.com/tickets/issuance/policy">
            <abc:Pseudonym Exclusive="true" Scope="http://ticketcompany.com/tickets/vip" Established="false"
                           Alias="#nym"/>
            <abc:Message>
                <abc:Nonce>KNsRu9cGzkaeabogeRVV</abc:Nonce>
                <abc:ApplicationData>
                    <abc:TestApplicationData>
                        <abc:Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                  xmlns:xs="http://www.w3.org/2001/XMLSchema"
                                  xsi:type="xs:string">Some data
                        </abc:Data>
                    </abc:TestApplicationData>
                </abc:ApplicationData>
            </abc:Message>
        </abc:PresentationPolicy>

        <abc:CredentialTemplate SameKeyBindingAs="#nym">
            <abc:CredentialSpecUID>http://MyFavoriteSoccerTeam/tickets/vip</abc:CredentialSpecUID>
            <abc:IssuerParametersUID>http://ticketcompany/MyFavoriteSoccerTeam/issuance:idemix</abc:IssuerParametersUID>
            <abc:UnknownAttributes/>
        </abc:CredentialTemplate>
    </abc:IssuancePolicy>

    <abc:Attribute>
        <abc:AttributeUID>-5027215341191833963</abc:AttributeUID>
        <abc:AttributeDescription DataType="xs:string" Encoding="urn:abc4trust:1.0:encoding:string:sha-256"
                                  Type="FirstName">
            <abc:FriendlyAttributeName lang="en">first name</abc:FriendlyAttributeName>
            <abc:FriendlyAttributeName lang="da">fornavn</abc:FriendlyAttributeName>
        </abc:AttributeDescription>
        <abc:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">John
        </abc:AttributeValue>
    </abc:Attribute>
    <abc:Attribute>
        <abc:AttributeUID>-2715953330829768453</abc:AttributeUID>
        <abc:AttributeDescription DataType="xs:string" Encoding="urn:abc4trust:1.0:encoding:string:sha-256"
                                  Type="LastName">
            <abc:FriendlyAttributeName lang="en">last name</abc:FriendlyAttributeName>
            <abc:FriendlyAttributeName lang="da">efternavn</abc:FriendlyAttributeName>
        </abc:AttributeDescription>
        <abc:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Dow
        </abc:AttributeValue>
    </abc:Attribute>
    <abc:Attribute>
        <abc:AttributeUID>-2231744817504418816</abc:AttributeUID>
        <abc:AttributeDescription DataType="xs:date" Encoding="urn:abc4trust:1.0:encoding:date:unix:signed"
                                  Type="Birthday">
            <abc:FriendlyAttributeName lang="en">birthday</abc:FriendlyAttributeName>
            <abc:FriendlyAttributeName lang="da">fødselsdag</abc:FriendlyAttributeName>
        </abc:AttributeDescription>
        <abc:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1985-05-05Z
        </abc:AttributeValue>
    </abc:Attribute>
    <abc:Attribute>
        <abc:AttributeUID>-2231744817504418826</abc:AttributeUID>
        <abc:AttributeDescription DataType="xs:date" Encoding="urn:abc4trust:1.0:encoding:date:unix:signed"
                                  Type="Matchday">
            <abc:FriendlyAttributeName lang="en">Match day</abc:FriendlyAttributeName>
            <abc:FriendlyAttributeName lang="da">Kamp dag</abc:FriendlyAttributeName>
        </abc:AttributeDescription>
        <abc:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">2013-08-07Z
        </abc:AttributeValue>
    </abc:Attribute>
    <abc:Attribute>
        <abc:AttributeUID>-1231744817504418817</abc:AttributeUID>
        <abc:AttributeDescription Type="MemberNumber" DataType="xs:integer"
                                  Encoding="urn:abc4trust:1.0:encoding:integer:unsigned">
            <abc:FriendlyAttributeName lang="en">VIP member id</abc:FriendlyAttributeName>
            <abc:FriendlyAttributeName lang="da">VIP medlems nummer</abc:FriendlyAttributeName>
        </abc:AttributeDescription>
        <abc:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:integer">23784638726
        </abc:AttributeValue>
    </abc:Attribute>
</abc:IssuancePolicyAndAttributes>

When I debug and check the value of the variable ipaa of the RestController, the variable itself is instantiated but all of its members are null, which indicates the unmarshalling is not occurring correctly.

What am I doing wrong?


回答1:

change the name of xml element

@XmlElement(name = "abc:IssuancePolicy", namespace = "http://abc4trust.eu/wp2/abcschemav1.0", required = true)
protected IssuancePolicy issuancePolicy;

@XmlElement(name = "abc:Attribute", namespace = "http://abc4trust.eu/wp2/abcschemav1.0")
protected List<Attribute> attribute;
  • 发表于 2019-03-28 23:15
  • 阅读 ( 160 )
  • 分类:sof

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除