I have just decided to use jabsorb in my web application and it seems
to be a powerful tool. However, I have problems in being able to pass
an object as a parameter to Java method, in my client sided Javascript
codes.
Here is the simplest codes I am using to achieve the goal.
package test.entities;
import java.io.Serializable;
public class Bar implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String baz;
public String getBaz() {
return baz;
}
public void setBaz(String baz) {
this.baz = baz;
}
<servlet>
<servlet-name>JSONRPCServlet</servlet-name>
<servlet-class>org.jabsorb.JSONRPCServlet</servlet-class>
<!--
the gzip_threshold indicates the response size at which the
servlet will attempt to gzip the response
if it can.
Set this to -1 if you want to disable gzip compression for some
reason,
or if you have another filter or other mechanism to handle
gzipping for you.
Set this to 0 to attempt to gzip all responses from this
servlet.
otherwise, set it to the minimum response size at which gzip
compression is attempted.
note: if the browser making the request does not accept gzip
compressed content,
or the result of gzipping would cause the response size to be
larger (this could happen
with very small responses) then the content will be returned
without gzipping regardless
of this setting, so it is very reasonable idea to set this to 0
for maximum bandwidth
savings, at the (very minor) expense of having the server
attempt to gzip all responses.
-->
<init-param>
<param-name>gzip_threshold</param-name>
<param-value>200</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>JSONRPCServlet</servlet-name>
<url-pattern>/JSON-RPC</url-pattern>
</servlet-mapping>
</web-app>
test.jsp file :
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@page import="test.entities.Foo"%>
<%@page import="test.entities.Bar"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://
www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=ISO-8859-1">
<title>Insert title here</title>
<script language="JavaScript" src="jsonrpc.js"> </script>
</head>
<jsp:useBean id="JSONRPCBridge" scope="session"
class="org.jabsorb.JSONRPCBridge" />
<%
test.entities.Foo f = new test.entities.Foo();
> // The row and username variables are visible > // here later when this callback function is called
> };
> var jsonrpc = new JSONRpcClient("/jsontest/JSON-RPC") > var bar=jsonrpc.barObj;
> jsonrpc.fooObj.setBar(cb,bar);
> </script>
You are trying to use the client-side proxy object as an argument to a call. This I am not sure is currently supported.
There is potential that this sort of thing to be implemented - I think there was some discussion some time back about using the callable proxies interchangeably as opaque references although I'm not sure if support for it is complete. William?
What is probably happening is the BeanSerializer is treating the serialized client proxy as any other object for which the server then tries to map the fields to the Bar class (but it will only have the fields of the client-side proxy object that was sent which has no 'baz' field - thus it not being set).
> You are trying to use the client-side proxy object as an argument to a > call. This I am not sure is currently supported.
I haven't tried this, but if it was declared as a callable reference, I'm not sure why it wouldn't work. With 1.3RC1 we have got constructors working, so you have two options, one of which I am sure will work!
First option, just register Bar as a callable reference: JSONRPCBridge.registerCallableReference(test.entities.Bar.class)
This could fix the whole thing up, but I haven't used a callable reference as an object on the bridge before, so I'm not sure it will work.
Another way is to construct it and use it purely in the javascript. To do this you need to declare it as a constructor by registering it both as a CallableReference and registering its class in jsp: JSONRPCBridge.registerCallableReference(test.entities.Bar.class) JSONRPCBridge.registerClass("Bar",test.entities.Bar.class);
Then you can create "Bar" in javascript: var bar = jsonrpc.createObject("Bar",[]); bar.setBaz("hede"); jsonrpc.fooObj.setBar(cb,bar);
> There is potential that this sort of thing to be implemented - I think > there was some discussion some time back about using the callable > proxies interchangeably as opaque references although I'm not sure if > support for it is complete. William?
> What is probably happening is the BeanSerializer is treating the > serialized client proxy as any other object for which the server then > tries to map the fields to the Bar class (but it will only have the > fields of the client-side proxy object that was sent which has no 'baz' > field - thus it not being set).
First option seem doesn't seem to work, as it gives exception message:
*uncaught exception: JSONRpcClientException: arg 1 could not unmarshall*
Second one also gives an exception message which is probably due to a version issue (I am using jabsorb 1.2.2) *jsonrpc.createObject is not a function*
However, even if I could use the second option, it wouldn't precisely solve my problem. My intention is to get an object from Java side, modifying it from jsonrpc and sending it to Java again. In second option, I need to specify the details of the object in client side. I guess I can relate it with Java part somehow, but it would be messy.
Thus, if someone could come up with a feature like I mentioned, it would be nice !
PS: I have spent hours for this and it is disappointing being not able to do it. In the documentation, as far as I have read, I haven't been able to recognize any parts regarding to this issue, which is in my opinion quite fundamental. In the documentation, it is explicitly written that we are able to execute java methods with string a parameter. As a newbie, I tend to understand that a java method can be executed by any parameter type. If you could add a part regarding to this, it would save a lot of time.
PS2: Umm, this one is another issue I guess, but I would like to know if we are able to execute a method with more than one string parameters just like that;
jsonrpc.fooObj.foo("test","test2")
Are we able to execute a method with more than one parameters ? In the documentation as far as I read, I doubt there is a sample about multiple parameters.
On Thu, May 22, 2008 at 12:37 PM, William Becker <wbec...@gmail.com> wrote:
> You are trying to use the client-side proxy object as an argument to a >> call. This I am not sure is currently supported.
> I haven't tried this, but if it was declared as a callable reference, I'm > not sure why it wouldn't work. With 1.3RC1 we have got constructors working, > so you have two options, one of which I am sure will work!
> First option, just register Bar as a callable reference: > JSONRPCBridge.registerCallableReference(test.entities.Bar.class)
> This could fix the whole thing up, but I haven't used a callable reference > as an object on the bridge before, so I'm not sure it will work.
> Another way is to construct it and use it purely in the javascript. To do > this you need to declare it as a constructor by registering it both as a > CallableReference and registering its class in jsp: > JSONRPCBridge.registerCallableReference(test.entities.Bar.class) > JSONRPCBridge.registerClass("Bar",test.entities.Bar.class);
> Then you can create "Bar" in javascript: > var bar = jsonrpc.createObject("Bar",[]); > bar.setBaz("hede"); > jsonrpc.fooObj.setBar(cb,bar);
> Hope this works, > Will
>> There is potential that this sort of thing to be implemented - I think >> there was some discussion some time back about using the callable >> proxies interchangeably as opaque references although I'm not sure if >> support for it is complete. William?
>> What is probably happening is the BeanSerializer is treating the >> serialized client proxy as any other object for which the server then >> tries to map the fields to the Bar class (but it will only have the >> fields of the client-side proxy object that was sent which has no 'baz' >> field - thus it not being set).
On Thu, May 22, 2008 at 5:36 PM, Ali Çevik <cevik....@gmail.com> wrote: > Hi,
> First option seem doesn't seem to work, as it gives exception message:
> *uncaught exception: JSONRpcClientException: arg 1 could not unmarshall*
> Second one also gives an exception message which is probably due to a > version issue (I am using jabsorb 1.2.2) > *jsonrpc.createObject is not a function*
> However, even if I could use the second option, it wouldn't precisely solve > my problem. My intention is to get an object from Java side, modifying it > from jsonrpc and sending it to Java again. In second option, I need to > specify the details of the object in client side. I guess I can relate it > with Java part somehow, but it would be messy.
This is quite possible. I do it all the time. What you need to do is call registerObject on the "entry points" into your API, and then call them to bring down the objects you want to use on the JavaScript side. An object that you pull down to JavaScript can then be sent back to Java on the server, but the object coming back will be a copy, not the original object (you have to use references to get back to the original object on the Java side -- I personally never use references, and instead just pass around light weight data transformation objects-- it's simpler and easier to understand that way, IMHO)
In other words, registering an object doesn't make the object itself serialize down to the JavaScript side, it only makes the public methods of that object into entry points that you can then call from JavaScript. Then you can call those methods (kind of like a factory pattern) to get the objects you are interested in down to JavaScript from Java.
When you call those methods, your objects that get sent as parameters are transformed to Java and the object coming back from Java as the return value is transformed into JavaScript. An object received from Java can be sent back to Java and it will serialize back into the proper type of Object on the server side.
Jabsorb can handle all the basic types as well as Java bean classes and aggregates of them quite well. But some complex types may not serialize properly (you can write a custom serializer for this-- in practice I've never had to do this) and In general you want to be careful about what kinds of objects you pass around anyway as passing very large objects will be inefficient.
> Thus, if someone could come up with a feature like I mentioned, it would be > nice !
> PS: I have spent hours for this and it is disappointing being not able to > do it. In the documentation, as far as I have read, I haven't been able to > recognize any parts regarding to this issue, which is in my opinion quite > fundamental. In the documentation, it is explicitly written that we are able > to execute java methods with string a parameter. As a newbie, I tend to > understand that a java method can be executed by any parameter type. If you > could add a part regarding to this, it would save a lot of time.
This is correct, you can pass any parameter type to a method from JavaScript. I'm not sure why you are having a problem with this. It is quite clearly described in the manual in section 3 ( http://jabsorb.org/Manual)
> PS2: Umm, this one is another issue I guess, but I would like to know if we > are able to execute a method with more than one string parameters just like > that;
> jsonrpc.fooObj.foo("test","test2")
> Are we able to execute a method with more than one parameters ? In the > documentation as far as I read, I doubt there is a sample about multiple > parameters.
Yes, of course you can call a method with multiple arguments-- and even overloaded methods, and your example is exactly how you would call it (assuming that the fooObj.foo method takes two Strings as it's arguments.) The unit tests page has at least one example of a call with multiple arguments http://jabsorb.org/jabsorb-1.2/unit.jsp
Thanks for your reply. It is great if we are able to do such kind of things. But, what I couldn't understand is, why I can't do those ?
Could you perhaps take my example (which is quite fundamental, consisting two classes Foo and Bar) and make it run and post it here so that I and other programmers having the same problem will be able to benefit from it ? If you could do that, it would really be nice.
Thanks, Ali.
On Fri, May 23, 2008 at 4:02 AM, Arthur Blake <arthur.bl...@gmail.com> wrote:
> Hi, Ali. I'm sorry that you are having trouble with jabsorb.
> On Thu, May 22, 2008 at 5:36 PM, Ali Çevik <cevik....@gmail.com> wrote:
>> Hi,
>> First option seem doesn't seem to work, as it gives exception message:
>> *uncaught exception: JSONRpcClientException: arg 1 could not unmarshall*
>> Second one also gives an exception message which is probably due to a >> version issue (I am using jabsorb 1.2.2) >> *jsonrpc.createObject is not a function*
>> However, even if I could use the second option, it wouldn't precisely >> solve my problem. My intention is to get an object from Java side, modifying >> it from jsonrpc and sending it to Java again. In second option, I need to >> specify the details of the object in client side. I guess I can relate it >> with Java part somehow, but it would be messy.
> This is quite possible. I do it all the time. What you need to do is call > registerObject on the "entry points" into your API, and then call them to > bring down the objects you want to use on the JavaScript side. An object > that you pull down to JavaScript can then be sent back to Java on the > server, but the object coming back will be a copy, not the original object > (you have to use references to get back to the original object on the Java > side -- I personally never use references, and instead just pass around > light weight data transformation objects-- it's simpler and easier to > understand that way, IMHO)
> In other words, registering an object doesn't make the object itself > serialize down to the JavaScript side, it only makes the public methods of > that object into entry points that you can then call from JavaScript. Then > you can call those methods (kind of like a factory pattern) to get the > objects you are interested in down to JavaScript from Java.
> When you call those methods, your objects that get sent as parameters are > transformed to Java and the object coming back from Java as the return value > is transformed into JavaScript. An object received from Java can be sent > back to Java and it will serialize back into the proper type of Object on > the server side.
> Jabsorb can handle all the basic types as well as Java bean classes and > aggregates of them quite well. But some complex types may not serialize > properly (you can write a custom serializer for this-- in practice I've > never had to do this) and In general you want to be careful about what kinds > of objects you pass around anyway as passing very large objects will be > inefficient.
>> Thus, if someone could come up with a feature like I mentioned, it would >> be nice !
>> PS: I have spent hours for this and it is disappointing being not able to >> do it. In the documentation, as far as I have read, I haven't been able to >> recognize any parts regarding to this issue, which is in my opinion quite >> fundamental. In the documentation, it is explicitly written that we are able >> to execute java methods with string a parameter. As a newbie, I tend to >> understand that a java method can be executed by any parameter type. If you >> could add a part regarding to this, it would save a lot of time.
> This is correct, you can pass any parameter type to a method from > JavaScript. I'm not sure why you are having a problem with this. It is > quite clearly described in the manual in section 3 ( > http://jabsorb.org/Manual)
>> PS2: Umm, this one is another issue I guess, but I would like to know if >> we are able to execute a method with more than one string parameters just >> like that;
>> jsonrpc.fooObj.foo("test","test2")
>> Are we able to execute a method with more than one parameters ? In the >> documentation as far as I read, I doubt there is a sample about multiple >> parameters.
> Yes, of course you can call a method with multiple arguments-- and even > overloaded methods, and your example is exactly how you would call it > (assuming that the fooObj.foo method takes two Strings as it's arguments.) > The unit tests page has at least one example of a call with multiple > arguments http://jabsorb.org/jabsorb-1.2/unit.jsp