Passing String from JSNI to Java - GWT - java

I am having problem passing String to a Java method in my GWT project:
public final native String waveIt()/*-{
var instance = this;
var data = $wnd.Waverecorder.data();
var strData = data.toString();
var arr = strData.split(',');
for (var i = 0; i < arr.length; i++) {
var data = arr[i];
console.log(data);
instance.#com.mycode.wave.showcase.client.Showcase::updateWave(Ljava/lang/String;)(data.toString());
}
}-*/;
Looking from the console log of Chrome/Firefox I can see that I get the right data (this is the exact log I get):
-0.00006103515625
-0.00006103515625
-0.00006103515625
-0.05072021484375
-0.553833007812
(more data omitted)
When the GWT java method received the data it is empty. What could be the reason?

This method should be void, because you do not return a string - you call a Java method from it.
Looking at your code, you don't need var instance = this; and you can remove instance. before #com.
You declare var data twice: before the loop and inside the loop. Instead of calling your Java method with data.toString(), you can call it with arr[i].

What do you mean by:
When the GWT java method received the data it is empty.
Are you talking about the string that waveIt() should return?
The bug may be that there is no return statement in waveIt().

Related

illegal arument exception in ajax call while passing js array object

I am passing two variables in ajax call, one as normal string variable and other one js array object which i m sending to my java class..but when i m sending with array object,the ajax call is getting failed and throwing 500 response code with illegal argument exception
var array1 = new Array();
var inputs = document.getElementsByTagName("input");
for (var i = 0; i < inputs.length; i++) {
array1.push($(inputs[i]).attr('name').toString());
}
var path = "javaclassurl";
$.ajax({
type: "POST",
url: path,
data: {
var1: var1,
array1: array1
},
});
$(this).dialog("close");
//}
},
This is the way i m receiving in my java class
String values[]=request.getParameterValues("array1");
This ajax call is inside dialog box as its a dialog box plugin being used.Please help me in getting the error corrected
Could you please try doing it this way:
String values[]=request.getParameterValues("array1[]");
jQuery API documentation for .ajax() call states:
processData (default: true)
Type: Boolean
By default, data passed in to the data option as an object (technically, anything other than a string) will be processed and transformed into a query string, fitting to the default content-type "application/x-www-form-urlencoded". If you want to send a DOMDocument, or other non-processed data, set this option to false.
So you might try setting this to false.

Is there a way to "expect" instance of certain Java class in JavaScript code?

Assume that I have Foo.class in Java:
public class Foo {
public int id;
public String data;
}
And that I have Foo "class" in JavaScript:
function Foo(id, data) {
this.id = id;
this.data = data;
}
Also, assume that I have Java controller that returns instance of Foo.class as a response to a REST request. In my JavaScript (AngularJS) code the request is sent as:
$http.get(url + 'bar/get-foo/')
.success(function (response) {
var foo = new Foo(response.id, response.data);
logger.info("SUCCESS: /get-foo");
})
.error(function (error_message) {
logger.error(error_message)
});
And it works. But is there a way to avoid passing every property from response to Foo constructor (some sort of expecting the Foo object, or casting it into a Foo object)?
I tried using Object.create(Foo, response) but I get TypeError: Property description must be an object: true
Of course there's always a possibility of refactoring the JavaScript side Foo constructor into:
function Foo(foo) {
this.id = foo.id;
this.data = foo.data;
}
But, that would require refactor of large portion of the codebase.
Thanks for your time. I appreciate it!
PS: For those who wonder why do I need this: It's not a problem with small classes like Foo, but some responses are instances of a much larger classes (with over a dozen of fields), which are not under my control.
EDIT: I accepted Chichozell's answer simply because it requires the least amount of work. Robin's and jonnyknowsbest's answers also work, (and will work for pure JavaScript, unlike Chichozell's answer, which is AngularJS specific). Haven't tried Laurentiu L.'s answer, but looks like it should also work.
Anyway this is A solution (not THE solution):
.success(function (response) {
var foo = new Foo();
angular.extend(foo, response); // angular.merge() for "deep-copy"
//...
}
Big thanks to everyone who answered/commented/edited in this thread.
If you want to keep your Java thinking on javascript, try using angular.extend(), which will "copy" the properties of an object to another
this = angular.extend(this, response)
In the foo function, or directly on the controler:
Foo = angular.extend(Foo, response)
You can do something like this to "deserialise" the JSON you receive back as the response to an initialised object:
function JSONToObj(jsondata) {
var json = JSON.parse(jsondata);
var name = null;
for(var i in json) { //Use first property as name
name = i;
break;
}
if (name == null)
return null;
var obj = new window[name]();
for(var i in json[name])
obj[i] = json[name][i];
return obj;
}
This assumes that the constructor exists in the global scope and that the response is JSON-formatted as such:
{
"Foo": {
"id": "the id",
"data": "the data"
}
}
You can make it pretty generic if you want to. And there wouldn't be too much refactoring to do, and this solution would ease your future changes to both classes.
You may change your Foo javascript object to an Angular JS service and inject it wherever you need it. This way you can have your data available globally. It's better than that local variable foo.
yourApp.factory('Foo',
function () {
//set a default or just initialize it
var fooObject= {};
return {
getId: function () { return fooObject.id; },
getData: function() { return fooObject.data;},
setId: function(newId){fooObject.id = newId},
setData: function(newData){fooObject.data=newData;},
initializeFromObject : function(response){
for (var prop in response){
fooObject[prop] = response[prop];
}
}
};
}
);
You can also make the creation of new services safer with methods like hasAllProperties (by iterating through the object's properties, whether it is an array or object). ; hasNullValues and so on.
Hope this helps and you see it's value.
You could also do something like this jsFiddle to achieve the structure you describe. The createObject function couold look something like the following code snippet.
function createObject(response, toCreate){
var newObject = new toCreate();
for(var attr in response){
if(newObject.hasOwnProperty(attr)){
newObject[attr] = response[attr];
}
}
return newObject;
}
Where you have createObject which takes a js object with the same attributes as your function as the response parameter, and a function (the object you want to create) as the toCreate parameter.
See the jsFiddle console log output, and you see that it works.
You could also, as seen in the jsFiddle, remove the check for hasOwnProperty to set the all attributes from the response regardless if the javascript function has them defined.

Accessing returned object in Loop

I had a quick question, Right now I have a method that returns a populated DTO object, in another class I am calling that method, and then trying to get access to some of the values that are on the returned Object. I am having trouble figuring out what the syntax should be to accomplish this. It is returning "result". I am currently getting an error:
"Null pointer access: The variable result can only be null at this location"
The DTO that I am returning contains a List and I want to get access to one of the values on that list. Below is my code snippet. Thank you for your help!
for (Integer i = 0; i < array.size(); i++) {
// System.out.println(array.get(i));
GetAccountRewardSummaryRequest request = new GetAccountRewardSummaryRequest();
AccountRewardSummaryDTO result = null;
request.accountKey = new AccountIdDTO(array.get(i));
RewardServicesImpl rewardServicesImpl = new RewardServicesImpl();
rewardServicesImpl.getAccountRewardSummary(request);
// This will return an AccountRewardSummaryDTO, print out and see if it is returning properly
System.out.println(result.rewards.get(6));
// System.out.println(request.accountKey);
}
It's not clear from your question, but I suspect that this:
rewardServicesImpl.getAccountRewardSummary(request);
should be:
result = rewardServicesImpl.getAccountRewardSummary(request);
If you want to use the value returned from a method, you need to do something with it.
Your code would be clearer if you didn't declare the result variable until you needed it though - and there's no point in using Integer here instead of int. Additionally, unless you really can't reuse the service, you might as well create that once:
RewardServices service = new RewardServicesImpl();
for (int i = 0; i < array.size(); i++) {
GetAccountRewardSummaryRequest request = new GetAccountRewardSummaryRequest();
request.accountKey = new AccountIdDTO(array.get(i));
AccountRewardSummaryDTO result = service.getAccountRewardSummary(request);
System.out.println(result.rewards.get(6));
}
Also, as noted, the fact that your variable called array clearly isn't an array variable is confusing.

VBA and Java Webservice

I have implemented a WebService in Java (RMI). In Excel I have two Makros, the one reads Data from the database via the webservice. the other writes to the database.
Reading the data from the database over the webservice is no problem (function: MyData[] getData() {...})
but when i try to call the method, which should write data to the database I have the problem, that the given Data from the VBA-Code is null then in the Java-Code.
Function: public void setData(final MyData[]) {...}
I debugged and found out, that the parameter isn't null in the VBA Code. It's only null in the Java Code.
So does anybody know, where the data may be lost?
I thought maybe I have a problem with the XML or the like, but I really don't know where to look for the mistake.
Of course: here is the code - I shortened it a little bit, but the main functionality is given
Btw, I changed the type of the data now to long and now I get an IllegalArgumentException
Java:
#WebMethod(operationName = "setData", action = "setData")
public void setData(final long k)
{
myValue = k;
}
VBA
in Sheet1 I call e.g.:
Call dataService.wsm_setData(5)
and in the serviceFile (generated with Web Service Toolkit):
Private sc_DataServic As SoapClient30
Private Const c_WSDL_URL As String = "http://pcname:8010/myurl/data?wsdl"
Private Const c_SERVICE As String = "DataServiceService"
Private Const c_PORT As String = "DataServicePort"
Private Const c_SERVICE_NAMESPACE As String = "http://myurl"
Private Sub Class_Initialize()
Set sc_DataServic = New SoapClient30
sc_DataServic.MSSoapInit2 c_WSDL_URL, str_WSML, c_SERVICE, c_PORT, c_SERVICE_NAMESPACE
sc_DataServic.ConnectorProperty("ProxyServer") = "<CURRENT_USER>"
sc_DataServic.ConnectorProperty("EnableAutoProxy") = True
Set sc_DataServic.ClientProperty("GCTMObjectFactory") = New clsof_Factory_Data
End Sub
Public Function wsm_setData(ByVal dcml_arg0 As Double)
On Error GoTo wsm_setDataTrap
sc_DataServic.setData dcml_arg0
Set sc_DataServic = Nothing
Exit Function
wsm_setDataTrap:
DataServicErrorHandler "wsm_setData"
End Function

Passing javascript array to servlet

I have looked previous questions on this topic on SO, but my problem is not solved yet.
I am passing the array from javascript to servlet.
JavaScript Code:
var action = new Array();
function getProtAcionValues(rowNo,columnCount)
{
for(var j=0;j<columnCount;j++)
{
action[j] = document.getElementById('textActions'+rowNo+''+j).value;
alert(action[j]);
}
}
Servlet Code:
String actions[] = request.getParameterValues("action[]");
if(actions!=null)
for(int i=0;i<actions.length;i++)
{
System.out.print(" Action: "+actions);
}
else
System.out.println("Action is null");
Using above code I am getting message "Action is null".
And if I try
String actions[] = request.getParameterNames("action[]");
I am getting Syntax error:
The method getParameterNames() in the type ServletRequest is not applicable for the arguments (String)
Please let me know if there is something wrong in code.
you can just simply get the array with the name of the array...
String actions[] = request.getParameterValues("action");
You can't pass a java array as a parameter, as it is an structure. The best way is to serialize it into an string object like a jSon. You can use JSON.stringify. Simple and efficient. As you can serialize in the server also, it's very useful.
Pass Javascript array variable with form action to send values to servlet, and then use
String[] darray=request.getParameterValues("variable name used with link");

Categories