Dynamically generated form submission and Spring framework? - spring

I have a dynamically generated form (using jQuery). So beforehand I don't know how many form elements do I have. Does anybody have any idea how we can do it.?

POST the fields in the request body as a JSON-ified map, and use Jackson to to turn it into a Map<String, String> on the controller side. Your controller method would look something like this:
#RequestMapping(value="/url", method=RequestMethod.POST)
public getMap(#RequestBody Map<String, String> fields){
//Manipulate fields as you wish
.
.
.
}
That way you will have your fields as key/pair values inside the map ready for you to manipulate them.
You can turn your fields into a map fairly easily using jQuery (or similar) like this:
var fields = {}
$.each("input:text", function(i, item){
fields[mapKeyValue] = $(item).val();
}
This example assumes that your pair value is the text input, but you can manipulate the values however you want. This is by no means a complete example, but should give you an idea on how to start.

Related

How to implement multiple values in single queryparameter in rest api?

eg:
http://host:port/template/products/?productid=1234,1235
how to implement rest api for the above url where in single queryparam passing multiple values and get the all existing records for the productids
Try something like below to accomplish what you are trying to do:
#RequestMapping(value="/products", method=RequestMethod.GET)
public String getMultipleProductsInfo(#RequestParam List<Long> productIdList) {
String productsInfoAsString = getExistingRecordsForTheProductIds(productIdList);
return productsInfoAsString;
}
Notice the
#RequestParam List productIdList
The comma separated list of product IDs are copied into the productIdList list object. You can either iterate through the list or send it over to the method that is responsible for fetching the results from the datasource, such as your database
Please note that the above code snippet returns the response as String. But you could make your API return a response in other formats too, such as JSON.

DataTables server-side filtering by objects in a Many to Many relationship

I have a datatables.net DataTable in my app which shows all elements from a table (All entities of class Action). This class has an attribute which is a List of Regions mapped as #ManyToMany using Spring JPA, and I'd like to be able to filter by Regions all the data. So if I choose Regions A, B and D, only show those Actions that apply to at least one of them (For example if Action 1 applies to Regions B and C)
So the controller, which looks like this...
#JsonView(value={DataTablesOutput.View.class})
#ResponseBody
#RequestMapping(value = "/rest/actions_datatable", method = RequestMethod.GET, produces = "application/json")
public DataTablesOutput<Action> getActions(#Valid DataTablesInput input, HttpServletRequest request) {
DataTablesOutput<Action> actions_datatable = actionService.getActions(input);
String[] regionIdsToFilter = request.getParameter("regionfilter").split("[,]");
return actions_datatable;
}
This is my service
#Override
public DataTablesOutput<Action> getActions(DataTablesInput input) {
return actionRepository.findAll(input);
}
And as a note, ActionRepository extends DataTablesRepository
receives the IDs for those regions I'd like to use to filter my actions, as well as the DataTablesInput object sent by the Javascript code.
What would be the best way to achieve this? It would be easier if the field I'm trying to filter was a simple String, or maybe even an object, but a list of them does look a bit harder for me.

Spring Rest Controller Patch implementation

I need to implement PATCH functionality at my Spring #RestController.
I saw a lot of questions and the most common approach is to use a plain Java Map to do this. Map that allows null helps to solve the issue with null or absent values because it looks like impossible to implement on POJO.
Is there at Spring any out of the box functionality that helps to reflect values from Map to the existing model object or I have to implement it by myself.. for example using Jackson and so on ?
I can share My implementation of PATCH, hope this helps some one in some way. I have a client which has six fields like ( name, type, address fields , ID, Number, postcode), I can edit the client and change anything.
this is also an elaboration on the question with a partial answer ( or a complete one if there is no other way than the two below) Or perhaps PATCH is supposed to be done differently
clientService is just a service which holds the ClientRepository
#RequestMapping(value = "/{id}", method = RequestMethod.PATCH ,produces = {"application/vnd.api+json"} )
ResponseEntity<Resource<Client>> editClient(#PathVariable("id") Integer id,#RequestBody Client editedClientFromBrowser) {
// the id is the ID of the client that I was editing..
//i can use this to retrieve the one from back end
// editedClientFromBrowser is the changed Client Model Object
//from the browser The only field changed is the one
// that was changed in the browser but the rest of
//the object is the same with the ID as well
logger.info("Edit Client reached");
//retreive the same Client from backend and update and save it
// Client client = clientService.getClient(id);
// if (client == null) {
// throw new EntityNotFoundException("Client not found - id: " + id);
// }else{
// change the field that is different from the
//editedClientFromBrowser and then saveAndFlush client
//}
//OR saveAndFlush the editedClientFromBrowser itself
clientService.saveAndFlush(editedClientFromBrowser);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
now another method I read on (http://www.baeldung.com/http-put-patch-difference-spring) and tried:
#RequestMapping(value = "/{id}", method = RequestMethod.PATCH ,
produces = {"application/vnd.api+json"} )
ResponseEntity<Resource<Client>> editClient(#PathVariable("id") Integer id,
#RequestBody Map<String, Object> updates)
this one does give me a hashMap. but it gives me each and every field. even the ones I did not change. So, is that really beneficial? No idea seriously, may be it is lighter than getting the whole client object back.
I would have liked if I get only the hashmap of one or two fields which I did change. that would have been more in line with PATCH i think. Can I improve my two implementations in some way?

How to correctly initialize an object that have to contain the data retrieved by 2 methods of my controller in this Spring MVC application?

I am pretty new in Spring MVC and I have the following doubt about how correctly achieve the following task.
I am working on a web application that implement a user registration process. This registration process is divided into some consecutive steps.
For example in the first step the user have to insert a identification code (it is a code that identify uniquely a user on some statal administration systems) and in the second step it have to compile a form for his personal data (name, surname, birth date, and so on).
So, actually I have the following controller class that handle these steps:
#Controller
public class RegistrazioneController {
#Autowired
private LoadPlacesService loadPlacesService;
#RequestMapping(value = "/iscrizioneStep1")
public String iscrizioneStep1(Model model) {
return "iscrizioneStep1";
}
#RequestMapping(value = "/iscrizioneStep2", method=RequestMethod.POST)
public String iscrizioneStep2(Model model, HttpServletRequest request, #RequestParam("cf") String codicFiscale) {
System.out.println("INTO iscrizioneStep2()");
//String codicFiscale = request.getParameter("cf");
System.out.println("CODICE FISCALE: " + codicFiscale);
model.addAttribute("codicFiscale", codicFiscale);
return "iscrizioneStep2";
}
#RequestMapping(value = "/iscrizioneStep3", method=RequestMethod.POST)
public String iscrizioneStep3(#ModelAttribute("SpringWeb")Step2FormCommand step2Form, ModelMap model, HttpServletRequest request) {
System.out.println("INTO iscrizioneStep3()");
System.out.println("NOME: " + step2FormCommand.getName());
return "iscrizioneStep3";
}
Into the iscrizioneStep2() it is retrieved the first code (#RequestParam("cf") String codicFiscale).
Into the iscrizioneStep3() it is retrieved a command object containing the data inserted into the form of the view in which this form was submitted, this one:
#ModelAttribute("SpringWeb")Step2FormCommand step2FormCommand
It works fine.
Now my problem is that I have another object named Step3View that have to be initialized with the aggregation of the #RequestParam("cf") String codicFiscale object retrieved into the iscrizioneStep2() method and the #ModelAttribute("SpringWeb")Step2FormCommand step2FormCommand retrieved into the iscrizioneStep3() method.
This Step3View class simply contain the String codicFiscale and all the fields of the Step2FormCommand class.
Now my doubts are: what is the best way to handle this situation? Where have I to declare this Step3View object? at controller level? (so I can use it in all my controller methods?). Have I to annotate this class with #Component (or something like this) to inject it in my controller?
What is the best solution for this situation?
I think in order to get an answer you need to understand the question and ask the right question. I think your question is "how do I pass a parameter from one page to another page in SpringMVC?". You specifically want to know how to pass the "cf" param, but readers here will tend to pass over questions that are too specific because it takes too much time to figure out what you want.
In answer to that, see Spring MVC - passing variables from one page to anther as a possible help.
Also, there are many good answers about this question for JSP in general, which can be worked into the SpringMVC architecture. See How to pass value from one jsp to another jsp page? as a possible help.

In JSP, Field Path Uses HashMap<String,ArrayList<String>> (SpringMVC Form)

Suppose my model field is a HashMap of Strings to ArrayList's of Strings.
HashMap<String,ArrayList<String>> map = new HashMap<String,ArrayList<String>>();
For field binding, I need to point to an i-th item of the ArrayList of a specific key in my JSP. How do I do it? Will this double-bracket notation work? Assume that 'key' and 'index' are known JSTL variables in my JSP.
<form:checkbox path="map[${key}][${index}]" />
What I'm essentially doing is, for a field value, store its path e.g.
map['testkey'][4]
which would point to
map.get("testkey").get(4);
That doesn't work:
org.springframework.beans.NullValueInNestedPathException: Invalid property 'map[TestKey][0]'
NOTE According to this (Binding a map of lists in Spring MVC), this will be a problem because sub-objects are not auto-growable, and I need to implement a LazyList or a growable list? An ArrayList by itself is growable for Spring MVC's forms, but when used as a sub-collection, it's not? Very tricky.
I solved this problem by following the LazyList/LazySet implementation in the link above,
Binding a map of lists in Spring MVC
From their example,
public class PrsData {
private Map<String, List<PrsCDData>> prsCDData;
public PrsData() {
this.prsCDData = MapUtils.lazyMap(new HashMap<String,List<Object>>(), new Factory() {
public Object create() {
return LazyList.decorate(new ArrayList<PrsCDData>(),
FactoryUtils.instantiateFactory(PrsCDData.class));
}
});
}
}
Once I had a data structure like that mapped to my JSP Path, the field binding magically started working and I could then make my path e.g. map["key"][index] in the JSP.
As they replied, SpringMVC auto-converts simple lists and maps to Lazy collections, but does not do it when the collection is a subobject.

Resources