Spring Web Services and Spring Security Exception handling - exception

I am trying to think of an solution to cascade exceptions from Spring security as soap faults in Spring Web services.
We use Spring web services and perform authentication using SimplePlainTextPasswordValidationCallbackHandler. However all customized exceptions from within spring security get output as a "Invalid Soap Header" in the soap response. This is believe is the default behavior.
Any way we could perhaps override this behavior to cascade our customized exception to Spring WS?
Thanks.

For this you need to implement an EndpointExceptionResolver as the handleValidationException method of the XwsSecurityInterceptor delegates the exception to this resolver as mentioned here and also here . Or you can simply add SoapFaultMappingExceptionResolver to your applicationContext.xml like this:
<beans>
<bean id="exceptionResolver" class="org.springframework.ws.soap.server.endpoint.SoapFaultMappingExceptionResolver">
<property name="defaultFault" value="SERVER"/>
<property name="exceptionMappings">
<value>
org.springframework.oxm.ValidationFailureException=CLIENT,Oops!Something went wrong
</value>
</property>
</bean>
</beans>
More Info on this here

Related

How to host and transform SOAP message in WSO2

I am relative new in WSO2 to create services, and i have to do a project in the enterprise where i work. First i had to take a message in, for example, json and send xml. I was able to do so, with this code:
<?xml version="1.0" encoding="UTF-8"?>
<api context="/Test" name="JsonToXmlApi" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" uri-template="/xml/">
<inSequence>
<property name="messageType" scope="axis2" type="STRING" value="text/xml"/>
<header action="remove" name="To" scope="default"/>
<property name="RESPONSE" scope="default" type="STRING" value="true"/>
<send/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
Now i need to do the following, i have to send a message in SOAP, XML format, consume it in SOAP and receive back with JSON or XML format.
Someone could help me? I am asking because i am searching for tutorials, for beginners, about it for more than a week, and wasn't able to solve my problem.
Another question, would be possible to do this in REST API project?
If someone could help me, with a detailed tutorial or good video teaching that, i would be grateful.
Thank you.
Your post is a bit unclear but I will try to summarise the typical common combinations of input interface, wso2 component and backend services when you are developing web services.
Web services are services you can invoke over http or https - you might have three types of interfaces for these and you might use two types of WSO2 ESB components - proxy and API - to develop these.
1) Input/Output: JSON
WSO2 component: API
Backend: Any (JSon/XML/SOAP)
2) Input/Output: Plain XML
WSO2 component: API
Backend: Any (JSon/XML/SOAP)
3) Input/Output: SOAP
WSO2 component: Proxy
Backend: Any (JSon/XML/SOAP)
One of the key components of any SOAP service is the WSDL - the WSO2 proxy allows you to publish a WSDL so that your caller knows what sort of data and operations your service provides.
See more here: https://docs.wso2.com/display/EI611/Working+with+Proxy+Services
Adding this note only because you asked:
Technically, you might be able to receive a SOAP message in an API component because SOAP is just an XML document - but it would be really pointless. The purpose of the API component is to expose resources and allow you to perform HTTP operations (GET, POST etc) on those resources (this model can be called REST).
The purpose of a SOAP based web service is to expose data and operations as defined in a WSDL and the WSO2 proxy component is what allows you to do that.

CXF JSON Schema Validation

I am writing RESTFul webservices which support both XML and JSON format. I need to add schema validation in the webservices. My beans are auto generated using JAX-B. As suggested at CXF's site at Schema validation, I am using org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider as JSON provider and org.apache.cxf.jaxrs.provider.JAXBElementProvider as JAX-B provider. The request and response is working fine but now I want to add schema validation.
The sample code at above CXF link is not working for me for JSON schema validation (its working for XML schema validation). They shown it for org.apache.cxf.jaxrs.provider.json.JSONProvider (under 'Schema Validation' section) which doesn't work for me as my beans are JAX-B generated, so I am using JacksonJaxbJsonProvider.
Is there any solution for this problem? Could somebody please suggest some approach that I can try?
Below is the XML configuration:
<bean id="jsonProvider" class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider"/>
<bean id="schemaHolder" class="org.apache.cxf.jaxrs.utils.schemas.SchemaHandler">
<property name="schemas" ref="theSchemas"/>
</bean>
<util:list id="theSchemas">
<value>classpath:/WEB-INF/classes/po.xsd</value>
</util:list>
<!-- Person REST Service Configurations -->
<bean id="personRESTServiceImpl" class="com.abc.webservices.service.rest.PersonRESTService" />
<jaxrs:server id="personRESTService" address="/person-rest-service">
<jaxrs:serviceBeans>
<ref bean="personRESTServiceImpl" />
</jaxrs:serviceBeans>
<jaxrs:providers>
<ref bean="jaxbProvider" />
<ref bean='jsonProvider' />
</jaxrs:providers>
</jaxrs:server>
Your classpath is wrong, in web application classpath is WEB-INF/classes
Hence you can use following configuration
<jaxrs:schemaLocations>
<jaxrs:schemaLocation>classpath:po.xsd</jaxrs:schemaLocation>
</jaxrs:schemaLocations>
if you have xsd directory in classes directory then classpath:xsd/po.xsd

Spring RESTful Web Service with JSON gives HTTP 406 error code

I am using Spring 3.2.5 to create a RESTful web service. To implement it I've used #ResponseBody tag. When I use InternalResourceViewResolver and try to load Html response then it is working fine. But when I call a URL which is marked as #ResponseBody then it gives HTTP 406 error code with error text as
The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers.
I have included Jackson jar files in my lib directory as well.
Here is my controller method which handles service request.
#ResponseBody
#RequestMapping (value = "/resp.htm")
public Data jsonResp() {
Data d = new Data();
d.setName("TEst");
d.setAddr("Address....");
return d;
}
There are lots of questions have been asked & answered, I've tried many of them, but it still gives the same result. Then I came across a new kind of answer, which was stating to use ContentNegotiatingViewResolver. By using it I am able to view response in intended format. That is JSON format.
After using ContentNegotiatingViewResolver, servlet dispatcher code looks like this:
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
</map>
</property>
<property name="defaultViews">
<list>
<!-- JSON View -->
<bean
class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
</bean>
</list>
</property>
<property name="ignoreAcceptHeader" value="true" />
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="order" value="2" />
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
So, my question is, whenever we require to use Spring's Web Service feature, do we must require to have ContentNegotiatingViewResolver?
Add gson in your class path. as well as jackson
I had a similar issue while calling a spring rest service from angular 8 for uploading a file. I was using ResponseEntity to encapsulate the success or failure message for which I was having the 406 response. all I did was in the UI side this.httpClient.post(url, formData,{responseType: 'text'}) and I was able accept the string as response from the service response.
The annotation #ResponseBody used with custom class types, generally uses MappingJackson2HttpMessageConverter to convert the object to JSON and return it in application/json content.
Since your request doesn't contain an Accept header for application/json, Spring deems the content it's creating as unacceptable and instead returns a 406.
You could simply change your request to add the Accept header. (You can't do this easily in a browser).
In my case the request had .html suffix and received this error. Once removed, it worked fine.
All you need to do is to add jackson libraries to your classpath find them Here

Spring Restful, Post multiple formats like json/xml/domain object into same action

I am writing a Spring Restful webservices application using Spring MVC. I have used content negotiating viewer to respond multiple data formats for eg. If some one requests a URL with .xml extension an XML will be sent in response body similarly if someone requests with an .json extension, an json will be sent in response body.
Now, I want the same process inwards, say if some body wants to post a Json or xml or a simple post from a webpage form using post method to same action, it should be able to handle all these.
This way i will be able to write a Web Service+Web Application in a single Spring MVC+Restful Application.
Thanks in advance for the help :)
You can use headers attribute of #RequestMapping annotation.
#RequestMapping(value = "/pets", method = RequestMethod.POST, headers="content-type=text/*")
to narrow content-type of requests your method is going to serve.
edit:
If you want to sent different content type in request body, then the only thing you need to do is to define MessageConverter (I assume you already did that) and annotate your method parameter with
#RequestBody
Spring should deserialize the body of your request using the MessageConverter you defined.
So assuming you have something like:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<util:list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
</util:list>
</property>
</bean>
<bean id="contentNegotiatingViewResolver" class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<util:map>
<entry key="json" value="application/json"/>
</util:map>
</property>
<property name="defaultViews">
<util:list>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
</util:list>
</property>
</bean>
in your spring context.
Annotating your method like this:
#RequestMapping(method=PUT, value="/user/{user_id}")
public void putUser(#RequestBody User user, #PathVariable int user_id) {
...
}
should do the job.
You don't have to do anything. You register converts and they will in turn tell "spring" what Content-types they can handle. XStream registers application/xml and text/xml (perhaps more), jackson registers application/json and so on.
It's all available at http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-ann-responsebody
I also don't like the filename-standard, I prefer to leave that to the same converter. In that case it will look at the Accept-header. If you want json, set Accepts: application/json.

spring prefixjson with responsebody

when controller method return is #responsebody , even if i put
<bean
class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
<property name="prefixJson" value="true" />
</bean>
there will no && {} insert at the front of json data. anyone knows what is reason?
JSON in #RequestBody/#ResponseBody is handled by MappingJacksonHttpMessageConverter which is configured in AnnotationMethodHandlerAdapter.messageConverters.
The easy way to configure it without interference with other features is to create a BeanPostProcessor to intercept creation of AnnotationMethodHandlerAdapter, see, for example, here.