How to make XSD validation in a REST based web service XML Request by using XSD file and JAXBMarshaller


Computer  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

5 thoughts on “How to make XSD validation in a REST based web service XML Request by using XSD file and JAXBMarshaller

  1. I tried your code but it’s not working for me. My xml is not getting validated . I have changed the xsd so that the validation fails but it is going thru fine and not hitting any exception

    Here is the spring xml config

    dataAccessFailure
    resourceNotFound
    resourceNotFound
    resourceNotFound

    org.acs.ecta.resource.Manuscript
    org.acs.ecta.resource.ResponsePayload

    and the controller is :

    @Controller
    public class MyController {

    @Autowired
    private MyService myService;

    private ResponsePayload resPayload;

    private static final Logger logger = LoggerFactory.getLogger(EctaController.class);

    @RequestMapping(value=”/submitManuscript”,method=RequestMethod.POST)
    public @ResponseBody ResponsePayload addManuscript( @RequestBody Manuscript xmlManuscript)throws Exception {

    resPayload=myService.submitXMLManuscript(xmlManuscript);

    return resPayload;

    }

    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    @ResponseBody
    String handleXMLException(HttpMessageNotReadableException ex) {

    String error = “Invalid XML Error is :”;
    error = error + ex.getMessage();
    String responseMessage = “FAILOVER”;

    System.out.println(“XSD Error :”+responseMessage +”:”+error);

    return error;
    }
    }

  2. Hello Parvinder,

    Great post indeed. Can you also post the Spring 4 annotation based configuration for the same.

    Many thanks,

    Best Regards,
    Chandra.

  3. There is not much difference if we will use Spring 4 .Only change that need to do is to use @RestController instead of @Controller in the Controller class. By using @RestController in the controller class , @ResponseBody annotation is active by default and so there is no need to specify @ResponseBody in every request mapping methods in the controller class.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s