In this shortish part, we'll add some interfaces to our application so external users can read the current greetings. Expanding the interfaces so greetings can be added is left as an exercise for the reader
JAX-RS
REST is hip (and now in EE 6 as JAX-RS) so let's throw it in. Add
package com.acme.greetings;
import java.util.List;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@Path(value = "/RESTExport")
public class RESTExporter
{
@Inject
GreetingServer greetingServer;
@GET
@Path("/greetings")
@Produces("application/xml")
public List<Greeting> getGreetings()
{
return greetingServer.getGreetings();
}
}
That fetches the current greetings (notice the injection) from the server and presents them in XML format. To hook up the JAX-RS implementation, RESTEasy, add the following to web.xml
<context-param> <param-name>resteasy.scan</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>resteasy.servlet.mapping.prefix</param-name> <param-value>/resteasy</param-value> </context-param> <listener> <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class> </listener> <servlet> <servlet-name>Resteasy</servlet-name> <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> </servlet> <servlet-mapping> <servlet-name>Resteasy</servlet-name> <url-pattern>/resteasy/*</url-pattern> </servlet-mapping>
and the @XMLRootElement annotation to the top of our Greeting class
@Entity @Audited @XmlRootElement public class Greeting
Your greetings should now be available from /Greetings/resteasy/RESTExport/greetings.
JAX-WS
Adding a Web Service is even more simple. Add
package com.acme.greetings;
import java.util.List;
import javax.inject.Inject;
import javax.jws.WebService;
@WebService
public class WebServiceExporter
{
@Inject
GreetingServer greetingServer;
public List<Greeting> getGreetings()
{
return greetingServer.getGreetings();
}
}
That does a similar job as our RESTExporter and then hook it up in web.xml
<servlet> <servlet-name>WSExport</servlet-name> <servlet-class>com.acme.greetings.WebServiceExporter</servlet-class> </servlet> <servlet-mapping> <servlet-name>WSExport</servlet-name> <url-pattern>/WebServiceExport/*</url-pattern> </servlet-mapping>
Hmm. Wonder if you can make it auto-register? Anyway, the WDSL should be viewable from /Greetings/WebServiceExport?wsdl
Conclusion
This was a short one. Partly because setting things up is really straightforward and don't require us to do that many workarounds. Hopefully, once Aslak finishes the Arqullian DBUnit integration (I already heard rumors on JSFUnit integration) I can be back with a more thorough article on testing all parts of the application.
Man, these are the tutorials we need! besides sun jee 6 tutorial, which is too much explanations between the examples, You did the best full stack tutorial i've ever seen.
thank you very much
Also, if you use EJB3 ws endpoints instead of POJO ws endpoints, you can avoid providing a web.xml for the JAXWS example. Just annotate the endpoint with @Stateless and pack it into a jar instead of a war. That's all, no descriptor required.
You can consolidate the resteasy web.xml if you use a filter:
<context-param> <param-name>resteasy.scan</param-name> <param-value>true</param-value> </context-param> <filter> <filter-name>Resteasy</servlet-name> <filter-class>org.jboss.resteasy.plugins.server.servlet.FilterDispatcher</servlet-class> </filter> <filter-mapping> <servlet-name>Resteasy</servlet-name> <url-pattern>/*</url-pattern> </filter-mapping>For next milestone of JBoss AS6 (m4), you do not need any web.xml fragments that are resteasy specific. A filter will be created automatically and JAX-RS classes will be scanned for. Resteasy deployer will determine whether the class is an EJB, CDI bean, or just a pojo and do the appropriate registrations.
Cool. Nice to know, although for build simplicity I think I'll keep this example single-moduled.
Good news, I will perhaps write a unified tutorial covering all six parts and testing once we're closer to the final release.
We may be able to do tighter integration with Tomcat and Jetty standalone once they roll out full Servlet 3.0. Servlet 3.0 is supposed to have an integration API that lets you hook into scanning and such. We'll see how it goes....
If all appservers manage to this it will be even more nice because at a quick glance it's the only appserver-specific configuration in web.xml, the JAX-RS implementations have to be swapped out to the GF one if you want to run the sample there.
Alessio, why the restriction? We should be able to lift this restriction, right?
Hi there,
very nice tutorial. Is the example downloadable?
Thanks and Greetz Florian
There will be a sixth (and final?), summarazing part of this series soon now that AS 6 M4 has evolved so that most workarounds can be removed. I'll attach the source there but currently - sorry.