XPages, Beans, Web Services and Javascript, continued...some success

I recently posted a question about Javascript SOAP web services:http://www-10.lotus.com/ldd/nd85forum.nsf/5f27803bba85d8e285256bf10054620d/87f9270dabc9c8bc8525776e0036e2df?OpenDocument

…a problem I have solved. I can now call my web services from JS. I am refining this code, but will post in forum for anyone that is interested.

Quick bit of background: current project I am working on, they would like a complete separation of ui and logic using MVC pattern, the premise being: the application could be surfaced\ accessed via the web services in a java app, or whatever you want (they may decide to move to SQL backend, the whole app might be moved off Domino). It means we will hardly be using any of the JSF functionality, all requests will go via the web service(s).

I’m right at the edge of my knowledge here, but my question is: if I use backing beans for my data bean and model bean, how can my web service “access” my model bean? I invoke a JS ajax POST SOAP request on web client, I can successfully contact my web service and get responses. My web service(s) can “access” any java (or lotusscript) script libraries I have, but I don’t know how to get to the web service to access java classes in the WebContent/WEB-INF/src folder. My primary reason for this is: my web services will get access to the scoped variables…due to above problem, I can’t test this, but I am hoping I am correct.

There are a whole list of things I can think of that are going to make this more complicated, since I won’t be able to bind to any forms\ beans etc. If I am correct, the submit will actually serialise the form and submit to web service, I can’t POST the form to the server…to keep an absolute separation of logic and HTML.

One way I am thinking of is a mixture of the 2: design the system using beans and surface that through to the xpage(s). As we go along, build up the Web Service API, so as we get to some piece of functionality, we could do a MyBeanObject.GetSomeProperties() or MyJSClientObject.GetSomeProperties() which gets values through Web Service.

…But, if I can get my web service to the bean, it’s a write once operation, else I also have to move code to traditional Java library.

My head is swirling a bit at the moment and I’ve been waffling…so any comments, suggestions would be greatly welcomed.

Nick

Subject: Yes, we are interested, post the code

“but will post in forum for anyone that is interested”

Subject: Ok…here’s what I’ve got…

…I have a database where I’m testing all this stuff, it’s really rough round the edges, purely proof of concept stuff. This is a mix mash of ideas by a whole laod of people way smarter than me: Tim Tripcony, Chris Toohey, Matt White, Stephan Wissel, etc.

I have a bigger update at end of this post, but for first part: calling a web service via javascript.

Set up your web service, either in LotusScript or Java, I’m doing mine in java (My goal is to get to backing beans, more on that in a minute). Do a really simnple web service: getUserName() beantest(). Test your web service…I use SOAPUi and make web service avaiable for public access, once tested, I take public access off. Next I get my javascript (not SSJS) bit sorted:

soapMessage = ‘’;

soapMessage+='<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">';

soapMessage+='<soapenv:Header/>';

soapMessage+='<soapenv:Body/>';

soapMessage+='</soapenv:Envelope>';

// If your web service has input, then the message looks something like this, where I’m passing in “xxxx” as a parameter.

/*

soapMessage+='<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:DefaultNamespace">';

soapMessage+='<soapenv:Header/>';

soapMessage+='<soapenv:Body>';

soapMessage+='<urn:TXT>xxxx</urn:TXT>';

soapMessage+='</soapenv:Body>';

soapMessage+='</soapenv:Envelope>';

*/

if(window.XMLHttpRequest) {

        httpRequest=new XMLHttpRequest();

} else if (window.ActiveXObject) { 

        httpRequest=new ActiveXObject("Microsoft.XMLHTTP"); 

}

              

var url = "http://urltoyourdatabase.nsf/EchoTestJava2?OpenWebService";

httpRequest.open("POST",url,true);

if (httpRequest.overrideMimeType) { 

        httpRequest.overrideMimeType("text/xml"); 

}

httpRequest.onreadystatechange=populateDiv;

  

httpRequest.setRequestHeader("Man", url + " HTTP/1.1")

httpRequest.setRequestHeader("MessageType", "CALL");

httpRequest.setRequestHeader("Content-Type", "text/xml");

// This is the line you change to match whatever “actions” your webservice has.

httpRequest.setRequestHeader("SOAPAction", "beantest");



httpRequest.send(soapMessage);

valTimeout=setTimeout("timeout(httpRequest);",120000);   

function populateDiv(){

try {

   if(httpRequest.readyState==4) {

        if(httpRequest.status==200) {

        clearTimeout(valTimeout);

        

      var text = httpRequest.responseText;

      console.debug("Creata XML dom");

      var dom = dojox.xml.parser.parse(text); 

      var docNode = dom.documentElement; 

      var html = "";



      var returnElement = docNode;



      for (var i = 0; i < returnElement.childNodes.length; i++) { 

       html +="~~~" + 

    	dojox.xml.parser.textContent(returnElement.childNodes[i]);

      }



     

      var resultDiv=document.getElementById("resultDiv");

      resultDiv.value = html;

     	}

    } 

 } catch(e) { 

   alert("Error!"+e.description); 

 }      

}

If you use the passing in parameter “xxxx” envelope above, and you are using FireBug, you will see a response something along the lines of below, for test I just return the text I sent in, the server name, filepath and the time. I am writing results to a “resultDiv”

<?xml version="1.0" encoding="UTF-8"?>

<soapenv:Envelope xmlns:soapenv=“http://schemas.xmlsoap.org/soap/envelope/” xmlns:xsd=“http://www.w3.org/2001/XMLSchema” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xmlns:soapenc=“http://schemas.xmlsoap.org/soap/encoding/”>

soapenv:Body<ns0:ECHOReturn xmlns:ns0=“urn:DefaultNamespace”>xxxx UserName: CN=gsxr/O=bikes, Server: CN=gsxr/O=bikes, FilePath: Projects\dev\test.nsf, Time: 04/08/2010 20:55:47</ns0:ECHOReturn></soapenv:Body>

</soapenv:Envelope>

OK, so that all works. Any legacy LotusScript or Java I have in Script Libraries, I can expose all that via webservice and get to it from client side javascript…nice.

…but what I really want is to be able to get to backing beans from web service. For more on backing beans see: Mindoo - XPages series #4: Backing Bean Management with XPages there is a series of articles (this guy has skills waaaayyyy beyond me). The backing bean stuff is great. Otherwise I write java code in backing bean, but then have to copy\ paste to a script library so the web service can access it. Now if anyone knows how to get from web service to backing bean, speak up now :slight_smile: But in the project I am involved with, they want complete separation, all done by web services, so how do I get to backing beans…well I went back to this article: http://www.wissel.net/blog/d6plinks/SHWL-7MGFBN, (another great blogger), I had a thought: from client side JS, call an action on my web service GetSomeDataFromBackingBean(), the java code in that opens a url connection to my xpagebeaninterface.xsp, which (since an xpage can get to the backing beans) does whatever action in my backing bean, then writes back, I read the xml\ JSON response from that, and pass back from web service. Result!!! It’s late, I’ve one glass of wine too many, but my url connection is getting login page, I think I need to POST a login before calling my benainterface.xsp, but I think this could do it. I am sooo close…I’m going on holiday for the next 10 days, but will dabble with this and post any results…I really want to know thew answer!!!