Forums de discussion

Remote JSON service with entity as a parameter.

Odysseas Doumas, modifié il y a 6 années.

Remote JSON service with entity as a parameter.

New Member Publications: 17 Date d'inscription: 22/06/16 Publications récentes
It has come to my understanding that a Service Builder service can accept as arguments only primitives, their wrapper classes, Entities and Lists or Maps of the above. My problem is that i have defined a remote service that takes an entity as an argument, but when i try to invoke this service from http://localhost:8080/api/jsonws, i always get an error saying "No zero argument constructor found for EntityClass". I suppose this is because the argument is actually the interface that defines the entity model. Is there any possible way to make a remote service that takes an entity as an argument to be invoked using JSON web services (I am mostly interested invoking them via javascript)?

I should point out that i am developing some JSF portlets, and based on the tutorial, most of my services are using Entities as arguments, so re-writing them using primitives only would not be optimal. I am using Liferay 6.2.
thumbnail
Andrew Jardine, modifié il y a 6 années.

RE: Remote JSON service with entity as a parameter.

Liferay Legend Publications: 2416 Date d'inscription: 22/12/10 Publications récentes
Hi Odysseas,

Have you tried to pass JSON objects that are serialized as Strings? Then in your service impl in liferay you can deserialize them back into your expected entity and leave all your existing logic the same.

Maybe that would work?
Odysseas Doumas, modifié il y a 6 années.

RE: Remote JSON service with entity as a parameter.

New Member Publications: 17 Date d'inscription: 22/06/16 Publications récentes
Hello and thanks for the reply.

Yes, of course it would work, but i was wondering if it could be "automated" so i don't have to do the deserialization manually. Anyway similarly to the url invocation, i managed to make it work with the following syntax:

For a service builder project with:
org.test.model.Entity : the Entity Interface
org.test.model.impl.EntityImpl : the Entity implementation

public Entity myMethod(Entity entityParameter) inside the EntityServiceImpl

Liferay.Service(
  '/mynamespace.entity/my-method',
  {
    "+entityParameter": "org.test.model.impl.EntityImpl ",  
    entityParameter: {"entityField1": 12.3 , "entityField1": 32.23}
  },
  function(obj) {
    console.log(obj);
  }
);


Which is acceptable i guess. Please feel free to provide any better alternatives if they exist, or point me out if there is something wrong with this approach.

Note: I tested this on Liferay 7.0.3
Edit: changed above code to be more clear.
thumbnail
Andrew Jardine, modifié il y a 6 années.

RE: Remote JSON service with entity as a parameter.

Liferay Legend Publications: 2416 Date d'inscription: 22/12/10 Publications récentes
On the server side it's just one line of code to deserialize an object -- right out of the Liferay API using the JSONFactoryUtil. So what I was trying to say was that if you got a serialized version of your "CustomEntity.java" class to the *ServiceImpl method, then it should only be one line to convert it to a java class. Maybe a few lines if you do some error handling, but you get the point.

So perhaps I misunderstood your question. When you say automating, do you mean on the client side? having an object that is modeled the same as your server side java class (automatically)? If that is what you are referring to, then I don't know of any such beast.
thumbnail
David H Nebinger, modifié il y a 6 années.

RE: Remote JSON service with entity as a parameter.

Liferay Legend Publications: 14919 Date d'inscription: 02/09/06 Publications récentes
Odysseas Doumas:
Hello and thanks for the reply.

Yes, of course it would work, but i was wondering if it could be "automated" so i don't have to do the deserialization manually. Anyway similarly to the url invocation, i managed to make it work with the following syntax:

Liferay.Service(
  '/mynamespace.myentity/my-method',
  {
    "+obParameter": "my.package.with.implemetation.obParameterImpl",  
    obParameter: {"innerParameter1": 12.3 , "innerParameter2": 32.23}
  },
  function(obj) {
    console.log(obj);
  }
);


It is not clear from your obfuscation, but is "my.package.with.implementation.obParameter" an entity that also has a remote API?

The JSON deserialization should work, but of course that depends upon the entity having the appropriate @JSON annotations which are only injected for remote entities, not local entities.







Come meet me at Devcon 2017 or 2017 LSNA!
Odysseas Doumas, modifié il y a 6 années.

RE: Remote JSON service with entity as a parameter.

New Member Publications: 17 Date d'inscription: 22/06/16 Publications récentes
David H Nebinger:

It is not clear from your obfuscation, but is "my.package.with.implementation.obParameter" an entity that also has a remote API?

The JSON deserialization should work, but of course that depends upon the entity having the appropriate @JSON annotations which are only injected for remote entities, not local entities.


Yes, sorry the example was hastily written, i changed it. It is an entity that has a remote api.

Andrew Jardine:
On the server side it's just one line of code to deserialize an object -- right out of the Liferay API using the JSONFactoryUtil. So what I was trying to say was that if you got a serialized version of your "CustomEntity.java" class to the *ServiceImpl method, then it should only be one line to convert it to a java class...


I wasn't aware that it was so easy to deserialize with this API, i ll definately check it out how it works. What i mean by automatically is a behavior similar to some Liferay methods that take as an argument a ServiceContext (a concrete class of course), and the deserialization doesn't happen inside the method but prior to invoking the remote method. The method doesn't take as argument a String or JSON object, it takes the class itself.
Again, the above code does exactly that, although i am not really a fan of having the client know about the entity implementation class, it suits my needs.