How to receive dynamically generated input value in spring as bean - java

In my project i dynamically generate the text box in table like below
project Name Date1 Date2 Date3 Date4 Date5 Activity
java Development Addnew
C++ Development Addnew
i display tables for one week.if user clicks addnew i generate the dynamic text box below the row where user clicked addnew button.
My problem is how to get all the textbox value in my spring controller as bean class.Because i am not sure abut how many text boxes are come in page load and submit.
Any Idea will be greatly appreciated!!!

There aren't enough specifics in your question for a specific answer. However the general approach I would recommend.
If you have a framework like Backbone or Angular, investigate use of its collection facilities.
Write JavaScript that builds JSON array from all your textfields
Define a POJO in Java that mirrors each entry in your array.
Ensure you're using Jackson - this maps JSON to Java objects for you before your controller is called
Define an method in your controller that takes a list of POJO, e.g. create(List values) with a URL like /times/{ employeeId} using PUT
For reading out of the database, add method in your controller that returns a list of POJO, e.g. List values get(long employeeId) with a URL like /times/{ employeeId} using GET
Alternatively if you need the form to be 'live', i.e. 'Add new' causes row in database instantly use a REST interface with a create, update and DELETE using POST, PUT and DELETE respectively
I assume you'll need to update the list later, so I'd recommend a structure with an ID which can be used for CREATE and UPDATE operations, not just a plain list of Strings, this will also allow more fields later.
public void Foo {
private String project;
private String name;
private long id;
// getters + setters
}
JSON for a create
[{"project":"java","name":"Development",id:0}, {"project":"C++","name":"Development",id:0}]
JSON for a later update, i.e. with IDs round-tripped
[{"project":"java","name":"Development",id:100}, {"project":"C++","name":"Development",id:101}]

Go with the traditional getParameter() method. I assume your text box will have unique names while generated using jquery.
In the controller,
List<String> requestParameterNames = Collections.list((Enumeration<String>) request.getParameterNames());
for (String parameterName : requestParameterNames) {
String attributeName = parameterName;
String attributeValue = request.getParameter(parameterName);
// will have the text box values
}

Related

Passing a boolean value from UI to rest controller

I have an application with front end on Angular and backend using Spring/Java.
The functionality is like show employee details and there is a checkbox in the UI. Following should be the behavior
when checkbox is checked, show all employees for a given department
when the checkbox is unchcecked, exclude some employees based on some criteria (this logic is done on backend)
For this, I have a get request and I added an additional parameter of type boolean to the "get" request.
This is how the code is for the UI component
get(include:boolean, dept:string):Observable<EmployeeList>{
let params = new HttpParams();
params=params.set('dept',dept);
params=params.set('include',String(include));
}
Please note that I am using casting to String for include param since I am not finding a way to pass the boolean value from UI using HttpParams.
On the backend the controller is like this
#GetMapping(value="/employee")
public EmployeeList list(#RequestParam String dept, String include) {
boolean flag = Boolean.parseBoolean(include);
.............
}
So I am trying to avoid the following
1. params=params.set('include',String(include));
2. boolean flag = Boolean.parseBoolean(include);
Is there a way? For post and put request,we use form which works fine with booleans.
Turns out the Spring automatically takes care of converting to intended data type so fixed the problem by
#GetMapping(value="/employee")
public EmployeeList list(#RequestParam String dept,#RequestParam boolean include) {
.............
}

Partial fields update REST API

There is this MongoBean: SuperBean
class SuperBean extends MongoBaseBean{
private String id;
private String title;
private String parent;
//And getters, setters
}
Need is to write an update API, which is capable of performing partial attributes update. Common approach seen across the web as well as heard from my peers is to check the fields in the request for Null and update if not null. But what if the update request is for the value to be updated to Null??
After few discussions, we came up with three approaches:
Set default value for the field in the bean. Hence instead of non-null parent field, if it does not have $ in the request, this will be considered for update.
class SuperBean extends MongoBaseBean{
private String id;
private String title;
private String parent = "$";
//And getters, setters
}
Let the update API Implementation accept a Map. The actual bean is fetched and all the fields that are present in the request map will be updated.
#Post
public SuperBean updatePartial(Map<String,Object> dataObject) {}
Let the update API accept DTO, that contains 2 maps. One to contain old values, other for new values. This could be advantageous in scenarios, where the update has to happen only if the database contains the values as sent in oldDataObj. But this increases the payload size.
class SuperBeanUpdateDTO {
private Map<String, Object> oldDataObj;
private Map<String, Object> newDataObject;
//getters, setters
}
#Post
public SuperBean updatePartial(SuperBeanUpdateDTO updateDTO) {}
What factors should be considered to chose one of these approaches? Is there another better way to approach this problem?
In my projects, we usually choose the way that similar with your second way. but not exactly the same.
for example, in your client side, you have a page or a view to modify your profile info, includes name, birthday, gender, although you just modify the name value, when you click save button, it still will send the data to server includes birthday and gender with name field, but just keep its value as old. and the server API will directly update these three values in database, won't check whether its value changed or not.
if you have another page or view to modify other parts of the profile, likes password, it need add a new method in client and a new API in server. the API URL likes PATCH /reset_password, and the sent data should include old_password and new_password field.
PS:
1. we use PUT or PATCH to update a resource, not POST, POST is used to create a new resource.
2. when you update a resource, in the above example, the API likes PATCH /profiles/:id (other's profile) or PATCH /profile (yourself profile), so the sent data doesn't need id field anymore, it includes in your API URL.

Dynamically show fields of the generic type through intellisense

In Servoy, a development and deployment platform, you have the possibility to use what is called a JSFoundSet which is an object containing record objects defined by its SQL. Such a JSFoundSet is created as follows using the appropriate annotation:
/** #type{JSFoundSet<db:/database/table_name}*/
var fs = null;
from this point on you can use in your code the variable fs to get or set values to the properties of table_name. So if I would create a foundset of table Customer and this table contains the columns id, firstName and lastName, then the Servoy platform provides intellisense that allows me to do this:
fs.id = 1;
fs.firstName = 'John';
fs.lastName = 'Doe';
Since I use a lot of Java too, I wanted to see if I can create something similar of this in Java. So I want to create a class FoundSet of a certain generic type, say of type Customer in our example, after which in my code I can create an object of this class and then access the public fields (set/get) of FoundSet. While typing I wish to see these fields show up through intellisense.
Is there a library or some sort that allows me to define some annotations as the Servoy example to accomplish this?

Lazy loading of the content

I have two entities : User and Post (relation one-to-many). Post fields: id, creationDate, title, content, user.
Data is stored in the database and accessed via Hibernate.
I have a controller to pass Post object as a JSON to JavaScript. Then it is shown on the web page. But it is not always necessary to pass all the Post fields. For ex., I need to show to the user only title and creation date, and if the user presses the button Show content, only then I need to show post content (which I want to request from server only when it is need to show).
So here is a problem: How can I implement lazy initialization of the content field in Post object? Should I write two methods in my controller: one for generating JSON with list of Posts and setting content field to null or empty String, and another to pass only content string?
Make post content an object and a single table in db.
It looks like the following in java:
public class Post {
...
PostContent postContent;
}
First you may try to initialize the lazy collection at the DAO via Hibernate.initialize(lazyCollection). If it didn't work then either use FetchType.EAGER or keep the session open during request and the collection should be fetched when needed.

Struts2 type conversion of a flattened JSON object in a query string

EDIT: Changed question title and content. Upon reading the JSON plugin guide I realize the plugin might be expecting a JSON string instead of this query map, in which case I normally go with GSON instead. I guess the question becomes: how can Struts2 handle type conversion of a query string like this: sort[0][field]=status&sort[0][dir]=asc
I am using Kendo UI grid to interface with my Struts2 backend. The AJAX request being sent to the server follows the following format (GET query string):
take=5&skip=0&page=1&pageSize=5&sort%5B0%5D%5Bfield%5D=status&sort%5B0%5D%5Bdir%5D=asc
or (non-escaped):
take=5&skip=0&page=1&pageSize=5&sort[0][field]=status&sort[0][dir]=asc
Basically, Kendo UI grid is sending a flattened JSON object to the server. So I create a sort model object like so to take the input:
public class SortModel {
private String field;
private String dir;
}
and include this in my Struts2 action as a variable to be populated:
private SortModel[] sort;
However, this never gets populated by Struts2 when the AJAX request comes in. I also tried to add the JSON interceptor, but I think I misunderstood its deserialization process, as explained in the edit.
Anyway, has anyone managed to Struts2 type conversion working using the above query string or similar: sort[0][field]=status&sort[0][dir]=asc?
sort[0][field]=status&sort[0][dir]=asc
The above is not proper JSON, strings should be quoted. With that done the following will work.
In which case a field (or json parameter) in the form name[i]['s'] which has a value of String and where i is an integer and s is any string would be backed by:
private List<Map<String, String>> name = new ArrayList<Map<String, String>>();
//getter AND setter required
PS: With Struts2 you can index into lists of lists of lists... without issue.
Okay.
It turns out that vanilla Struts2 doesn't accept query strings in the format obj[idx][property] (feel free to correct me on this). I was expecting it to convert the query string to an array of that specific object.
What Struts2 does accept is the format obj[idx].property which it will correctly convert to private Object[] obj.
So I guess the possible solutions to this would be:
JSON.stringify(jsonObj) before passing it to the query string, a la &jsonData=[{property:'value'}] - which in this case, I can't do since Kendo UI grid doesn't seem to have an interceptor-like event to let me change the query parameters. Or,
Implement a custom type converter that handles this particular format. Or,
Intercept the AJAX request before it is being sent to the server and re-format the query string, using jQuery.ajaxSend e.g.
$(body).ajaxSend(function(event, req, settings){
console.log(settings.url); //contains the url string to replace
settings.url = settings.url.replace(some_regex, 'correct format');
});

Categories

Resources