Showing posts with label webservices. Show all posts
Showing posts with label webservices. Show all posts

Easiest way to publish Java Web Services --how to

In a previous post I wrote about publishing a Web Service through an embeddable ejb3 implementation, which is good since @Stateless beans can have injected managed entityManagers, in some cases that is the way to go if you don't want to deploy your app in a full J2EE server or you need a more flexible environment.

Just days ago I found that the J2SE itself has an lightweight http server embedded into, and the API itself has an Endpoint class that allows you to publish a Web Service in a J2SE environment.

There is more than one way for doing this, but this is the more automatic I could found, the next is a working example. The JRE version I am using is 6 update 7, I am not sure since when it supports it

-----

import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.xml.ws.Endpoint;


@WebService
@SOAPBinding(style=Style.RPC) // without this it does not work automatically.

public class ASimpleTest {
public static class WebServiceTest {
public String callMe(String name) {
return "Hello "+name+" !";  
}
}
public static void main(String[] args) {
Endpoint.publish("http://localhost:8080/sayHello", 
new WebServiceTest());
// http://localhost:8080/sayHello?wsdl will be the 
// place for the wsdl generated on the fly

// remember to use the DNS address of your IP or 
// your IP itself if you want to expose so as to 
// be accessible not only from localhost or
// 127.0.0.1
}
}

----- 


Now you wonder how does this work ? Well, as you publish(...) it starts its embedded http server and binds the webservice automatically generated from the WebServiceTest class to the ip:port you've specified. The threading configuration should be quite ok for most cases.

Have fun trying it !

Easy WebServices in Java (not the common way)

Where we are working now we needed to have a fast way to create WebServices and I didn't want to deal/manage J2EE containers (packaging/deployment ...) so I tried what OpenEJB  has to offer.

OpenEJB is an embedable and ligthweight implementation of EJB3, can be used as a standalone server also. In popular words, OpenEJB  is a way in which you can have everything that is available in the EJB3 container, but 'outside' the container (well, not really).
Consider the next step by step tutorial for creating a webservice.
  • Create a sampleproject
  • Download  openejb-3.0.zip from http://openejb.apache.org/download.html and unpack it
  • Add to the classpath of your sampleproject every .jar file that's in unpacked/lib
  • Create a META-INF folder inside your src directory and create a file inside that folder called ejb-jar.xml and just put in it this stringr "<ejb-jar/>" (without quotes)
  • Create now the interface that defines the contract of your webservice and anotate it with
     @WebService(targetNamespace="http://yourcompany.com/wsdl")
     public interface TestWs { ... }
  • Create the class that implements your interface and anotate it like this:
     @Stateless
     @WebService(portName = "TestPort",
         serviceName = "TestWsService",
         targetNamespace = "http://yourcompany.com/wsdl",
         endpointInterface = "full.qualified.name.of.your.interface.TestWs")
     public class TestImpl { ... }
  • To start the Webservice you need to do this:
   pubilc static void main(String[] args) {
      Properties properties = new Properties();        
      properties.setProperty(Context.INITIAL_CONTEXT_FACTORY,
      "org.apache.openejb.client.LocalInitialContextFactory");
      properties.setProperty("openejb.embedded.remotable", "true");
      new InitialContext(properties); // here the magic starts ....
   }

Taran !, after this steps what you have is a stateless bean exposed as a webservice in this location: http://localhost:4204/TestImpl?wsdl
You can use apache axis2 if you want to generate a Java client for it or just use a dynamic proxy like this:


   // this code can be placed rigth after InitialContext call, or 
   // can be in another program or in another thread in the same program
   // Of course, the program that made the call to InitContext need to be
   // alive for the EJB3 services to be exposed
   URL serviceUrl = new URL("http://localhost:4204/TestImpl?wsdl");
   Service testService = Service.create(serviceUrl, null);

   TestWs testWs = testService.getPort(TestWs.class);
   // test the methods you've implemented ...


You would be wondering how does it works ?

Well, as you request the initial context, openejb automatically searchs for clases in your classpath containing ejb3-related anotations, it automaticaly exposes them as it founds, more or less as it happens when you deploy an application as a .ear in any aplication server, but simpler and with great flexibility due to its embedable architecture.

UPDATE 10 / 29  / 2008
By default openejb serves only to localhost request, if you want to use the exposed webservice from other computers add the next properties to InitialContext(prop)
prop.setProperty("httpejbd.bind", "0.0.0.0");
prop.setProperty("ejbd.bind", "0.0.0.0");
and if you want to change the default port in use, change the next properties:
httpejbd.port, ejbd.bind
Suppose your machine has more than one IP and you want that openejb answers only to requests comming from only one of the IPs in the server, then put the desired IP instead of 0.0.0.0