Adobe ColdFusion 8

Using Java objects

You use the cfobject tag to create an instance of a Java object. You use other ColdFusion tags, such as cfset and cfoutput, or CFScript to invoke properties (attributes), and methods (operations) on the object.

Method arguments and return values can be any valid Java type; for example, simple arrays and objects. ColdFusion does the appropriate conversions when strings are passed as arguments, but not when they are received as return values. For more information on type conversion issues, see Java and ColdFusion data type conversions.

The examples in the following sections assume that the name attribute in the cfobject tag specified the value obj, and that the object has a property called Property, and methods called Method1, Method2, and Method3.

Note: The cfdump tag displays an object's public methods and data.

Using basic object techniques

The following sections describe how to invoke Java objects.

Invoking objects

The cfobject tag makes Java objects available in ColdFusion. It can access any Java class that is available on the JVM classpath or in either of the following locations:

  • In a Java archive (.jar) file in web_root/WEB-INF/lib
  • In a class (.class) file in web_root/WEB-INF/classes

For example:

<cfobject type="Java" class="MyClass" name="myObj">

Although the cfobject tag loads the class, it does not create an instance object. Only static methods and fields are accessible immediately after the call to cfobject.

If you call a public non-static method on the object without first calling the init method, there ColdFusion makes an implicit call to the default constructor.

To call an object constructor explicitly, use the special ColdFusion init method with the appropriate arguments after you use the cfobject tag; for example:

<cfobject type="Java" class="MyClass" name="myObj">
<cfset ret=myObj.init(arg1, arg2)>

Note: The init method is not a method of the object, but a ColdFusion identifier that calls the new function on the class constructor. So, if a Java object has an init method, a name conflict exists and you cannot call the object's init method.

To have persistent access to an object, you must use the init function, because it returns a reference to an instance of the object, and cfobject does not.

An object created using cfobject or returned by other objects is implicitly released at the end of the ColdFusion page execution.

Using properties

Use the following coding syntax to access properties if the object does either of the following actions:

  • Exposes the properties as public properties.
  • Does not make the properties public, but is a JavaBean that provides public getter and setter methods of the form getPropertyName() and setPropertyName(value). For more information, see the following section, Calling JavaBean get and set methods.
  • To set a property: <cfset obj.property = "somevalue">
  • To get a property: <cfset value = obj.property>

Note: ColdFusion does not require that property and method names be consistently capitalized. However, you should use the same case in ColdFusion as you do in Java to ensure consistency.

Calling methods

Object methods usually take zero or more arguments. Some methods return values, while others might not. Use the following techniques to call methods:

  1. If the method has no arguments, follow the method name with empty parentheses, as in the following cfset tag:
    <cfset retVal = obj.Method1()>

  2. If the method has one or more arguments, put the arguments in parentheses, separated by commas, as in the following example, which has one integer argument and one string argument:
    <cfset x = 23>
    <cfset retVal = obj.Method1(x, "a string literal")>
    

Note: When you invoke a Java method, the type of the data being used is important. For more information see Java and ColdFusion data type conversions.

Calling JavaBean get and set methods

ColdFusion can automatically invoke getPropertyName() and setPropertyName(value) methods if a Java class conforms to the JavaBeans pattern. As a result, you can set or get the property by referencing it directly, without having to explicitly invoke a method.

For example, if the myFishTank class is a JavaBean, the following code returns the results of calling the getTotalFish() method on the myFish object:

<cfoutput>
    There are currently #myFish.TotalFish# fish in the tank.
</cfoutput>

The following example adds one guppy to a myFish object by implicitly calling the setGuppyCount(int number) method:

<cfset myFish.GuppyCount = myFish.GuppyCount + 1>

Note: You can use the direct reference method to get or set values in some classes that have getProperty and setProperty methods but do not conform fully to the JavaBean pattern. However, you cannot use this technique for all classes that have getProperty and setProperty methods. For example, you cannot directly reference any of the following standard Java classes, or classes derived from them: Date, Boolean, Short, Integer, Long, Float, Double, Char, Byte, String, List, Array.

Calling nested objects

ColdFusion supports nested (scoped) object calls. For example, if an object method returns another object and you must invoke a property or method on that object, you can use the following syntax:

<cfset prop = myObj.X.Property>.

Similarly, you can use code such as the following CFScript line:

GetPageContext().include("hello.jsp?name=Bobby");

In this code, the ColdFusion GetPageContext function returns a Java PageContext object, and the line invokes the PageContext object's include method.

Creating and using a simple Java class

Java is a strongly typed language, unlike ColdFusion, which does not enforce data types. As a result, there are some subtle considerations when calling Java methods. The following sections create and use a Java class to show how to use Java effectively in ColdFusion pages.

The Employee class

The Employee class has four data members: FirstName and LastName are public, and Salary and JobGrade are private. The Employee class has three overloaded constructors and a overloaded SetJobGrade method.

Save the following Java source code in the file Employee.java, compile it, and place the resulting Employee.class file in a directory that is specified in the classpath:

public class Employee {

public String FirstName;
public String LastName;
private float Salary;
private int JobGrade;

public Employee() {
    FirstName ="";
    LastName ="";
    Salary = 0.0f;
    JobGrade = 0;
}

public Employee(String First, String Last) {
    FirstName = First;
    LastName = Last;
    Salary = 0.0f;
    JobGrade = 0;
}

public Employee(String First, String Last, float salary, int grade) {
    FirstName = First;
    LastName = Last;
    Salary = salary;
    JobGrade = grade;
}

public void SetSalary(float Dollars) {
    Salary = Dollars;
}

public float GetSalary() {
    return Salary;
}

public void SetJobGrade(int grade) {
    JobGrade = grade;
}

public void SetJobGrade(String Grade) {
    if (Grade.equals("CEO")) {
        JobGrade = 3;
    }
    else if (Grade.equals("MANAGER")) {
        JobGrade = 2;
    }
    else if (Grade.equals("DEVELOPER")) {
        JobGrade = 1;
    }
}

public int GetJobGrade() {
    return JobGrade;
}

}

A CFML page that uses the Employee class

Save the following text as JEmployee.cfm:

<html>
<body>
<cfobject action="create" type="java" class="Employee" name="emp">
<!--- <cfset emp.init()> --->
<cfset emp.firstname="john">
<cfset emp.lastname="doe">
<cfset firstname=emp.firstname>
<cfset lastname=emp.lastname>
</body>

<cfoutput>
    Employee name is #firstname# #lastname#
</cfoutput>
</html>

When you view the page in your browser, you get the following output:

Employee name is john doe

Reviewing the code

The following table describes the CFML code and its function:

Code

Description

<cfobject action=create type=java class=Employee name=emp>

Loads the Employee Java class and gives it an object name of emp.

<!--- <cfset emp.init()> --->

Does not call a constructor. ColdFusion invokes the default constructor when it first uses the class; in this case, when it processes the next line.

<cfset emp.firstname="john"> <cfset emp.lastname="doe">

Sets the public fields in the emp object to your values.

<cfset firstname=emp.firstname> <cfset lastname=emp.lastname>

Gets the field values back from emp object.

<cfoutput> Employee name is #firstname# #lastname# </cfoutput>

Displays the retrieved values.

Java considerations

Keep the following points in mind when you write a ColdFusion page that uses a Java class object:

  • The Java class name is case-sensitive. You must ensure that the Java code and the CFML code use Employee as the class name.
  • Although Java method and field names are case-sensitive, ColdFusion variables are not case-sensitive, and ColdFusion does any necessary case conversions. As a result, the sample code works even though the CFML uses emp.firstname and emp.lastname; the Java source code uses FirstName and LastName for these fields.
  • If you do not call the constructor (or, as in this example, comment it out), ColdFusion automatically invokes the default constructor when it first uses the class.

Using an alternate constructor

The following ColdFusion page explicitly calls one of the alternate constructors for the Employee object:

<html>
<body>

<cfobject action="create" type="java" class="Employee" name="emp">
<cfset emp.init("John", "Doe", 100000.00, 10)>
<cfset firstname=emp.firstname>
<cfset lastname=emp.lastname>
<cfset salary=emp.GetSalary()>
<cfset grade=emp.GetJobGrade()>

<cfoutput>
    Employee name is #firstname# #lastname#<br> 
    Employee salary #DollarFormat(Salary)#<br>
    Employee Job Grade #grade#
</cfoutput>

</body>
</html>

In this example, the constructor takes four arguments: the first two are strings, the third is a float, and the fourth is an integer.