掲示板

Remote JSON service with entity as a parameter.

6年前 に Odysseas Doumas によって更新されました。

Remote JSON service with entity as a parameter.

New Member 投稿: 17 参加年月日: 16/06/22 最新の投稿
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
6年前 に Andrew Jardine によって更新されました。

RE: Remote JSON service with entity as a parameter.

Liferay Legend 投稿: 2416 参加年月日: 10/12/22 最新の投稿
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?
6年前 に Odysseas Doumas によって更新されました。

RE: Remote JSON service with entity as a parameter.

New Member 投稿: 17 参加年月日: 16/06/22 最新の投稿
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
6年前 に Andrew Jardine によって更新されました。

RE: Remote JSON service with entity as a parameter.

Liferay Legend 投稿: 2416 参加年月日: 10/12/22 最新の投稿
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
6年前 に David H Nebinger によって更新されました。

RE: Remote JSON service with entity as a parameter.

Liferay Legend 投稿: 14916 参加年月日: 06/09/02 最新の投稿
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!
6年前 に Odysseas Doumas によって更新されました。

RE: Remote JSON service with entity as a parameter.

New Member 投稿: 17 参加年月日: 16/06/22 最新の投稿
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.