Assuming we are using Jaxb2Marshaller class for marshaling/marshaling the XML request/response.Lets we want to use a xsd file named validate.xsd for validating XML REST Request.First put the validate.xsd file in to src/main/resources directory in the project workspace.Now set the JAXB configuration in your rest-servlet.xml file like:
<bean id="jaxb2Marshaller"> <property name="schema" value="classpath:/validate.xsd" /> <property name="classesToBeBound"> <list> <value>com.devil.space.RPCRequest</value> <value>com.devil.space.RPCResponse</value> </list> </property> </bean>
RPCRequest and RPCResponse are the rest request and response java xml object respectively.So the full rest-servlet.xml file would be like:
<?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: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-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/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd></beans> <!-- @Controllers --> <context:component-scan base-package=com.devil.space.controller,com.devil.space.rest /> <bean class=org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping > <bean class=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter> <property name=messageConverters> <list> <ref bean=marshallingHttpMessageConverter > <bean class=org.springframework.http.converter.StringHttpMessageConverter > </list> </property> </bean> <bean id=marshallingHttpMessageConverter class=org.springframework.http.converter.xml.MarshallingHttpMessageConverter p:marshaller-ref=jaxb2Marshaller p:unmarshaller-ref=jaxb2Marshaller > <bean id=jaxb2Marshaller> <property name=schema value=classpath:/validate.xsd > <property name=classesToBeBound> <list> <value<com.devil.space.RPCRequest</value> <value<com.devil.space.RPCResponse</value> </list> </property> </bean> <bean id=viewResolver class=org.springframework.web.servlet.view.InternalResourceViewResolver> <property name=viewClass value=org.springframework.web.servlet.view.JstlView> </bean> </beans>
So if the xml file data is not as per xsd file validations,response message will be like :
“The request sent by the client was syntactically incorrect”
Thats it.You are done.!!
Now this message is kind of generic error message.If we want to know where exactly is the problem in our XML request,there are more things to be done:
1.Configuration in to rest-servlet.xml.
Add following configuration in to rest-servlet.xml:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver"> <property name="messageConverters"> <list> <ref bean="marshallingHttpMessageConverter" /> <bean class="org.springframework.http.converter.StringHttpMessageConverter" /> </list> </property> </bean>
2.Adding method for handling exception.
Lets us assume your controller class is :
@Controller @RequestMapping("/SaveXMLData") public class DownloadXMLDataEndPointController { @RequestMapping(value = "/SaveAndUpdateData", method = RequestMethod.POST) @ResponseBody public RPCResponse saveXMLRequestData( @RequestBody RPCRequest request) throws Exception { ----Logic for processing request----- RPCResponse response=new RPCResponse(); --construct response object---------- return response; } }
In the above controller class,add another method for handling exception:
@ExceptionHandler(HttpMessageNotReadableException.class) @ResponseStatus(value = HttpStatus.BAD_REQUEST) @ResponseBody RPCResponse handleXMLException(HttpMessageNotReadableException ex) { String error = "Invalid XML.Error is:-"; error = error + ex.getMessage(); String responseMessage = "FAILOVER"; RPCResponse response=new RPCResponse(); --construct response object---------- return response; }
So the complete Controller class would be :
@Controller @RequestMapping("/SaveXMLData") public class DownloadXMLDataEndPointController { @RequestMapping(value = "/SaveAndUpdateData", method = RequestMethod.POST) @ResponseBody public RPCResponse saveXMLRequestData( @RequestBody RPCRequest request) throws Exception { ----Logic for processing request----- RPCResponse response=new RPCResponse(); --construct response object---------- return response; } @ExceptionHandler(HttpMessageNotReadableException.class) @ResponseStatus(value = HttpStatus.BAD_REQUEST) @ResponseBody RPCResponse handleXMLException(HttpMessageNotReadableException ex) { String error = "Invalid XML.Error is:-"; error = error + ex.getMessage(); String responseMessage = "FAILOVER"; RPCResponse response=new RPCResponse(); --construct response object---------- return response; } }
Now if we deploy the application again.And send a xml request.If there is any validation error as per our XSD file,A detail error message will be in response stating in which line in XML request is the error.
Now if there is more than one XSD files which are been used to validate more than one type of XML request,We can configure them in single XSD file.Lets there are three XSD files (ABCD.xsd,PQRS.xsd,XYZT.xsd)for validating three types of XML request..Our validate.xsd will be as
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xs:include schemaLocation="ABCD.xsd" /> <xs:include schemaLocation="PQRS.xsd" /> <xs:include schemaLocation="XYZT.xsd" /> </xs:schema>
That is it.Similarly we can configure more XSD files for validating different types of XML requests.
If still there is any issue that you encounter :mail me at– parry.ism@gmail.com