I have a SOAP request similar to this:
<SOAP-ENV:Envelope>
<SOAP-ENV:Header>
....
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<MyRequest>
<Param>3</Param>
</MyRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
and the response should be like
<SOAP-ENV:Envelope>
<SOAP-ENV:Header>
....
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<MyResponse>
<Value>3234</Value>
<Value>542</Value>
</MyResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
My problem is that my JAX-WS SOAP service expects a namespace e.g. xmlns="http://myapp.example.com" in MyRequest. It also adds this namespace to the MyResponse element too.
I have managed to write an Interceptor that will add my apps target namespace to the request message if it is blank. This works fine.
My issue right now is that I am not sure how to remove this namespace from the response message.
I know the best solution would be to have clients use namespaces, however this is not possible on the project I am working on.
CXF comes with Transformation Feature, Please have look here
A sample bean extract from page.
<bean id="transformFeature" class="org.apache.cxf.feature.StaxTransformFeature">
<property name="outTransformElements">
<map>
<!-- change "book" to "thebook" -->
<entry key="book" value="thebook"/>
<!-- drop the namespace from "book" -->
<entry key="{http://books}book" value="book"/>
<!-- qualify "book" with "http://books" -->
<entry key="book" value="{http://books}thebook"/>
<!-- change namespace to "http://books" for all the elements with the "http://book" namespace -->
<entry key="{http://book}*" value="{http://books}*"/>
</map>
</property>
</bean>
That's pretty broad since we don't know what you are using, but if you can use Metro (JAX-WS) then you can take advantage of what they call SOAPMessage Handler (have a look here). It works pretty much like a Servlet filter component.
Have something that implements SOAPHandler<SOAPMessageContext> and remove the namespace declaration(s) there.
Related
Moving from web.xml to OSGi Http Whiteboard pattern created bundle-context.xml
how to pass below properties from web.xml in jspServletfilter's osgi:service-properties
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>true</el-ignored>
</jsp-property-group>
</jsp-config>
I tried below solution but it does not work.
<bean id="jspServlet" class="com.test.servlet.web.servlet.TestJSPServlet"/>
<osgi:service ref="jspServlet" interface="javax.servlet.Servlet" >
<osgi:service-properties>
<entry key="osgi.http.whiteboard.filter.name" value="JSPServlet" />
<entry key="osgi.http.whiteboard.servlet.pattern" value-ref="jspPatternsList"/>
<entry key="osgi.http.whiteboard.context.select" value="(osgi.http.whiteboard.context.name=cb)" />
<entry key="servlet.init.el-ignored" value="true" />
</osgi:service-properties>
</osgi:service>
I just checked one more time, but if I'm not completely wrong the OSGi spec doesn't handle JSPs in a certain way. So what you are trying to do there doesn't work with the Apache Felix implementation.
The only way to have JSPs working with the Http Whiteboard approach is to switch to the Pax - Web Project. As it not only supports the Whiteboard approach (spec compliance is still work in progress, 6.0.0-SNAPSHOT) but also more then there is in the spec right now.
To achieve what you want the following is needed with Pax-Web:
<!-- JSP handling -->
<service id="jspMapping" interface="org.ops4j.pax.web.extender.whiteboard.JspMapping">
<bean class="org.ops4j.pax.web.extender.whiteboard.runtime.DefaultJspMapping">
<property name="urlPatterns">
<array>
<value>/jsp</value>
</array>
</property>
</bean>
</service>
an example can also be found in the samples of the pax-web project.
I'm using SpringWSTemplate Client to send a message.
Using the method sendSourceAndReceiveToResult(Source requestPayload, WebServiceMessageCallback requestCallback, Result responseResult).
In this I'm setting a few security credentials using wss4jsecurityinterceptor.
But currently I'm in need of setting a custom tag (RegisterKey) inside usernametoken as similar to shown below.
<wsse:Security soap:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-11" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>test</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">a287645857cfaaddf82e2d333651b3e0</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">oKGlwEkbkhYJH6upsbiqeQ==</wsse:Nonce>
<wsu:Created>2011-10-25T13:10:11.958Z</wsu:Created>
<RegisterKey>UUUiiiIUBGGGTTT</RegisterKey>
</wsse:UsernameToken>
</wsse:Security>
I tried using Transformer (java.xml.transform.transformer) to inject the custom tag, but it's getting injected straight to SoapHeader and not within UsernameToken.
These details are already provided by spring-ws dependency
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-security</artifactId>
<version>1.5.6</version>
</dependency>
Add the below details in the spring-config.xml to get the below details
<bean id="xwsSecurityInterceptor"
class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
<property name="securementActions" value="UsernameToken" />
<property name="securementUsername" value="UNAME" />
<property name="securementPasswordType" value="PasswordText" />
<property name="securementPassword" value="Pass" />
<property name="securementMustUnderstand" value="false" />
</bean>
And add the interceptor to the webserviceTemplate
I had done this using implementing ClientInterceptor
org.springframework.ws.client.support.interceptor.ClientInterceptor
ClientInterceptor does have a handleRequest(MessageContext context) method in which we can manipulate the request message(including the SoapHeaders).
Using org.apache.axiom.om.OMContainer you can iterate through the elements and using org.apache.axiom.om.impl.llom.OMElementImpl you can add a new element and set its value too.
I am using java and cxf SOAP webservices. I have enabled schema validation as below but it is not working. I dont have any external xsds. All xsd elements are part of WSDL. Will schemavlaidation= true property does not work if it has no external xsd and all xsd elements are part of WSDL? I placed minOccur and maxOccur attributes.
<jaxws:endpoint id="serviceEndpoint" implementor="#serviceEndpoint"
address="/CreateService" wsdlLocation="classpath:wsdl/Service.wsdl">
<jaxws:properties>
<entry key="schema-validation-enabled" value="true" />
</jaxws:properties>
</jaxws:endpoint>
I'm having a problem with RESTlet Framework configuration with Spring. I want to have one global filter for all requests and responses. I guess I can use Filter class and it's methods beforeHandle, afterHandle and setNext like this:
Filter.beforeHandle() -> Router -> Filter.afterHandle()
The problem is, that I'm using Spring configured RESTlet and I don't know if the regular Filter will work correctly with SpringRouter from org.restlet.ext.spring package. My current restlet configuration is as follows:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="root" class="org.restlet.ext.spring.SpringRouter">
<property name="attachments">
<map>
<entry key="/login">
<bean class="org.restlet.ext.spring.SpringFinder">
<lookup-method name="create"
bean="loginResource" />
</bean>
</entry>
</map>
</property>
</bean>
</beans>
I'm thinking about adding a bean with id root and class that extends class Filter, and pass to it as property next a bean with id router (which currently is called root). What do you think about this solution?
Mixing Restlet classes from the Spring extension with other one shouldn't be an issue. Spring* classes only provide additional configurability.
I'm migrating my xfire soap project which uses aegis for databinding to cxf with jaxb. I got the new cxf project working for old xfire requests with aegis binding. But when i move the databinding to jaxb unmarshalling errror occurs.
This is my cxf web service definition.
<!--<bean id="aegisBean" class="org.apache.cxf.aegis.databinding.AegisDatabinding" scope="prototype"/> -->
<bean id="jaxbBean" class="org.apache.cxf.jaxb.JAXBDataBinding" scope="prototype"/>
<bean id="jaxws-and-aegis-service-factory" class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean"
scope="prototype">
<property name="dataBinding" ref="jaxbBean"/>
<property name="serviceConfigurations">
<list>
<bean class="org.apache.cxf.jaxws.support.JaxWsServiceConfiguration"/>
<bean class="org.apache.cxf.aegis.databinding.XFireCompatibilityServiceConfiguration"/>
<bean class="org.apache.cxf.service.factory.DefaultServiceConfiguration"/>
</list>
</property>
</bean>
<jaxws:endpoint id="trace" address="/trace" implementor="#traceImplBean">
<jaxws:serviceFactory>
<ref bean="jaxws-and-aegis-service-factory"/>
</jaxws:serviceFactory>
<jaxws:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
</jaxws:outInterceptors>
</jaxws:endpoint>
I used #XMLRootElement Annotaion on my DTOs as following.
#XmlRootElement(name = "context" )
public class Context implements Serializable {
private KeyValues keyValues;
.....
}
#XmlRootElement(name = "keyValues" )
public class KeyValues implements Serializable {
private String tag;
private String value;
....
}
One method which i tested generated following soap request for cxf
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pay="http://example.project.com">
<soapenv:Header/>
<soapenv:Body>
<pay:trace>
<pay:context>
<keyValues>
<tag>tag</tag>
<value>value</value>
</keyValues>
</pay:context>
</pay:trace>
</soapenv:Body>
</soapenv:Envelope>
HOWEVER old xfire generate following request, I have mark the difference.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pay="http://example.project.com" xmlns:api="http://example.com">
<soapenv:Header/>
<soapenv:Body>
<pay:trace>
<pay:context>
<api:keyValues>
***<api:KeyValues>***
<api:tag>tag</api:tag>
<api:value>value</api:value>
***</api:KeyValues>***
</api:keyValues>
</pay:context>
</pay:trace>
</soapenv:Body>
</soapenv:Envelope>
I got following exception when i tried to send xfire request to cxf service.
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://example.project.com", local:"keyValues"). Expected elements are <{}keyValues>
So I think i need to add additional tags to cxf request inorder to compatible with xfire. Does anyone knows how to resolve this ?
Thanks in advance.
JAXB, by default, uses unqualified elements whereas Aegis/XFire by default used qualified elements. Couple ways around that:
1) For every element, specify the namespace.
#XmlElement(name = "tag", namespace = "http:...")
likely easier:
2) Add a package-info.java with:
#javax.xml.bind.annotation.XmlSchema(namespace = "http://......",
elementFormDefault = XmlNsForm.QUALIFIED)