Error setting rewrite jetty 9.4.8 - url-rewriting

I'm trying to set url rewrite in jetty 9.4.8.
I am using configuration file below:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.server.handler.ContextHandler">
<Set name="handler">
<New id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RewriteHandler">
<Set name="handler">
<New class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/QuestionWeb</Set>
<Set name="war"><SystemProperty name="jetty.base"/>\QuestionWeb.war</Set>
<Set name="extractWAR">true</Set>
<Set name="copyWebDir">true</Set>
</New>
</Set>
<Set name="rewriteRequestURI">true</Set>
<Set name="rewritePathInfo">false</Set>
<Set name="originalPathAttribute">requestedPath</Set>
<Call name="addRule">
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
<Set name="pattern">/test</Set>
<Set name="replacement">/question</Set>
</New>
</Arg>
</Call>
</New>
</Set>
</Configure>
After starting the java -jar server start.jar, redirection only works first to access the address:
http://localhost:8080/QuestionWeb/queston
Then access the address:
http://localhost:8080/QuestionWeb/test
If I try to access address "http://localhost:8080/QuestionWeb/test" before that address "http://localhost:8080/QuestionWeb/queston" I get error status 404.
My Servelt Code:
#WebServlet("/question")
public class QuestonServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss:SSS");
public QuestonServlet() { }
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().append(df.format(Calendar.getInstance().getTime())).append(request.getContextPath());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}

Related

How Do I Run My WAR in Jetty using Gretty plugin?

My current goal is to get gradle to start my web application running in a Jetty instance on my machine so that I can write Selenium tests against it. The Gretty plugin seems to be loading, but I haven't been able to find any actual instructions on how to create and configure a task to do that.
Part of the problem is that there is confusion with different versions and editions of the Gretty plugin. Just getting it to load in the first place was an exercise in trial-and-error.
I am trying to do the using Gradle 5.4.1 and Gretty 2.3.1, which I believe are the current versions (at this time).
I have three sub-projects "laoi" depends on "aofl" depends on "efl". The laoi build produces a WAR file. The task appRunWar seems to want to create and run its own WAR file, rather than using mine (at least that seems to be what's happening).
settings.gradle:
rootProject.name = 'aoi'
include 'cm', 'efl', 'aofl', 'laoi', 'uiTest'
build.gradle (laoi):
static def getDate() {
return new Date().format('yyyyMMdd-HHmmss')
}
final String timepickerAddonVersion = '1.6.3'
final String datatablesVersion = '1.10.19'
final String jqueryUIVersion = '1.12.1'
final String jqueryVersion = '3.2.1'
if (null == System.properties['aoi.release'] || null == System.properties['aoi.iteration']) {
if (null == System.env['RELEASE'] || null == System.env['ITERATION']) {
ext.ITERATION = "un"
ext.RELEASE = "dev"
} else {
ext.ITERATION = System.env['ITERATION']
ext.RELEASE = System.env['RELEASE']
}
} else {
ext.ITERATION = System.properties['aoi.iteration']
ext.RELEASE = System.properties['aoi.release']
}
System.setProperty('aoi.iteration', ext.ITERATION)
System.setProperty('aoi.release', ext.RELEASE)
if (null == System.properties['aoi.manifest']) {
if (null == System.env['MANIFEST']) {
System.out.println("Using default manifest name.")
ext.MANIFEST = "aoiManifest"
System.out.println("Manifest: ${ext.MANIFEST}")
} else {
ext.MANIFEST = System.env['MANIFEST']
}
} else {
ext.MANIFEST = System.properties['aoi.manifest']
}
System.setProperty('aoi.manifest', ext.MANIFEST)
System.out.println("Manifest: ${ext.MANIFEST}")
final String warFileName = 'aoi-'+ System.properties['aoi.release'] +'_'+ System.properties['aoi.iteration'] + ".war"
println "War file name: ${warFileName}"
final String sourceManifestName = "${ext.MANIFEST}.xml"
println "Source manifest name: ${sourceManifestName}"
def rootLibs = new File("${rootDir}/libs")
repositories {
mavenCentral()
jcenter()
flatDir {
dirs "${rootDir}/libs"
}
}
compileScala {
dependsOn ":efl:test", ":aofl:test"
}
task copyManifest(type: Copy) {
from('src/main/resources') {
include sourceManifestName
rename sourceManifestName, 'aoiManifest.xml'
}
into("${buildDir}/resources/main/bootstrap/liftweb")
}
task createVersionFile {
dependsOn "processResources"
doLast {
new File("${buildDir}/resources/main/aoiVersion.conf").text = "AOI_VERSION=" + System.properties['aoi.release'] +'-'+ System.properties['aoi.iteration'] + " (" + getDate() + ")"
new File("${buildDir}/resources/main/WebJarVersions.conf").text =
"""jQuery-Timepicker-Addon=$timepickerAddonVersion
datatables=$datatablesVersion
jquery=$jqueryVersion
jquery-ui=$jqueryUIVersion
jquery-ui-themes=$jqueryUIVersion
"""
}
}
war {
dependsOn ":aofl:test", "compileScala", "copyManifest", "processResources", "createVersionFile"
setDestinationDirectory(rootLibs)
setArchiveFileName(warFileName)
from('${buildDir}/resources/main') {
include '**/*.xml'
into("classes")
}
}
dependencies {
implementation project(":efl")
implementation project(":aofl")
implementation "org.webjars:jquery:$jqueryVersion"
implementation "org.webjars:jquery-ui:$jqueryUIVersion"
implementation "org.webjars:jquery-ui-themes:$jqueryUIVersion"
implementation "org.webjars:datatables:$datatablesVersion"
implementation "org.webjars:jQuery-Timepicker-Addon:$timepickerAddonVersion"
implementation 'org.webjars:webjars-servlet-2.x:1.1'
}
Since no answers were forthcoming I had to find an answer on my own.
Jetty has a feature that allows you to drop WAR files in a directory and it will load them. In order to make use of that, you have to either figure out what directory it's looking in, or tell it what directory to look in. I went for the second option.
The easiest way to specify a deploy directory is to put it in a "serverConfigFile" which is specified in the gretty options.
gretty {
serverConfigFile = "$contextFile"
servletContainer = 'jetty9.4'
jvmArgs <--- a bunch of arguments go here --->
}
Jetty comes with a bunch of configuration files in the "etc" directory. I viciously and blatantly plagiarized the main Jetty configuration file along with the deployment manager configuration file - but setting the path to one of my choosing. I created a task that writes the serverConfigFile.
task createJettyContextsFile {
doLast {
new File("$contextFile").text =
"""<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- =============================================================== -->
<!-- Documentation of this file format can be found at: -->
<!-- https://www.eclipse.org/jetty/documentation/current/ -->
<!-- -->
<!-- Additional configuration files are available in JETTY_HOME/etc -->
<!-- and can be mixed in. See start.ini file for the default -->
<!-- configuration files. -->
<!-- -->
<!-- For a description of the configuration mechanism, see the -->
<!-- output of: -->
<!-- java -jar start.jar -? -->
<!-- =============================================================== -->
<!-- =============================================================== -->
<!-- Configure a Jetty Server instance with an ID "Server" -->
<!-- Other configuration files may also configure the "Server" -->
<!-- ID, in which case they are adding configuration to the same -->
<!-- instance. If other configuration have a different ID, they -->
<!-- will create and configure another instance of Jetty. -->
<!-- Consult the javadoc of o.e.j.server.Server for all -->
<!-- configuration that may be set here. -->
<!-- =============================================================== -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Arg name="threadpool"><Ref refid="threadPool"/></Arg>
<!-- =========================================================== -->
<!-- Add shared Scheduler instance -->
<!-- =========================================================== -->
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.util.thread.ScheduledExecutorScheduler"/>
</Arg>
</Call>
<!-- =========================================================== -->
<!-- Http Configuration. -->
<!-- This is a common configuration instance used by all -->
<!-- connectors that can carry HTTP semantics (HTTP, HTTPS, etc.)-->
<!-- It configures the non wire protocol aspects of the HTTP -->
<!-- semantic. -->
<!-- -->
<!-- This configuration is only defined here and is used by -->
<!-- reference from other XML files such as jetty-http.xml, -->
<!-- jetty-https.xml and other configuration files which -->
<!-- instantiate the connectors. -->
<!-- -->
<!-- Consult the javadoc of o.e.j.server.HttpConfiguration -->
<!-- for all configuration that may be set here. -->
<!-- =========================================================== -->
<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<Set name="secureScheme"><Property name="jetty.httpConfig.secureScheme" default="https" /></Set>
<Set name="securePort"><Property name="jetty.httpConfig.securePort" deprecated="jetty.secure.port" default="8443" /></Set>
<Set name="outputBufferSize"><Property name="jetty.httpConfig.outputBufferSize" deprecated="jetty.output.buffer.size" default="32768" /></Set>
<Set name="outputAggregationSize"><Property name="jetty.httpConfig.outputAggregationSize" deprecated="jetty.output.aggregation.size" default="8192" /></Set>
<Set name="requestHeaderSize"><Property name="jetty.httpConfig.requestHeaderSize" deprecated="jetty.request.header.size" default="8192" /></Set>
<Set name="responseHeaderSize"><Property name="jetty.httpConfig.responseHeaderSize" deprecated="jetty.response.header.size" default="8192" /></Set>
<Set name="sendServerVersion"><Property name="jetty.httpConfig.sendServerVersion" deprecated="jetty.send.server.version" default="true" /></Set>
<Set name="sendDateHeader"><Property name="jetty.httpConfig.sendDateHeader" deprecated="jetty.send.date.header" default="false" /></Set>
<Set name="headerCacheSize"><Property name="jetty.httpConfig.headerCacheSize" default="4096" /></Set>
<Set name="delayDispatchUntilContent"><Property name="jetty.httpConfig.delayDispatchUntilContent" deprecated="jetty.delayDispatchUntilContent" default="true"/></Set>
<Set name="maxErrorDispatches"><Property name="jetty.httpConfig.maxErrorDispatches" default="10"/></Set>
<Set name="blockingTimeout"><Property deprecated="jetty.httpConfig.blockingTimeout" name="jetty.httpConfig.blockingTimeout.DEPRECATED" default="-1"/></Set>
<Set name="persistentConnectionsEnabled"><Property name="jetty.httpConfig.persistentConnectionsEnabled" default="true"/></Set>
<Set name="requestCookieCompliance"><Call class="org.eclipse.jetty.http.CookieCompliance" name="valueOf"><Arg><Property name="jetty.httpConfig.requestCookieCompliance" deprecated="jetty.httpConfig.cookieCompliance" default="RFC6265"/></Arg></Call></Set>
<Set name="responseCookieCompliance"><Call class="org.eclipse.jetty.http.CookieCompliance" name="valueOf"><Arg><Property name="jetty.httpConfig.responseCookieCompliance" default="RFC6265"/></Arg></Call></Set>
<Set name="multiPartFormDataCompliance"><Call class="org.eclipse.jetty.server.MultiPartFormDataCompliance" name="valueOf"><Arg><Property name="jetty.httpConfig.multiPartFormDataCompliance" default="RFC7578"/></Arg></Call></Set>
</New>
<!-- =========================================================== -->
<!-- Set the default handler structure for the Server -->
<!-- A handler collection is used to pass received requests to -->
<!-- both the ContextHandlerCollection, which selects the next -->
<!-- handler by context path and virtual host, and the -->
<!-- DefaultHandler, which handles any requests not handled by -->
<!-- the context handlers. -->
<!-- Other handlers may be added to the "Handlers" collection, -->
<!-- for example the jetty-requestlog.xml file adds the -->
<!-- RequestLogHandler after the default handler -->
<!-- =========================================================== -->
<Set name="handler">
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<Set name="handlers">
<Array type="org.eclipse.jetty.server.Handler">
<Item>
<New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
</Item>
<Item>
<New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
</Item>
</Array>
</Set>
</New>
</Set>
<!-- =========================================================== -->
<!-- extra server options -->
<!-- =========================================================== -->
<Set name="stopAtShutdown"><Property name="jetty.server.stopAtShutdown" default="true"/></Set>
<Set name="stopTimeout"><Property name="jetty.server.stopTimeout" default="5000"/></Set>
<Set name="dumpAfterStart"><Property name="jetty.server.dumpAfterStart" deprecated="jetty.dump.start" default="false"/></Set>
<Set name="dumpBeforeStop"><Property name="jetty.server.dumpBeforeStop" deprecated="jetty.dump.stop" default="false"/></Set>
<Call name="addBean">
<Arg>
<New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
<Set name="contexts">
<Ref refid="Contexts" />
</Set>
<Call name="setContextAttribute">
<Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
<Arg>.*/[^/]*servlet-api-[^/]*\\.jar\$|.*/javax.servlet.jsp.jstl-.*\\.jar\$|.*/org.apache.taglibs.taglibs-standard-impl-.*\\.jar\$</Arg>
</Call>
<Call id="webappprovider" name="addAppProvider">
<Arg>
<New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
<Set name="monitoredDirName">
<Property>
<Name>jetty.deploy.monitoredPath</Name>
<Default>
<Property name="jetty.deploy.monitoredDir" deprecated="jetty.deploy.monitoredDirName" default="$deployDirectory"/>
</Default>
</Property>
</Set>
<Set name="defaultsDescriptor">
<Property>
<Name>jetty.deploy.defaultsDescriptorPath</Name>
<Default>
<Property name="jetty.home" default="." />/etc/webdefault.xml
</Default>
</Property>
</Set>
<Set name="scanInterval"><Property name="jetty.deploy.scanInterval" default="1"/></Set>
<Set name="extractWars"><Property name="jetty.deploy.extractWars" default="true"/></Set>
<Set name="configurationManager">
<New class="org.eclipse.jetty.deploy.PropertiesConfigurationManager">
</New>
</Set>
</New>
</Arg>
</Call>
</New>
</Arg>
</Call>
</Configure>
"""
}
}
Then I added a task to copy the WAR file into the correct directory.
task copyWar(type: Copy) {
dependsOn ":cm:buildPS", ":laoi:war", 'createJettyContextsFile'
from("$rootLibs") {
include "*.war"
}
into("$deployDirectory")
}
I had to tweak the task dependencies a bit, but now the Gretty tasks that start up the Jetty server will all run with my WAR file properly deployed.

How to have dynamic endpoint mapping and wsdl definitions for Spring Webservices?

I have a webservice with endpoint defined as below -
#Endpoint
public class MyEndPoint {
private static final Log logger = LogFactory.getLog(MyEndPoint.class);
private static final String NAMESPACE_URI = "http://localhost:8080/soap/soap-ws/mySoapService";
#PayloadRoot(namespace = NAMESPACE_URI, localPart="mySoapRequest")
public #ResponsePayload MyResponse handleMySoapRequest(#RequestPayload MyRequest mySoapRequest) throws Exception{
//do something here
mySoapRequest.getUserId();
}
}
Then I have the request object
#XmlRootElement(name="mySoapRequest" , namespace="http://localhost:8080/soap/soap-ws/mySoapService")
#XmlAccessorType(XmlAccessType.NONE)
public class MySoapRequest {
#XmlElement
private String userId;
#XmlElement
private String userName;
}
This is my static wsdl
<?xml version="1.0" encoding="UTF-8" standalone="no"?><wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:sch="http://localhost:8080/soap/soap-ws/mySoapService" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://mycompany.com/ls/schemas" targetNamespace="http://mycompany.com/ls/schemas">
<wsdl:types>
<xsd:schema xmlns:tns="http://localhost:8080/soap/soap-ws/timeServices" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://localhost:8080/soap/soap-ws/mySoapService">
<xsd:element name="mySoapRequest">
<xsd:complexType>
<xsd:all>
<xsd:element name="userId" type="xsd:string"/>
<xsd:element name="userName" type="xsd:string"/>
</xsd:all>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
-----
---some more code which is not relevant here--
<wsdl:service name="mySoapService">
<wsdl:port binding="tns:mySoap11" name="mySoap11">
<soap:address location="http://localhost:8080/soap/soap-ws/mySoapService/"/>
</wsdl:port>
<wsdl:port binding="tns:mySoap12" name="mySoap12">
<soap12:address location="http://localhost:8080/soap/soap-ws/mySoapService/"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
My challenge is to have dynamic endpoint mappings so that I should be not bound to this url http://localhost:8080/soap/ when making request.
I would like to test webservice on dev server, qa server and then deploy to production without changing code.
I can define the endpoint url in properties file/dbase and then based on environment , would like to transform the request to appropriate url.
My questions
Can I modify the endpoint NAMESPACE_URI at run time ?
Can I transform the path in wsdl (maybe WsdlDefinitionHandlerAdapter) ?
Can I change the namesapce in MySoapRequest ?

406 Not Acceptable Spring Rest WS

I am writing a spring rest WS to return response as XML. Below are my classes and pom file.
I am getting Http 406 Error on executing the service as below:
http://localhost:8080/SpringRestExample/rest/emp/dummy.xml
However, I am getting the JSON response back when executing
http://localhost:8080/SpringRestExample/rest/emp/dummy.json
Please advise
pom.xml
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>${jackson.version}</version>
</dependency>
EmployeeController:
#RequestMapping(value = "/rest/emp/dummy", method = RequestMethod.GET,produces={"application/xml"})
public #ResponseBody Employee getDummyEmployeeXML() {
logger.info("Start getDummyEmployee");
Employee emp = new Employee();
emp.setId(9999);
emp.setName("Dummy");
emp.setCreatedDate(new Date());
empData.put(9999, emp);
return emp;
}
app-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<context:component-scan base-package="com.skanda.spring.controller" />
<beans:bean id="contentNegotiationManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<beans:property name="favorPathExtension" value="true" />
<beans:property name="favorParameter" value="true" />
<beans:property name="parameterName" value="mediaType" />
<beans:property name="ignoreAcceptHeader" value="true"/>
<beans:property name="useJaf" value="false"/>
<beans:property name="defaultContentType" value="application/json" />
<beans:property name="mediaTypes">
<beans:map>
<beans:entry key="json" value="application/json" />
<beans:entry key="xml" value="application/xml" />
</beans:map>
</beans:property>
</beans:bean>
Employee:
public class Employee implements Serializable{
private static final long serialVersionUID = -7788619177798333712L;
private int id;
private String name;
private Date createdDate;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#JsonSerialize(using=DateSerializer.class)
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
}
406 means that the server is not able to produce a response in the content type asked by the client. Check the Accept header of your HTTP request, and make sure it contains application/xml.
Maybe it contains text/xml, and that's what you should use in the producesattribute of your #RequestMappingannotation. BTW, you should use the constants in org.springframework.http.MediaType instead of hard-coding the string as you're doing.
for any type of xml conversion you need to add #XmlRootElement annotation on top of Model class. i have done the changes and run the above program and got the result.Just add #XmlRootElement above Employee class and you are done.

error in springifying junit with ant

When I execute the following I get a strange error:
"junit.framework.AssertionFailedError: No tests found in com.ac.spring.login.LoginServiceTest
I am using spring 3.0 with junit 4.x.
Test class:
#ContextConfiguration(locations={"classpath:META-INF/spring-context.xml","classpath:META-INF/spring-context-test.xml"})
public class LoginServiceTest extends AbstractJUnit4SpringContextTests{
#Autowired
private LoginServiceTestCase loginTestCase;
#Before
public void setup() {
loginTestCase.initialize();
}
#After
public void teardown() {
}
#Test
public void testLoginWithValidAccount() throws Exception {
loginTestCase.setTestName("Validate Login with valid credentials");
loginTestCase.setTestCondition(loginTestCase.CONDITION_USERNAME, "...");
loginTestCase.setTestCondition(loginTestCase.CONDITION_PASSWORD, "...");
loginTestCase.setExpectedResult(loginTestCase.RESULT_IS_ERROR, false);
assertTrue(loginTestCase.isTestPass());
}
....
}
Case to be tested:
public class LoginServiceTestCase extends TestCase{
#Autowired
private LoginService loginService; // the class to be tested
......
protected void executeTest() throws Exception {
try {
..... } catch (Exception e) {
isError = true;
}
}
build.xml:
<target name="compile" >
<echo message="-----> Compile Classes from ${src}" />
<mkdir dir="${build}/classes" />
<javac srcdir="${src}"
includes="**/*.java"
destdir="${build}/classes"
debug="on">
<classpath refid="dependencies"/>
</javac>
<copy todir="${build}/classes/META-INF">
<fileset dir="${basedir}/config" includes="**"/>
</copy>
</target>
<target name="batch-test" >
<mkdir dir="${reports.tests}"/>
<junit printsummary="yes" haltonfailure="yes">
<classpath>
<pathelement location="${build}/classes"/>
<path refid="dependencies"/>
</classpath>
<formatter type="plain"/>
<formatter type="xml"/>
<batchtest fork="yes" todir="${reports.tests}">
<fileset dir="${src}">
<include name="**/*Test.java"/>
</fileset>
</batchtest>
</junit>
</target>
Where am I going wrong?
Wanted to close this question - but just wanted to inform the problem was with the ant version.Moving up from ant 1.5 to 1.7 took care of the issue.

Getting data elements from SOAP request

My Request comes as below
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hel="http://example.org/HelloService">
<soapenv:Header>
<sampler>Test</sampler>
</soapenv:Header>
<soapenv:Body>
<hel:LastName>
<lastName>Test</lastName>
</hel:LastName>
</soapenv:Body>
</soapenv:Envelope>
My flow which exposes my CXF:proxy-service is as below
<flow name="WS_In">
<http:inbound-endpoint address="http://localhost:8080/HelloService"
exchange-pattern="request-response">
<cxf:proxy-service wsdlLocation="classpath:helloservice.wsdl"
namespace="http://example.org/HelloService" service="ProxyService" >
<cxf:inInterceptors>
<spring:bean id="inLogger"
class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<spring:bean id="msgInt" class="com.example.components.MessageInterceptor"/>
</cxf:inInterceptors>
</cxf:proxy-service>
</http:inbound-endpoint>
<component>
<spring-object bean="proxyService"></spring-object>
</component>
<echo-component></echo-component>
</flow>
But I am not able to get the elements in the soap header. I tried using interceprots with method like below
#Override
public void handleMessage(SoapMessage message) throws Fault {
System.out.println("The headers is " + message.getHeaders() );
}
But this is printing an emply Collection.
Please suggest how I can get this.
Try adding a custom-processor on your flow before the proxy-service
<flow name="WS_In">
<http:inbound-endpoint address="http://localhost:8080/HelloService"
exchange-pattern="request-response">
<custom-processor class="your.package.SoapHeaderObserver" />
<cxf:proxy-service wsdlLocation="classpath:helloservice.wsdl"
namespace="http://example.org/HelloService" service="ProxyService" >
<cxf:inInterceptors>
<spring:bean id="inLogger"
class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<spring:bean id="msgInt" class="com.example.components.MessageInterceptor"/>
</cxf:inInterceptors>
</cxf:proxy-service>
</http:inbound-endpoint>
<component>
<spring-object bean="proxyService"></spring-object>
</component>
<echo-component></echo-component>
public class SoapHeaderObserver {
doSomething(SoapMessage message) {
//try to get header here
}
}
Also, your custom-processor can implement MessageProcessor or Callable. Take a look here on How to implement a Mule Message Observer?
And also, the framework have a lot of processors that you might use, instead of building your own.
I got the solution be adding a message processor before my proxy-service.
Given below is my processor.
public class SOAPHeaderExtractor implements MessageProcessor {
#Override
public MuleEvent process(MuleEvent event) {
try
{
MuleMessage inputMessage = event.getMessage();
SOAPMessage soapMsg = MessageFactory.newInstance().createMessage(null,
new java.io.ByteArrayInputStream(inputMessage.getPayloadAsString().getBytes()));
SOAPHeader header = soapMsg.getSOAPHeader();
System.out.println(header.getElementsByTagName("sampler").item(0).getTextContent() );
}
catch(Exception e){
e.printStackTrace();
}
return event ;
}
}
And the change to my flow.
<http:inbound-endpoint address="http://localhost:8080/HelloService"
exchange-pattern="request-response">
<custom-processor class="com.example.processors.SOAPHeaderExtractor" />
<cxf:proxy-service wsdlLocation="classpath:helloservice.wsdl"
namespace="http://example.org/HelloService" service="ProxyService" >
<cxf:inInterceptors >
<spring:bean id="inLogger" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
</cxf:inInterceptors>
</cxf:proxy-service>
</http:inbound-endpoint>
Please do suggst if there is any better way.

Resources