123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- ---
- title: Exposing Server Side API To JavaScript
- order: 41
- layout: page
- ---
-
- [[exposing-server-side-api-to-javascript]]
- Exposing server-side API to JavaScript
- --------------------------------------
-
- The new JavaScript integration functionality will allow you to easily
- publish methods that can be called with JavaScript on the client side.
- In effect, you can publish a JavaScript API for your application.
- Although you will probably not find yourself using this very often, it
- can be useful when integrating with JavaScript frameworks or embedding
- within legacy sites.
-
- Exposing a `notify()` method that takes a message and displays that as a
- notification can be done in one simple block in e.g `UI.init()`:
-
- [source,java]
- ....
- JavaScript.getCurrent().addFunction("notify", new JavaScriptFunction() {
- public void call(JSONArray arguments) throws JSONException {
- Notification.show(arguments.getString(0));
- }
- });
- ....
-
- This will expose the `notify()`{empty}-method globally in the window object.
- Technically it's thus `window.notify()`, but you can call it by simply
- by `notify()`. Try entering `notify("Hey!")` into the Firebug or
- Developler Tools console, or `javascript:notify("Hey!")` into the
- address bar.
-
- You'll notice that this assumes there is a String in the first position
- of the array. Also, this will clutter the global namespace, which is
- generally not a good idea, unless you really have a specific need for
- that.
-
- Let's make a complete example with two arguments, some simple error
- handling, and namespacing:
-
- [source,java]
- ....
- JavaScript.getCurrent().addFunction("com.example.api.notify",
- new JavaScriptFunction() {
- public void call(JSONArray arguments) throws JSONException {
- try {
- String caption = arguments.getString(0);
- if (arguments.length() == 1) {
- // only caption
- Notification.show(caption);
- } else {
- // type should be in [1]
- Notification.show(caption,
- Type.values()[arguments.getInt(1)]);
- }
- } catch (JSONException e) {
- // We'll log in the console, you might not want to
- JavaScript.getCurrent().execute(
- "console.error('" + e.getMessage() + "')");
- }
- }
- });
- }
- ....
-
- Using the dotted notation for the method will automatically create those
- objects in the browser; you'll call this method like so:
- `com.example.api.notify("Hey!")`. You do not have to use a long name
- like this, though - it's up to you and your use-case.
-
- The second thing to notice is that we now wrapped the code in a
- try-catch, so that the wrong number or wrong types of arguments does not
- cause an ugly stacktrace in our server logs. Again, how you should react
- to erroneous use of your exposed API depends on your use-case. We'll log
- an error message to the browser console as an example.
-
- We're now accepting a second (integer) argument, and using that as
- _type_ for the `Notification`.
-
- Finally, we'll add a link that will call the function, and work as a
- _Bookmarklet_. You can drag the link to your bookmarks bar, and when you
- invoke it when viewing the application with our exposed `notify()`{empty}-method, you will be prompted for a message that will then be sent to
- the method. Here is the plain HTML code for creating such a link:
-
- [source,html]
- ....
- <a href="javascript:(function(){com.example.api.notify(prompt('Message'),2);})();">Send message</a>
- ....
-
- Here is the full source for our application:
-
- [source,java]
- ....
- import org.json.JSONArray;
- import org.json.JSONException;
- import com.vaadin.server.ExternalResource;
- import com.vaadin.server.VaadinRequest;
- import com.vaadin.ui.JavaScript;
- import com.vaadin.ui.JavaScriptFunction;
- import com.vaadin.ui.Link;
- import com.vaadin.ui.Notification;
- import com.vaadin.ui.Notification.Type;
- import com.vaadin.ui.UI;
-
- public class JSAPIUI extends UI {
- @Override
- public void init(VaadinRequest request) {
-
- JavaScript.getCurrent().addFunction("com.example.api.notify",
- new JavaScriptFunction() {
- public void call(JSONArray arguments) throws JSONException {
- try {
- String caption = arguments.getString(0);
- if (arguments.length() == 1) {
- // only caption
- Notification.show(caption);
- } else {
- // type should be in [1]
- Notification.show(caption,
- Type.values()[arguments.getInt(1)]);
- }
- } catch (JSONException e) {
- // We'll log in the console, you might not want to
- JavaScript.getCurrent().execute(
- "console.error('" + e.getMessage() + "')");
- }
- }
- });
-
-
- setContent(new Link(
- "Send message",
- new ExternalResource(
- "javascript:(function(){com.example.api.notify(prompt('Message'),2);})();")));
- }
- }
- ....
|