Introduction
The Spring Web Service tutorial is pretty good, but doesn't really go down far enough to explain how to build a basic Spring Web Service from scratch. People who are already familiar with Java and either NetBeans or Eclipse won't need much more than the listings under the source code and configuration files section. For the sake of brevity, here is a simple explanation of what each file is and where it should go in a NetBeans project.
- Web.xml - Standard Java Enterprise Edition web configuration file. Goes in web/WEB-INF in a NetBeans project.
- schema.xsd - A XML schema which defines two XML elements: RequestObject and ResponseObject. Goes in web/WEB-INF.
- spring-ws-servlet.xml - A Spring context file which defines a number of Java beans either from the Spring Web Service toolkit or from the files added/generated in the NetBeans project. Goes in web/WEB-INF. This context does the following things that are worth-noting:
- Defines an instance of the endpoint object
- Provides a "payload mapping" which maps the namespace-qualified RequestObject XML document to the endpoint.
- Provides a JAXB2 Marshaller which is used by the endpoint.
- Adds a validating interceptor object which validates the incoming and outgoing XML against the schema.
- Defines an instance of DefaultWsdl11Definition which will generate a WSDL on the fly at the absolute URL of the deployed web application under the file name basicSpringWS.wsdl.
- org.springframework.ws.examples.BasicMarshallingEndpoint - A POJO which extends the AbstractMarshallingPayloadEndpoint base class from the Spring Web Services toolkit. The incoming object will be a JAXB2-generated RequestObject. The return should be a JAXB2-generated ResponseObject. In NetBeans, simply add the contents of figure 4 to a new POJO with the same package and class name.
- com.springframework.ws.examples.test.BasicTest - a JUnit4 test case which extends off of WebServiceGatewaySupport, a Spring helper class which makes sending to and receiving from a web service as simple as defining a source and a result object.
The dependencies for a successful deployment are roughly:
- activation-1.1.1.jar
- aopalliance-1.0.jar
- castor-1.2.jar
- commons-logging.jar
- log4j-1.2.15.jar
- saaj-api-1.3.jar
- saaj-impl-1.3.2.jar
- spring-aop-2.5.6.jar
- spring-beans-2.5.6.jar
- spring-context-2.5.6.jar
- spring-context-support-2.5.6.jar
- spring-core-2.5.6.jar
- spring-oxm-1.5.8.jar
- spring-oxm-tiger-1.5.8.jar
- spring-web-2.5.6.jar
- spring-webmvc-2.5.6.jar
- spring-ws-core-1.5.8.jar
- spring-ws-core-tiger-1.5.8.jar
- spring-xml-1.5.8.jar
- stax-api-1.0-2.jar
- wsdl4j-1.6.1.jar
- xalan-2.7.0.jar
- xercesImpl-2.8.1.jar
- xml-apis-1.3.04.jar
That list is just one that I threw together to be on the safe side. It's based on the files that were added by maven when I ran the maven package target on the EchoWS example, and trial-and-error getting the rest of the dependencies resolved.
Source Code and Configuration Files
Figure 1: web.xml
Figure 2: schema.xsd
Figure 3: spring-ws-servlet.xml
Figure 4: Endpoint
Figure 5: JUnit Test
Steps in NetBeans 6.5+
Create a new web project.
Open the WEB.xml file in WEB-INF (under Web Pages in the Project tree), and copy in the contents of Figure 1. Right click on the project, and add two new empty files into the WEB-INF directory and name them schema.xsd and spring-ws-servlet.xml. Paste in the contents of figures 2 and 3 respectively. Now, add a new Java class to the project, using the contents of figure 4.
Create a JUnit test using the contents of figure 5. Save everything, right click on the project and select deploy. That will build the war file, start Tomcat or Glassfish, and install the web service. Once the service is deployed, right click on the JUnit and run it to test it.
If I missed a step that needs clarification, just leave a comment in the comments section.
What about the RequestObject and ResponseObject classes?
My compiler cries about them that they cannot be resolved to a type inside the BasicMarshallingEndpoint class
Thank you
Did you create them through the JAXB compiler/NetBeans task?
I finally got my first spring webservice working because of your example.
Thanks.
Hi,
Can you please give an example of how to call this service using javascript as a client
You really wouldn't want to call a SOAP web service via JavaScript. If you need to be able to easily call a web service from JavaScript, implement it as a REST service.
could not make it work...
got the error:
org.springframework.ws.client.WebServiceTransportException: Not Found [404]
It works now!! Redeployed the war file on tomcat. However, could not see the .wsdl
same problem... deployed in tomcat but could not generate the wsdl file........Pls help.........
Could not see .wsdl earlier since was looking at the wrong path.
I have a question. I worked on a spring webservice that works fine on my local tomcat. however, when I deployed the same .war file on a tomcat on different location, it stopped working. I changed the IS_AUTHENTICATED_ANONYMOUSLY to /**, but it didnt work. What is wrong?
Why don't you post that question on the Spring forums?
"The dependencies for a successful deployment are roughly"
What exactly libraries related to JAXB ? If'm not mistaken, JAXB is in javax.xml... and in org.springframework.oxm.jaxb.
Am I wrong?
Should I add another additional JAXB libs for Netbeans?
JAXB is in java.xml... The second choice are Spring's APIs for using JAXB. Just add the JAXB 2.0 "library" in NetBeans.
Can you tell me for what exactly Castor is used.
Is it used for marshaling/unmarshaling stuf? or for DAO?
I Spring + MVC + Hibernate project. And i am forking on wb service with Spring WS.
Want to clarify all libraries which you listed above.
According to the great oracle Google, Castor is a XML-mapping library. How it is used here is beyond my pay grade at the moment.
I've done everything. I have generated wsdl file, and Test is good.
But I have one trouble - I've researched netbeans project and JAXB, and "Regenerate Java code" doesn't get new information from /web/WEB-INF/schema.xsd after editing it.
But when I edit src/conf/xml-resources/jaxb/UNIQUENAME/schema.xsd (this file is shown under "JAXB Binding" item in project) - THEN "Regenerate Java code" works, and appropriated package is regenerated.
So, is it normal?
I thought that I can edit /web/WEB-INF/schema.xsd and after that regenerate these new changes to Java.
Please help me to understand how JAXB work on Netbeans with XSD file regeneration.
The JAXB plugin for NetBeans caches the XSD. If you right click on the JAXB binding part of the project, one of the options should be something like "refresh schema" or reload it. Point is, it'll say something that indicates that it will recache the XSD from the WEB-INF directory.
I'm trying to deploy it on jboss-5.1.0.GA but getting following error even though all specified jars are in application's lib directory and in JBoss lib folder as well.
Caused by: java.lang.NoClassDefFoundError: org/springframework/web/servlet/FrameworkServlet
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)....................
That means you are missing part of the Spring Framework or JBoss is having problems loading or locating the Spring Framework jars.
You are correct.... i was missing some jars. Now i have included but getting another error
I don't know what your requirements are, but in my limited experience with web services, if you can avoid using SOAP services altogether in favor of REST, you should. I've found JAX-RS to be significantly easier to use than any SOAP toolkit.
Now It is throwing following error
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'marshaller' defined in ServletContext resource [/WEB-INF/spring-ws-servlet.xml]: Initialization of bean failed; nested exception is java.lang.NoSuchMethodError: org.springframework.util.ObjectUtils.isEmpty([Ljava/lang/Object;)Z
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:341)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:222)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:146)
That's a very tricky type of bug in Spring. It means that something is wrong with the way you defined the marshaller bean. Spring can be very anal about bean definitions, so I suggest you focus your attention on carefully reading over how you defined that bean and if you see nothing there, look at any other beans it depends on that you've defined in the Spring context file.
I've copied all the code from this site. Also i tried the following thing
Without initializing anything here, i tired to access the service, expecting atleast error message should change. But i got no success. Could you tell me what might be wrong?
No idea. It worked for me, and judging from the comments, most people have found it to work for them as well. I copied everything straight out of a working NetBeans project, so there's no reason why it shouldn't work in at least a web app project created in NetBeans and deployed on Tomcat.