I am using the Google Visualization API on the client side and I create a DataTable object. Then I want to pass it to my server and upload it via the Spreadsheet API to a spreadsheet. Probably the best way is to use JSON, so I converted it with the method toJSON() and sent it over POST to my server. I tried to use these 2 classes:
DataTable (JavaScript)
DataTable (Java)
Now I noticed, that these 2 classes aren't compatible, at least not over JSON. The JavaScript class converts for example to this:
{"cols":[
{"id":"Col1","label":"","type":"string"}
{"id":"Col2","label":"","type":"date"}
],
"rows":[
{"c":[{"v":"a"},{"v":"Date(2010,10,6)"}]},
{"c":[{"v":"b"},{"v":"Date(2010,10,7)"}]}
]
}
But the Java side DataTable has different names for the parameters, and I am using Gson which has different type values:
cols -> columns
c -> cells
v -> value
type:"string" -> type:"TEXT"
type:"number" -> type:"NUMBER"
And I am afraid that there are even more incompatibilities.
So.. how can I convert the JavaScript DataTable to the Java object DataTable?
I ran into the same problem in reverse. It appears that the DataTable object in the Java Datasource Library is not parallel to the Javascript DataTable object in the Google Visualization API.
Returning a Java Datasource Library DataTable object requires using the JsonRenderer, rather than the default serialization. And it appears only to work passing from the server to the client. Am not sure if it can be done the other direction.
#WebService
#Path("/tables")
public class DataManager extends GenericManager<db, Long> {
#Path("/hello/")
#GET
#Produces(MediaType.APPLICATION_JSON)
public DataTable getDataTable() {
DataTable data = new DataTable();
... populate object ...
return data;
}
However, the Java DataTable object returned by default serialization is not the same thing as the Google Visualization API javascript DataTable. You can't pass it to a GVis chart.
Instead, from Java, you use the JsonRenderer class (see this Google Groups email) to convert it to a Json-like string that's missing quotes around attributes for modest compression.
#Path("/hello/")
#GET
#Produces(MediaType.TEXT_PLAIN)
public String getDataTable() {
DataTable data = new DataTable();
CharSequence charSequence = JsonRenderer.renderDataTable(dataTable, true, true);
return charSequence.toString();
}
That string can be parsed in Javascript by surrounding with parentheses, not shown in the object literal notation in the examples (see this Google Group forum):
jQuery.ajax({
context: this,
type: 'Get',
url: url,
success: function(data) {
var args = eval('('+data+')'); // add parens around the returned string
var dataTable = new google.visualization.DataTable(args);
...
});
I don't see a method for going the reverse way to the Java Datasource Library DataTable object.
So not quite an answer but you're not alone
Well I am using python on the backend and GWT on the frontend and passing a DataTable from the backend to the frontend works without any problems.
I am using the google-visualization-python api on the backend to create the DataTable.
Parsing is done with following code:
DataTable dataTable = DataTable.create(JSONParser.parseLenient(data).isObject().getJavaScriptObject());
I also convert the parsed DataTable back to JSON to store the json string in localStorage and parsing the stored json string also works fine.
The GWT DataTable is just a simple wrapper which ultimately just calls the function of the underlying Javascript DataTable via JSNI.So I don't see any reason why they should be incompatible.
Make sure you use the latest gwt-visualization API (1.1.2) ?
Related
I was trying to write a data model to send a JSON to the API and delete some fields
the JSON should contain the id of some words and it should look exactly like this :
{
"words":[3,4,5]
}
as I know and also as the https://jsonformatter.org/ said the data class should be something like the following piece of code:
data class words(var id: List<Int>)
but the problem is when I pass the data to it and toast it to see if it's a valid JSON request for the server the output will be this :
words(id=[1,2,4,5])
and it's not what it should be.
as I said I need this :
{
"words":[3,4,5]
}
I think the following should work.
data class AnyNameYouWant(val words: List<Int>)
I think the name of the data class really doesn't matter as it would finally represent the { } object syntax of json.
Looking in the comments, I think it's better to use some logging library like Timber. If you are using Retrofit then use can also use HttpLoggingInterceptor and set the level to Body that will print the body of the response in the logcat.
I'm currently working on an application built in Scala with Spray routing.
So for dealing with a JSON document sent over POST, it's pretty easy to access the variables within the body, as follows;
respondWithMediaType(`application/json`) {
entity(as[String]) { body =>
val msg = (parse(body) \ "msg").extract[String]
val url = (parse(body) \ "url").extractOpt[String]
However, I'm now trying to write an additional query with GET, and am having some issues accessing the parameters sent through with the query.
So, I'm opening with;
get {
respondWithMediaType(`application/json`) {
parameterSeq { params =>
var paramsList = params.toList
So, this works well enough in that I can access the GET params in a sequential order (just by accessing the index) - the problem is, unfortunately I don't think we can expect GET params to always be sent in the correct order.
The list itself prints out in the following format;
List((msg,this is a link to google), (url,http://google.com), (userid,13))
Is there any simple way to access these params? For example, something along the lines of;
var message = paramsList['msg']
println(message) //returns "this is a link to google"
Or am I going about this completely wrong?
Apologies if this is a stupid question - I've only switched over to Scala very recently, and am still getting both acquainted with that, and re-acquainted with Java.
What I usually do is use the parameters directive to parse the data out to a case class which contains all the relevant data:
case class MyParams(msg: String, url: String, userId: Int)
parameters(
"msg".as[String],
"url".as[String],
"userId".as[Int]
).as[MyParams] {
myParams =>
// Here you have the case class containing all the data, already parsed.
}
To build your routes you could use the parameters directives. I'm not sure if this is what you're looking for, anyway you could use them as:
get {
parameters('msg) { (msg) =>
complete(s"The message is '$msg'")
}
}
Spray directives can be easily composed so you can use combine them in any way you want.
I hope that helps you.
I'm working with jQuery DataTables. I have it listing out a view and have checkboxes to select multiple documents. I'm able to get the selected keys into session scope via this client side JavaScript code :
<xp:this.script><![CDATA[// Build array of selected rows
var myTableApi = x$("inventoryTable").DataTable();
var count = myTableApi.rows( { selected: true } ).count();
var dataArr = [];
var rowData = myTableApi.rows( { selected: true } ).data();
$.each($(rowData),function(key,value){
dataArr.push(value[3]);
});
// Push that to the requestScope
setScopeValue("session", "rowCount", count);
setScopeValue("session", "rowIds", dataArr);]]></xp:this.script>
Once the id's are in Scope I change pages and then I want to load them into my Java pageController.
I can easily use a variable resolver to get ahold of "rowIds". But I'm not sure how to get it into Java so I could work with it. Ideally I'd like it to be List or Set or something similar.
In Java, how can I convert this JavaScript Array to a Collection based object?
Thanks!
There are a few tricks to do here.
First, since the particular implementation of your setScopeValue function converts all values to a string before sending them to the server, it's important to do setScopeValue("session", "rowIds", XSP.toJson(dataArr)). That way, the value stored on the server will be ["foo", "bar", "baz"] instead of foobarbaz.
Secondly, the best way to get to the session-scoped value in Java would be via ExtLibUtil.getSessionScope().get("rowIds").
That value will be a string, though, and not an array type, so it'll have to be parsed from JSON. Using the IBM Commons JSON capabilities, that can be done with:
List<?> rowIds = (List<?>)JsonParser.fromJson(JsonJavaFactory.instance, ExtLibUtil.getSessionScope().get("rowIds"))
for(Object rowIdObj : rowIds) {
String rowId = StringUtil.toString(rowIdObj);
// do stuff with each ID here
}
You can also potentially case it directly to a List<String>, since Java's generics are really just hints for compiler-generated code, and not really enforced in the objects themselves, but there you run the risk of a ClassCastException if the incoming List contains any non-string types.
I'm making checkboxes and using Scala, I found nice example but in Java. But I couldn't convert it to Scala.
This is Java code:
Form<StudentFormData> formData = Form.form(StudentFormData.class).fill(studentData);
Scala's play.api.data.Form class doesn't have "fill" and "form" methods like Java's play.data.Form. How I can create Form in Scala?
Here is a function that I use to get data from the Form and generate an object Location.
def add = DBAction { implicit rs =>
val data = LocationForm.form.bindFromRequest.get
Locations.create(Some(data.venueName), data.lat, data.lon)
Redirect(routes.LocationController.all) }
I'm using playframework 2.2.0 with Java. How can I return Not Modified from my controller actions?
There are several methods in the Controller superClass: ok(), noContent() etc, but not notModified().
Looking at the source code for play I can see:
val NotModified = SimpleResult(header = ResponseHeader(NOT_MODIFIED), body = Enumerator.empty,
connection = HttpConnection.KeepAlive)
in play.api.mvc.Results. But how do I wrap a SimpleResult in something which can be returned by Java controller?
the method wants to return a Result:
public interface Result {
scala.concurrent.Future<play.api.mvc.SimpleResult> getWrappedResult();
}
but I don't know how to generate a Future from Java. (I tried with scala.concurrent.Future$.MODULE$... but it's not visible to my java code)
Instead of something like ok(), try this:
return status(304, "Content not modified, dude.");
Reference: http://www.playframework.com/documentation/2.2.0/JavaActions
It looks like play.api.mvc.Results, in the Scala API, actually has a NotModified generator, but the Java API does not. You can't use anything from the Scala API if you're going with the Java API. Seems like the Java API is the Play Framework's unloved child.
In summary, returning status 304 is much simpler than trying to drag in components from the Play Scala API and use them from Java. HTTP response code 304 = Content Not Modified.
See the list of codes here: http://www.w3.org/Protocols/HTTP/HTRESP.html