Java bridge
Contents
JavaScript developers may optionally invoke and use Java-based code, since the XP runtime builds on the JVM.
The __
object
In Enonic XP, there is a global object named __
(double underscore), accessible from any serverside JavaScript code, which provides a way to wrap Java objects in a JavaScript object. The __
object has functions that allow JavaScript to communicate with Java classes. The newBean
function will wrap the Java object named in the parameter, for instance:
var bean = __.newBean('com.enonic.xp.lib.io.IOHandlerBean');
This line is from the lib-io
library, which is a good example of how this is used. In the Java IOHandlerBean
class, there are several methods, like the readLines
method:
public List<String> readLines( final Object value )
throws Exception
{
final CharSource source = toCharSource( value );
return source.readLines();
}
This method is now accessible as a function on the JavaScript bean
and may be invoked from JavaScript, like this:
exports.readLines = function (stream) {
return __.toNativeObject(bean.readLines(stream));
};
This results in a global JavaScript function readLines
. This example also shows the use of the toNativeObject
method, which in this case, converts a Java String array to a JSON object.
Java objects constructed by newBean
may, but not required to, implement com.enonic.xp.script.bean.ScriptBean
interface. ScriptBean::initialize
is used to inject com.enonic.xp.script.bean.BeanContext
object, which can be used to access the application and resource keys, as well as current Request, Context and XP Java API Services.
Passing parameters to Java
There are 2 ways to pass parameters to a Java method, from JavaScript:
-
Passing the parameters in the method call
-
Setting the parameters as properties in the Java object, and then calling the method without parameters
The first one is recommended when there are few parameters (1 or 2) and of simple types. The second one is better when there are multiple parameters, or some of them are optional.
exports.doSomething = function (param1, param2) {
var bean = __.newBean('com.enonic.lib.mylib.MyClass');
return bean.execute(param1, param2);
};
exports.doSomethingElse = function (params) {
var bean = __.newBean('com.enonic.lib.mylib.MyClass');
bean.text = __.nullOrValue(params.text) || '';
bean.size = __.nullOrValue(params.size) || 250;
return bean.execute();
};
When passing values that might be null or undefined it is recommended to filter them using the __.nullOrValue built-in function. This function converts any value that is null or undefined in JavaScript to null in Java. Otherwise returns the input value without changes. |
To be able to set property values as in the 2nd example above, the Java object must implement a setter method for each field.
The Java class used in the example above looks like this:
package com.enonic.lib.mylib;
public final class MyClass {
private String text;
private Long size;
public String something( String param1, Long param2 ) {
return "Parameters: " + param1 + " " + param2;
}
public String somethingElse() {
return "Parameters: " + this.text + " " + this.size;
}
public void setText( String text ) {
this.text = text;
}
public void setSize( Long size ) {
this.size = size;
}
}
Parameter conversions
There are some type conversions that are made when calling from JavaScript to Java:
-
when passing a JavaScript
string
, the Java method should expect a JavaString
-
when passing a JavaScript
boolean
, the Java method should expect a JavaBoolean
-
when passing a JavaScript
number
, the Java method should expect a JavaLong
,Integer
orDouble
-
when passing a JavaScript
array
, the Java method should expect a JavaList
-
when passing a JavaScript
object
, the Java method should expect a JavaMap<String, Object>
Returning results from Java
When returning simple values from Java to a JavaScript caller, the same type conversions applies.
To return complex object values, you should create a specific Java class to make the mapping. This class should implement the MapSerializable
interface. It will implement the serialize
method, which allows generating a JSON object.
package com.enonic.lib.mylib;
import java.util.Map;
import com.enonic.xp.script.serializer.MapGenerator;
import com.enonic.xp.script.serializer.MapSerializable;
public final class ExampleObjectMapper
implements MapSerializable
{
private final String text;
private final Object[] array;
private final Map<String, Object> object;
public ExampleObjectMapper( String text, Object[] array, Map<String, Object> object )
{
this.text = text;
this.array = array;
this.object = object;
}
@Override
public void serialize( MapGenerator gen )
{
gen.value( "text", text );
gen.array( "arrayValues" );
for ( Object value : array )
{
gen.value( value );
}
gen.end();
gen.map( "objectValues" );
for ( String key : object.keySet() )
{
gen.value( key, object.get( key ) );
}
gen.end();
}
}
Finally, for returning values of type binary stream from Java, it should be wrapped on a ByteSource object. This is required by XP to allow returning it from an HTTP request, or add it as a content attachment.
Functions
disposer
Add a disposer that is called when the app is stopped.
Parameters
Name | Kind | Details |
---|---|---|
func |
Function to call |
Returns
void
newBean
Creates a new JavaScript bean that wraps the given Java class and makes it’s methods available to be called from JavaScript.
Parameters
Name | Kind | Details |
---|---|---|
name |
Classname for bean to create |
Returns
void
nullOrValue
Converts a JavaScript variable that is undefined to a Java null object. If the JavaScript variable is defined, it is returned as is.
Parameters
Name | Kind | Details |
---|---|---|
value |
Value to convert |
Returns
void
registerMock
Registers a mock
Parameters
Name | Kind | Details |
---|---|---|
name |
Name of mock |
|
value |
Value to register |
Returns
void
toNativeObject
Converts arrays or complex Java objects to JSON.
Parameters
Name | Kind | Details |
---|---|---|
value |
Value to convert |
Returns
void
toScriptValue
Converts JSON to a Java Map structure that can be used as parameters to a Java method on a bean created with newBean.
Parameters
Name | Kind | Details |
---|---|---|
value |
Value to convert |
Returns
void