使用jaxb的spring 4 restful service - post方法错误地绑定输入数据

时间:2016-08-13 17:56:37

标签: java spring rest model-view-controller jaxb

我正在尝试创建基于Spring 4的restful服务。该服务应该使用json和xml。我创建了一个xsd并使用xjc将xsd编译为绑定类。

这是xsd

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="qualified">
    <xsd:element name="ServicesRequest">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="activityType" type="xsd:int"/>
                <xsd:element ref="ServicesInput" minOccurs="0" maxOccurs="unbounded"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name="ServicesInput">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="name" type="xsd:string" minOccurs="0"/>
                <xsd:element ref="ListOfValues" minOccurs="0"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name="ListOfValues">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="Value" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

以下是运行xjc之后的java类:

ServiceRequest.java

   //
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.11 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2016.08.13 at 12:54:09 PM EDT 
//


package org.acme.foo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;


/**
 * <p>Java class for anonymous complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType&gt;
 *   &lt;complexContent&gt;
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
 *       &lt;sequence&gt;
 *         &lt;element name="activityType" type="{http://www.w3.org/2001/XMLSchema}int"/&gt;
 *         &lt;element ref="{}ServicesInput" maxOccurs="unbounded" minOccurs="0"/&gt;
 *       &lt;/sequence&gt;
 *     &lt;/restriction&gt;
 *   &lt;/complexContent&gt;
 * &lt;/complexType&gt;
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "activityType",
    "servicesInput"
})
@XmlRootElement(name = "ServicesRequest")
public class ServicesRequest
    implements Serializable
{

    private final static long serialVersionUID = 1L;
    protected int activityType;
    @XmlElement(name = "ServicesInput")
    protected List<ServicesInput> servicesInput;

    /**
     * Gets the value of the activityType property.
     * 
     */
    public int getActivityType() {
        return activityType;
    }

    /**
     * Sets the value of the activityType property.
     * 
     */
    public void setActivityType(int value) {
        this.activityType = value;
    }

    /**
     * Gets the value of the servicesInput property.
     * 
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a <CODE>set</CODE> method for the servicesInput property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getServicesInput().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link ServicesInput }
     * 
     * 
     */
    public List<ServicesInput> getServicesInput() {
        if (servicesInput == null) {
            servicesInput = new ArrayList<ServicesInput>();
        }
        return this.servicesInput;
    }

}

ServiceInout.java

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.11 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2016.08.13 at 12:54:09 PM EDT 
//


package org.acme.foo;

import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;


/**
 * <p>Java class for anonymous complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType&gt;
 *   &lt;complexContent&gt;
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
 *       &lt;sequence&gt;
 *         &lt;element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/&gt;
 *         &lt;element ref="{}ListOfValues" minOccurs="0"/&gt;
 *       &lt;/sequence&gt;
 *     &lt;/restriction&gt;
 *   &lt;/complexContent&gt;
 * &lt;/complexType&gt;
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "name",
    "listOfValues"
})
@XmlRootElement(name = "ServicesInput")
public class ServicesInput
    implements Serializable
{

    private final static long serialVersionUID = 1L;
    protected String name;
    @XmlElement(name = "ListOfValues")
    protected ListOfValues listOfValues;

    /**
     * Gets the value of the name property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getName() {
        return name;
    }

    /**
     * Sets the value of the name property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setName(String value) {
        this.name = value;
    }

    /**
     * Gets the value of the listOfValues property.
     * 
     * @return
     *     possible object is
     *     {@link ListOfValues }
     *     
     */
    public ListOfValues getListOfValues() {
        return listOfValues;
    }

    /**
     * Sets the value of the listOfValues property.
     * 
     * @param value
     *     allowed object is
     *     {@link ListOfValues }
     *     
     */
    public void setListOfValues(ListOfValues value) {
        this.listOfValues = value;
    }

}

ListOfValues.java

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.11 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2016.08.13 at 12:54:09 PM EDT 
//


package org.acme.foo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;


/**
 * <p>Java class for anonymous complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType&gt;
 *   &lt;complexContent&gt;
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
 *       &lt;sequence&gt;
 *         &lt;element name="Value" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/&gt;
 *       &lt;/sequence&gt;
 *     &lt;/restriction&gt;
 *   &lt;/complexContent&gt;
 * &lt;/complexType&gt;
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "value"
})
@XmlRootElement(name = "ListOfValues")
public class ListOfValues
    implements Serializable
{

    private final static long serialVersionUID = 1L;
    @XmlElement(name = "Value")
    protected List<String> value;

    /**
     * Gets the value of the value property.
     * 
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a <CODE>set</CODE> method for the value property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getValue().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link String }
     * 
     * 
     */
    public List<String> getValue() {
        if (value == null) {
            value = new ArrayList<String>();
        }
        return this.value;
    }

}

ControllerClass

package com.journaldev.spring.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.acme.foo.ServicesRequest;
import org.springframework.web.bind.annotation.PathVariable;
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.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.journaldev.spring.model.Employee;

/**
 * Handles requests for the Employee service.
 */
@RestController
public class EmployeeController {



    @RequestMapping(value = "/bcreate", method = RequestMethod.POST, consumes = "application/xml")
    public String createBatch(@RequestBody ServicesRequest serviceRequest) {

        try {

            if (serviceRequest.getServicesInput().size()==0) {
            System.out.println("input is null");
        }

        } catch (Exception e) {
        }

        return "test";
    }
}

的web.xml

<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>Spring Web MVC Application</display-name>

    <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

</web-app>

MVC分派-servlet.xml中

<?xml version="1.0" encoding="UTF-8"?>
<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"
    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">


    <context:component-scan base-package="com.journaldev.spring.controller" />
<mvc:annotation-driven/>
 </beans>

发布请求:

<ServicesRequest>
    <activityType>1234512340</activityType>
    <ServicesInput>
        <name>MyName</name>
        <ListOfValues>
              <Value>Thisisatest</Value>
        </ListOfValues>
    </ServicesInput>
</ServicesRequest>

Image : eclipse Debug Breakpoint

这些是罐子

  1. commons-logging.jar jackson-annotations.jar jackson-core.jar jackson-databind.jar jackson-dataformat-xml.jar jackson-dataformat-yaml.jar jackson-datatype-joda.jar jackson-jaxrs-base.jar jackson-jaxrs-json-provider.jar jackson-module-jaxb-annotations.jar jaxb-api.jar jaxb-core.jar jaxb-impl.jar jaxb-jxc.jar jaxb-xjc.jar log4j.jar spring-aop.jar spring-aspects.jar spring-beans.jar spring-bridge.jar spring-context-support.jar spring-context.jar spring-core.jar spring-expression.jar spring-jdbc.jar spring-jms.jar spring-messaging.jar spring-oxm.jar spring-tx.jar spring-web.jar spring-webmvc.jar spring-ws-core.jar spring-ws-support.jar spring-xml.jar stax-api.jar stax-ex.jar stax2-api.jar streambuffer.jar
  2. 所以我的问题是,上面列出的输入为什么我在控制器中看不到相同的内容。输入确认到xsd。

    非常感谢所有的帮助。

1 个答案:

答案 0 :(得分:0)

我不得不从类路径中删除Jackson-dataformat-xml.jar。然后它开始使用jaxb绑定并开始正确绑定。