Frühjahr: Validierung der REST-controller gegen XSD-schema
Im moment habe ich RestController mit dem folgenden code
package be.smartask.api;
import be.smartask.api.model.NumberValue;
import be.smartask.api.model.TextValue;
import be.smartask.api.model.Translations;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
/**
* @author Glenn Van Schil
* Created on 21/01/2016
*/
@CrossOrigin
@RestController
@RequestMapping(path = "/values")
public class Controller {
@RequestMapping(method = RequestMethod.POST, headers = "Value-Type=text")
ResponseEntity<?> createAttribute(@RequestBody TextValue value) {
System.out.println(value.getCode());
for (Translations.Translation translation : value.getTranslations().getTranslation()) {
System.out.println(translation.getLang());
System.out.println(translation.getValue());
}
return new ResponseEntity<>(HttpStatus.CREATED);
}
@RequestMapping(method = RequestMethod.POST, headers = "Value-Type=number")
ResponseEntity<?> createAttribute(@RequestBody NumberValue value) {
System.out.println(value.getMinValue());
System.out.println(value.getMaxValue());
return new ResponseEntity<>(HttpStatus.CREATED);
}
}
Dies funktioniert hervorragend, ich kann nach ein NumberValue wie diese:
<numberValue id="id" minValue="0" maxValue="10"/>
Aber wenn ich nach einem Textwert, um NumberValue Methode
<textvalue code="LUXE">
<translations>
<translation lang="en">luxury car</translation>
</translations>
</textvalue>
Es funktioniert immer noch. Es bleibt nur die minValue-und maxValue auf 0,0.
Meine Frage ist: Wie kann ich durchsetzen, 400: Bad Request (oder etwas ähnliches), wenn der Körper nicht genau das gleiche wie definiert in meiner xsd Datei? Durch definierte ich meine, die xml-tag-Namen ist nicht die gleiche oder eine erforderliche xs:attribute fehlt, ...
Mein xsd-Datei:
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- ValueVO -->
<xs:complexType name="geopoint">
<xs:attribute type="xs:double" name="lat"/>
<xs:attribute type="xs:double" name="lon"/>
</xs:complexType>
<xs:complexType name="translations">
<xs:sequence>
<xs:element name="translation" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="lang" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="value">
<xs:attribute type="xs:string" name="id" use="required"/>
</xs:complexType>
<xs:complexType name="textValue">
<xs:complexContent>
<xs:extension base="value">
<xs:sequence>
<xs:element type="translations" name="translations"/>
</xs:sequence>
<xs:attribute type="xs:string" name="code" use="required"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="numberValue">
<xs:complexContent>
<xs:extension base="value">
<xs:attribute type="xs:double" name="minValue" use="required"/>
<xs:attribute type="xs:double" name="maxValue" use="required"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="dateValue">
<xs:complexContent>
<xs:extension base="value">
<xs:attribute type="xs:date" name="minValue" use="required"/>
<xs:attribute type="xs:date" name="maxValue" use="required"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="cityValue">
<xs:complexContent>
<xs:extension base="value">
<xs:sequence>
<xs:element type="geopoint" name="geopoint"/>
<xs:element type="translations" name="translations"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="timeValue">
<xs:complexContent>
<xs:extension base="value"/>
</xs:complexContent>
</xs:complexType>
<xs:element name="value" type="value"/>
<xs:element name="textValue" type="textValue"/>
<xs:element name="numberValue" type="numberValue"/>
<xs:element name="dateValue" type="dateValue"/>
<xs:element name="cityValue" type="cityValue"/>
<xs:element name="timeValue" type="timeValue"/>
<xs:element name="values">
<xs:complexType>
<xs:sequence>
<xs:element ref="value" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- END ValueVO -->
</xs:schema>
UPDATE
Ich habe Folgendes in meine Feder config basiert auf Sheetal Mohan Sharma Antwort
<?xml version="1.0" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="be.smartask.api"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="marshallingHttpMessageConverter"/>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
</list>
</property>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
</bean>
<bean id="marshallingHttpMessageConverter"
class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"
p:marshaller-ref="jaxb2Marshaller" p:unmarshaller-ref="jaxb2Marshaller"/>
<bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="schema" value="classpath:schema/xsd/smartaskRead.xsd"/>
<property name="classesToBeBound">
<list>
<value>be.smartask.api.model.NumberValue</value>
<value>be.smartask.api.model.TextValue</value>
</list>
</property>
</bean>
</beans>
Aber NumberValue noch akzeptiert Textwert...
- Hast du es geschafft, eine funktionierende Lösung?
- Ja, habe ich, ich poste die Antwort
- Finden Sie unserer Lösung unten. 🙂
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie sich, mithilfe von jaxb marshaller und unmarshaller
Message-Wandler und jaxmashaller zur Prüfung gegen XSD. Fehler wird geworfen, wenn die Validierung fehlschlägt, aber es kann nicht sein bestimmten. Überprüfen Sie die links unten.
Paar gute Beispiele - hier und hier
Wir es geschafft, dies auch mit API-Versionierung, indem Sie den namespace innerhalb der XSD-Dateien
config.xml
Zuerst geben Sie die schema-locations, die zweite die das Paket Speicherort der xsd-Objekte werden erzeugt und im letzten überschreiben der marshallingHttpMessageConverter mit Ihrem neu erstellten Jaxb2Marshaller
Wenn Sie planen, machen einige Versionierung in der API ist es am besten, um die Versorgung ein namespace, so der marshaller wissen, welche xsd-Datei zu verwenden, für welches Paket
in unserem Fall war es "smartask:v1" und "smartask:v2"