Wednesday, March 19, 2008

This Week In Wonder

Misc Stuff
AjaxTabbedPanel tracks selected tabs and allows you track the selection. Check out AjaxTabbedPanelDemo for an example.

ERXStyleSheet generates a <link> tag. For non-XHTML, browsers expect the link tag to not have a closing tag. You can now set "er.extensions.ERXStyleSheet.xhtml=false" to make your link tags not generate a closing tag.

ERXWOContext now has a bunch of static directActionUrl(..) generation methods that allow you to override various combinations of host name, port, path, directaction name, http/https, and query string params.

The big one for this week is the enhanced JSON features (with a lot more surprises coming). We've had page-based JSON proxy support almost since the beginning, but it has been enhanced quite a bit along with the addition of a JSON Request Handler for JSON web services. We've upgraded our implementation from the old JSON library to the new library (which metaparadigm turned into). We also spent some time to add some new JSON EO features. One of the problems we had previously was the complexity of the demo app for JSON. There are now much easier examples that show just how simple it is to pass data around. You can hand an NSArray of EO's to your browser client and the browser can make changes and hand them back -- more to come on this front.

Stateful Page Clients
Do you need access to stateful objects from your component in the browser? Just bind:

AjaxProxy : AjaxProxy {
name = "json";
proxyName = "example";
proxy = proxy;

make a "proxy" method that returns an object that you want to be able to message (if you leave the proxy binding off, it will bind to your component directly):

public SomeProxyObject proxy() {
return _proxy;

public class SomeProxyObject {
public NSArray people() { ... } // these can be EO's!
public void doSomethingWithAPerson(Person person) { ... }

and then in javascript:

var people = json.example.people();
people.nsarray.each(function(person, index) { alert(person.firstName); }

It's pretty cool how easy it is.

JSON Web Services
Or you can use JSON for web services instead of SOAP/WOWebServices:

In your Application:

JSONRequestHandler requestHandler = JSONRequestHandler.register();
requestHandler.registerService("exampleService", new ExampleService());

Your service class is similar to a registered WOWebService class:

public class ExampleService {
public void printThisString(String string) { .. }

JSON services also support "local args", which allow the server to fill in parameters to your method for you based on the request. For instance, if your method is stateful and you need a session, you can just add a WOSession parameter to your method:

public class ExampleService {
public void printThisStringStateful(WOSession session, String string) { .. }

And you will be given a session, and the session will be maintained with cookies. The external signature of the method does not change. This works for WOSession, WORequest, WOResponse, and WOContext.

JSON Browser Client
If you want to call your JSON service from a component:

<webobject name = "AjaxJSONClient"/>.exampleService.printThisString('hi');

AjaxJSONClient : AjaxJSONClient {

JSON Java Client
If you need JSON in a Java client app:

Client client = JavaJSONClient.create("http://yourhost/cgi-bin/WebObjects/YourApp.woa/-yourPort/json", true);
IExampleService exampleService = (IExample) client.openProxy("exampleService", IExampleService.class);

public interface IExampleService {
public void printThisString(String str);

(the "true" means you want to use HttpClient as the backing impl, which requires you have that installed in your classpath). Currently there is no stubs generator, so you have to write the stub classes yourself. For most classes it's pretty straightforward (just write the accessor methods). For EO's, it's the same, but you should extend JSONEnterpriseObject on the client. JSONEnterpriseObject just exposes a set/getGlobalID method for tracking purposes. Note that EO's in a Java JSON client app do not track changes -- they only support pass-by-reference right now. That may change at some point.

Check out JSONExample in the AjaxExample app for a bunch of examples that show various ways to use the feature.

No comments:

Post a Comment