How to display JSON data in Vaadin Grid? - json

Vaadin version : 23.3.1
I am trying to display the fetched JSON data in grid,
It is ignoring the new line in the data.
I have bunch of JSON data which I am adding to a list and will add to the grid later
class Details{
String message;
Details(String msg){
this.message = msg;
}
public String getMessage() {
return msg;
}
public void setMessage(String msg) {
this.msg = msg;
}
}
Where Details is class which contains variable of type
String message.
public static List<Details> details = new ArrayList<Details>();
Details items = new Details(JSON_values);
details.add(items);
Creating list of objects of type detail class and writing it with JSON_value and then adding it to a list and after binding displaying it in grid.
After that I am adding it to the grid along with other columns
grid.addColumn(Details::getMessage).setHeader("MESSAGE");
grid.getColumns().forEach( col -> col.setAutoWidth(true));
grid.setItems(details);
Where details is another list of all the parameters.
I am trying to use the Html component but failed to do so.
Any suggestions on how to proceed further?

You can use grid.addThemeVariants(GridVariant.LUMO_WRAP_CELL_CONTENT); to make the cell contents increase in size.

I used TextArea Component in the Vaadin Grid which will display the formatted data as it is without truncating the new lines or whitespaces.
Using the Component Render method
https://vaadin.com/docs/latest/components/grid

Related

Convert Dataframe Dataset<Row> to JSON Format of String Data Type for particular Columns and convert the JSON String back to Dataframe

I have a dataframe. I need to call a Rest API for each record.
Lets say the Dataframe looks like:
|----|-------------|-----|---------|
|UUID|PID |DEVID|FIRSTNAME|
|----|-------------|-----|---------|
|1111|1234567891011|ABC11|JOHN |
|2222|9876543256827|ABC22|HARRY |
|----|-------------|-----|---------|
The JSON request string for first row should look like(Note: the json is created on 2 columns, not all), as the Rest API to be called requires the input in this format:
{"applicationInfo": {"appId": "ec78fef4-92b9-3b1b-a68d-c45376b6977a"}, "requestData": [{"secureData": "JOHN", "secureDataType": "FIRSTNAME", "index": 1 }, {"secureData": "1234567891011", "secureDataType": "PID", "index": 2 } ] }
The value of index key has to be generted on the fly, using an incremental counter for each row.
Then, i need to call the Rest API sending the above JSON as a string param.
The response from the API after encryption will look like:
{"responseData":[{"resultCode":"00","secureData":"63ygdydshbhgvdyw3et7edgu","secureDataType":"FIRSTNAME","index":1},{"resultCode":"00","secureData":"HKJJBJHVHG66456456FXXFFCGF","secureDataType":"PID","index":2}],"responseCode":"00","responseMessage":"SUCCESS","resultCounts":{"totalCount":2,"successCount":2,"failedCount":0}}
Then I need to read the above response and create a dataframe which should look like:
|----|--------------------------|-----|------------------------|
|UUID|PID |DEVID|FIRSTNAME |
|----|--------------------------|-----|------------------------|
|1111|HKJJBJHVHG66456456FXXFFCGF|ABC11|63ygdydshbhgvdyw3et7edgu|
|----|--------------------------|-----|------------------------|
If i convert the initial input dataframe toJSON().collectAsList(), then it looks like:
[{"UUID":"1111","PID":"1234567891011","DEVID":"ABC11","FIRSTNAME":"JOHN"}, {"UUID":"2222","PID":"9876543256827","DEVID":"ABC22","FIRSTNAME":"HARRY"}]
But this doesnt work as the Rest API requires its input in a certain format, mentioned above.
Please help.
For the above, I assume that the data set has been partitioned across the number of Spark workers and it is a generic data set of Row (data frame), then the below mechanism can be employed.
Define a class with the required attributes as a data container
Take the data set content as a List (takeAsList method if data set, refer)
Create and populate the objects of your data container (and store in such a way to identify them later, you shall have to repopulate them with decrypted data)
Serialize the list into a JSON array with Jackson (refer)
Step 4 & 5 can be combined with Jackson custom serializer refer example
Make the REST call and repopulate the data container objects (after deserializing the response with Jackson)
Create a data frame (an example)
Process the data frame (dataset of rows)
NOTE: The JSON structure you have provided seems not to be correct, JSON array is [{},{},{}]
In your case, given the format of the request JSON, direct conversion of rows will not work, as mentioned in point 1, make a set of model classes, you could consider the below model classes.
package org.test.json;
import java.util.List;
public class RequestModel {
protected ApplicationInfo applicationInfo;
protected List<RequestData> requestData;
public ApplicationInfo getApplicationInfo() {return applicationInfo;}
public void setApplicationInfo(ApplicationInfo applicationInfo) {this.applicationInfo = applicationInfo;}
public List<RequestData> getRequestData() {return requestData;}
public void setRequestData(List<RequestData> requestData) {this.requestData = requestData;}
}//class closing
package org.test.json;
public class ApplicationInfo {
protected String appId;
public String getAppId() {return appId;}
public void setAppId(String appId) {this.appId = appId;}
}//class closing
package org.test.json;
public class RequestData {
protected String secureData;
protected String secureDataType;
protected int index;
public String getSecureData() {return secureData;}
public void setSecureData(String secureData) {this.secureData = secureData;}
public String getSecureDataType() {return secureDataType;}
public void setSecureDataType(String secureDataType) {this.secureDataType = secureDataType;}
public int getIndex() {return index;}
public void setIndex(int index) {this.index = index;}
}//class closing
Process the list as obtained from the data frame and populate the model classes and then convert with Jackson to get the request JSON.
The below should do what you are looking for, don't directly run this, the data set is null
//Do not run this, will generate NullPointer, for example only
Dataset<Row> ds=null;
List<Row> rows=ds.collectAsList();
RequestModel request=new RequestModel();
//Set application id
ApplicationInfo appInfo=new ApplicationInfo();
appInfo.setAppId("some id");
request.setApplicationInfo(appInfo);
List<RequestData> reqData=new ArrayList<>();
for(int i=0;i<rows.size();i++) {
//Incrementally generated for each row
int index=i;
Row r=rows.get(i);
int rowLength=r.size();
for(int j=0;j<rowLength;j++) {
RequestData dataElement=new RequestData();
dataElement.setIndex(index);
switch(j) {
case 1:{dataElement.setSecureData(r.getString(j));dataElement.setSecureDataType("PID");break;}
case 3:{dataElement.setSecureDataType(r.getString(j));dataElement.setSecureDataType("FIRSTNAME");break;}
default:{break;}
}//switch closing
reqData.add(dataElement);
}//for closing
}//for closing

Can the GXT JsonReader (using AutoBeans) parse complex JSON structures in one request?

I need to work with data returned from a service which has a more complex JSON structure than the examples provided in the GXT documentation and thus far I cannot find any instructions or example which demonstrates how this might be accomplished.
The JSON contains multiple key/value pairs, but some of the key/value pairs are collections. I can have all of the data returned to me in one call from the service in the proper structure, but there does not appear to be a way to parse the data into separate entities. In my particular case I am attempting to configure a loader which will process one of the collections but I also need other key/value pairs from the same message (it is not ok to have the loader make one call and then have another call made for the same data and retrieve the other key/value pairs). Is there any way to accomplish this using GXT3?
Example: let's assume I can make a request from a server which returns JSON containing the name of an author along with a collection of the books the author has written. I want to display the author's name above a grid which lists the books. I want only one request made to the server and then have my view display the author in one component and the book list in a grid. Assume I need a loader instead of just a store as the grid may have to make additional calls (e.g. if it is a paging grid, livegrid, etc.).
Example JSON: (one JSON message returned with and author element along with a collection of book elements - I've indented the JSON to illustrate the structure)
{ "returnData" :
{"author" : "AuthorName"},
{"books" :
{"id" : "1", "name" : "Book1"},{"id" : "2", "name" : "Book2"}
}
}
Using the example for JsonReader (see the javadoc for an example) I can receive the request and parse the links into a collection using AutoBeans. This works fine when I need to have those retrieved and parsed in a loader. However, if I do that then the other properties are ignored. I currently don't see any way to parse the other values in the same request so they can be used elsewhere. My example code for the collection processing is below:
// this is the root JSON object, the AuthorRecord
public interface AuthorRecord {
#PropertyName(value="author")
String getAuthor();
#PropertyName(value="author")
void setAuthor(String author);
#PropertyName(value="books")
List<Book> getBooks();#
#PropertyName(value="books")
void setBooks (List<Book> books);
}
// models the book objects returned
public interface Book {
#PropertyName(value="id")
String getId();
#PropertyName(value="id")
void setId(String id);
#PropertyName(value="name")
String getName();
#PropertyName(value="name")
void setName(String name);
}
public interface ReturnData {
AuthorRootObject getAuthorRoot();
}
public interface LibraryAutoBeanFactory extends AutoBeanFactory {
AutoBean<ReturnData> authorRecord();
AutoBean<ListLoadConfig> loadConfig();
}
public class ReturnDataJsonReader extends JsonReader<ListLoadResult<Book>,
ReturnData> {
public ReturnDataJsonReader(AutoBeanFactory factory,
Class<ReturnData> rootBeanType) {
super(factory, rootBeanType);
}
#Override
protected ListLoadResultBean<Book> createReturnData(Object loadConfig,
ReturnData incomingData) {
return new ListLoadResultBean<Book>(incomingData.getBooks());
}
}
The problem I was having was that I need to have a view that includes a grid (paging grid, etc.) which lists out the books, while having the Author's name sit above the grid. I wanted to get all of this information (or at least the first page of results) with only one request to the server since the JSON message contains all the information I need to accomplish this. The problem is that the loader makes the request and receives the response, and it expects that the reader it will use is going to process a collection. In my case, I need the loader to process the collection of books but also populate another data field. The solution I found was to create an arbitrary collection to pass to the loader and then implement my own load handler to process the return object as needed.
1.The JSON being returned is really just one object of type ReturnData. The extended JsonReader could process this using AutoBeans, but if the reader is to be used for the loader, it needs to return a collection. Therefore, override the createReturnData() method to return a collection of one object.
public class ReturnDataJsonReader extends JsonReader<ListLoadResult<AuthorRecord>,
ReturnData> {
public ReturnDataJsonReader(AutoBeanFactory factory, Class<ReturnData> rootBeanType)
{
super(factory, rootBeanType);
}
#Override
protected ListLoadResultBean<AuthorRecord> createReturnData(Object loadConfig,
ReturnData incomingData) {
List<AuthorRecord> authorDataCollection = new ArrayList<AuthorRecord>();
authorDataCollection.add(incomingData);
return authorDataCollection;
}
}
2.The LoadHandler used in the examples takes a ListStore as an input and populates it with the results from the loader. Since the return object is not what we want populating the loader, and since we need to populate another property on the view, create your own LoadHandler to take the objects needed as input and populate them:
View Class Example:
public class ExampleViewClass {
// truncating most of the code in here for brevity
// note some of the objects referenced here reference objects in the question
private String authorName;
private ListStore<Book> bookList;
// IMPORTANT - create your own LoadHandler
private class LibraryLoadResultistStoreBinding<C, M, D extends
ListLoadResult<AuthorRecord>> implements LoadHandler<ListLoadConfig,
ListLoadResult<AuthorRecord>> {
private final ListStore<Book> bookStore;
private final String authorName;
public LibraryLoadResultistStoreBinding(ListStore<Book> books, String author) {
this.bookStore = books;
this.authorName = author;
}
#Override
public void onLoad(LoadEvent<ListLoadConfig, ListLoadResult<AuthorRecord> event)
{
// the response object
AuthorRecord response = event.getLoadResult().getData().get(0);
bookStore.replaceAll(response.getBooks());
author = response.getAuthor();
}
}
// example uses an HttpProxy but that's not required
public void populateView() {
LibraryAutoBeanFactory factory = GWT.create(LibraryAutoBeanFactory.class);
ReturnDataJsonReader reader = new ReturnDataJsonReader(factory, ReturnData.class);
String path = "http://path.to.resource/getinfo";
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, path);
HttpProxy<ListLoadConfig> proxy = new HttpProxy<ListLoadConfig>(builder);
final ListLoader<ListLoadConfig, ListLoadResult<AuthorRecord>> loader = new
ListLoader<ListLoadConfig, ListLoadResult<AuthorRecord>> (proxy, reader);
loader.useLoadConfig(ReturnDataAutoBeanFactory.instance.loadConfig().as();
loader.addLoadHandler(new LibraryLoadResultistStoreBinding<ListLoadConfig,
AuthorRecord, ListLoadResult<AuthorRecord>>(bookList, authorName);
// pass in the objects to be populated
loader.load(); // fire the loader
}

Adding content from a database into a dropdownlist in struts2

I am doing my project in struts2 framework. but i cant find a way to specify a dropdown list from a database.. is there a way.. pls help
If you are talking about a drop down list in your JSP page than there is already a select Tag for that
<s:select name="mydrop_down" list="%{sports}" />
where list is a Iterable source to populate from. If the list is a Map (key, value), the Map key will become the option 'value' parameter and the Map value will become the option body.
All you need to create a List/Map/Array in you action class and provide its getter and setter how the list will be picked form the ActionClass in jsp will be handled by the framewrok itself
Action Class
public class MyAction extends ActionSuport{
private List<String> sports; //can be array or map etc
getters and setters for sports
public String execute() throws Exception{
sports = init the List and fill it
// can fill the list from database
return SUCCESS;
}
}

How to decorate a custom member on LINQ To SQL

I want to create a property on my LINQ To SQL designer-generated class that gets and sets a formatted type, like that:
public partial ALinqClass
{
public string formatedValue
{
get { return formatValue(TheValue); }
set { TheValue = RemoveFormating(value); }
}
}
TheValue is the property generated by the Linq designer.
How do I decorate public string formatedValue so I can bind it to controls on my form?
For example: When I use Visual Studio to create a Object Data Source from my linq object/class all properties linq generated are present on the Object data Source, but formatedValue is not.
Why ?
WHY ?
WHHHHHHHHY ????????!!!!!
Thank you.
Fábio
Linq-to-SQL generated entities are declared as partial classes so you should be able to create another file and add custom properties to the same partial class. This is so if you have to regenerate the classes, your additions to the entities are still available in a different file.
Also as long as these properties are public, you should be able to databind them just like generated properties.
For Windows Forms Databinding, you need either
A datasource, which is derived from Control.
An intermediate component, BindingSource, acting as link between the LinqToSql datasource and bound controls.
I'll outline how to use BindingSource.
private BindingSource binding1;
private YourDataContext context;
void Form1_Load(object sender, EventArgs e) {
// initialize the data context
context = new YourDataContext();
// initialize the BindingSource
binding1 = new BindingSource();
binding1.DataSource = context.YourObjects;
// bind controls to BindingSource
listBox1.DataSource = binding1;
listBox1.DisplayMember = "Name";
}
Obviously, this short sample is not complete, but should give you an idea on how to start. Further information can be found at Data Binding and Windows Forms.
Mark
I think this is the answer I wanted. Linq must have a few more classes and inheritances, but I think this will do.
http://msdn.microsoft.com/en-us/library/system.componentmodel.bindableattribute.aspx
[Bindable(true)]
public int MyProperty
{
get {
// Insert code here.
return 0;
}
set {
// Insert code here.
}
}

ErrorProvider(from Windows Forms) for ASP.net & linq-to-sql?

I am trying to figure out how to notify the user which field failed to validate.
I setup LINQ to SQL class datacontext to access a database from ASP.net pages. Since user input will be from by web interface forms and import from Excel files, i would like the write the validation logic in one place. The idea behind this is when i import from excel. I will collect the error messages for each row, and display a summary, somehow. A logical place seems to extend the class generated by LINQ to SQL. According to most documentation and examples, i should do something like this:
public partial class Customer
{
partial void OnTitleChanging(string value)
{
if (!Char.IsUpper(value[0])) {
throw new ValidationException(
"Title must start with an uppercase letter.");}
}
}
The problem with this approach is that validation will stop on the first failed field.
In Windows Forms Link1, if I define an ErrorProvider component in the form and set the DataSource property of it to your BindingSource the exception will be indicated by a red circle right to the validated control. The tooltip of this red circle will show the exception message.
Is there something similar for ASP.net pages? I am using the listview control and inline editing in the listview.
Updates:
- I actually did something similar to what Nick Carver is suggesting. Link2 . Instead of throwing an exception, i record an error message.
public partial class PQSSClassesDataContext
{
public partial class ErrorFeilds
{
private static List<string> Messages = new List<string>();
public void AddErrorMessage(string message)
{
Messages.Add(message);
}
public List<string> GetErrorMessages()
{
return Messages;
}
}
}
I am actually stuck on how to map the error message to the field. That's why i was looking for something like ErrorProvider. I am already using events instead of exceptions to record errors. Any idea how to mark the corresponding failed field from the codebehind file?
Any help appreciated.
What we have done in the past is simply have an error collection on the DataContext, extend it just adding something like a List<ValidationError>. Then all you need to do is override SubmitChanges() and check if you have any validation errors, and decide to abort, throw them, handle however you wish really at that point...all before calling base.SubmitChanges()
We're in a ASP.Net per-request life-cycle, but if your Context is around longer make sure to clear the error list.
It's handy for your ValidationError class/objects to contain a reference to a common base or interface that all your classes implement so you can point to the object later from the error if needed. (e.g. get the ID for throwing the error labels or other info in the right place).
Example classes:
public class ValidationError {
public string Message { get; set; }
public IBase { get; set; }
}
public interface IBase {
public long ID { get; set; }
public DateTime DateModified { get; set; }
}
There is the ValidationSummary control, that works with the individual validation controls to show a list of errors. But the action of the WinForms ErrorProvider is performed in ASP.NET by the individual validation controls, which derive from the Label control