开发者

BlazeDS not handling Java inner class DTO

I've noticed BlazeDS has certain things it does not support and it is often difficult to find this out. Ex: polymorphism is not. One must create methods with different names as methods with the same name with different parameters create a conflict.

I'm trying to find out if BlazeDS does not support Java static and non-static inner classes. Details of an example pointing out the issue:

public class UserDTO {
     private  String name;
     private AddressDTO adddress;
     private PhoneDTO phone;
     ....

     public static class PhoneDTO {
          private String phoneNumber;
          .....
     }

     public class AddressDTO {
          private String address;
          .....
     }

This code appears to work fine for passing data to Flex via BlazeDS but results in errors when passing the data from Flex via Bla开发者_高级运维zeDS back to Java.

@Service
@RemotingDestination(channels = { "my-amf" }, value = "UserService")
public class UserService {
   ....
   public UserDTO getUser(Long userID) {
      .....
      return userDTO;
   }

   public void updateUser(UserDTO userDTO) {
     ....
   }

   public void updatePhone(PhoneDTO phoneDTO) {
      .....
   }

The example code above will compile and the getUser method will work. A call to the updateUser or updatePhone methods on the other hand results in a BlazeDS error. Is there a special way to use inner classes in Flex or are inner classes not supported?

Here is an example of the error messages produced:

[BlazeDS]Cannot create class of type 'com.test.dto.UserDTO.PhoneDTO'.
flex.messaging.MessageException: Cannot create class of type 'com.test.dto.UserDTO.PhoneDTO'. Type 'com.test.dto.UserDTO.PhoneDTO' not found.

Example Flex code:

var thisPhone:PhoneDTO = new PhoneDTO();
thisPhone.phoneNumber = "8885551212";
updateTagsResult.token = userService.updatePhone(thisPhone);


As for the static classes, I'm also very skeptical that they can be used as well. Static classes are possible in Actionscript, but only in the same file (private static) and I don't believe AMF3 supports it.

The purpose of AMF3 is just to have simple property to property serialization between classes. Anything more complex than that is hard to transfer over and frankly, shouldn't be done in the first place because the complexity will, in all probability, affect your development. This is why Java has DTOs. Abstract data objects that can be transferred to any languages using your choice of data protocol.


Inner Classes

No, sending an Actionscript object aliased to a Java inner class (static or otherwise) is not supported out-of-the-box.

As you've seen, when the AMF packet is deserialized, the class name is interpreted as an outer class, rather than as an inner class.

However, you could implement this yourself by having your classes implement IExternalizable. (See here for further information)

An alternative to IExternalizable is to use an approach similar to this one, which provides support for Java Enum's to be sent across to Flex. They use a custom deserializer endpoint.

In the interests of completeness, I should point out that serializing Actionscript inner classes is supported, however the [RemoteClass] metatag is not. Instead, inner classes must be explicitly registered using registerClassAlias, normally within a static method of the outer class.

Polymorphism

To correct a point in the original post:

.... Ex: polymorphism is not. One must create methods with different names as methods with the same name with different parameters create a conflict.

Given that BlazeDS is a server-side product, I'm assuming that you're referring to the way BlazeDS handles Polymorphism & overloading in Java. In which case, your statement is incorrect.

For example, the following code is valid:

@RemotingDestination
public class EchoService {
public String echo(String source)
{
    return "Received String";
}
public Object echo(Object source)
{
    return "Recieved object of type " + source.getClass().getName();
}

Executed as follows:

remoteObject.echo("Hello") // result from service is "Received String"
remoteObject.echo(new Date()) // result from service is "Received object of type java.util.Date"

However, this is not an example of polymoprhism, as your question states. This is method overloading, which is different.

Polymorphism is supported, as shown here:

// Java
// This method on EchoService
public String echo(Employee employee)
{
    return employee.sayHello();
}

public class Employee {

    public String sayHello() {
        return "Hello, I'm an employee";
    }

}   
public class Manager extends Employee {

    @Override
    public String sayHello() {
        return "Hello, I'm a Manager";
    }
}

Executed as follows:

// In flex...
remoteObject.echo(new Employee()) // Recieves "Hello, I'm an employee"
remoteObject.echo(new Manager()) // Recieves "Hello, I'm a Manager"

If we remove the echo(Employee employee) method, then the result is:

// In flex...
remoteObject.echo(new Employee()) // Recieves "Recieved object of type Employee"
remoteObject.echo(new Manager()) // Recieves "Recieved object of type Manager"
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜