Spring MVC Controller List<MyClass> as a parameter - spring

I have a Spring MVC application. Jsp page contains form, which submitting.
My controller's method looks like:
#RequestMapping(value = "photos/fileUpload", method = RequestMethod.POST)
#ResponseBody
public String fileDetailsUpload(List<PhotoDTO> photoDTO,
BindingResult bindingResult,
HttpServletRequest request) {
// in the point **photoDTO** is null
}
My class is:
public class PhotoDTO {
private Boolean mainPhoto;
private String title;
private String description;
private Long realtyId;
//getters/setters
But, if I write the same method, but param is just my object:
#RequestMapping(value = "photos/fileUpload", method = RequestMethod.POST)
#ResponseBody
public String fileDetailsUpload(PhotoDTO photoDTO,
BindingResult bindingResult,
HttpServletRequest request) {
// Everething is Ok **photoDTO** has all fields, which were fielded on the JSP
What should I do in the situation? What if I have on Jsp many PhotoDTO objects (15) how can I recive all of them on the server part?

The page should pass the parameters for each PhotoDTO in the list back to the server in the appropriate format. In this case you need to use the status var to specify the index of each object in the list using the name attribute.
<form>
<c:forEach items="${photoDTO}" var="photo" varStatus="status">
<input name="photoDTO[${status.index}].title" value="${photo.title}"/>
<input name="photoDTO[${status.index}].description" value="${photo.description}"/>
</c:forEach>
</form>

Related

#RequestMapping in spring 3.2.8

I have this controller in Spring Framework MVC application (version 3.2.8) with 2 different methods: 1 for the GET and the other one for the POST
#Controller
public class ManageAccountController {
private static final Logger LOGGER = Logger.getLogger (ManageAccountController.class);
//private static final String USER="userBean";
#Autowired
private UserService userService;
/**
*
* #param request the http servlet request.
* #param model the spring model.
*
*/
#RequestMapping(value = "/accounts/manageaccount.do", method = RequestMethod.GET)
public String showForm ( #ModelAttribute("dataAccountCommand") final DataAccountCommand dataAccountCommand,
BindingResult result,
HttpServletRequest request,
Model model,
Locale locale) {
dataAccountCommand.setUserBean(getUser(request));
return "registerAccountView";
}
#RequestMapping(value = "/accounts/saveaccount.do", method = RequestMethod.POST)
private String saveAccount ( #ModelAttribute("dataAccountCommand") final DataAccountCommand dataAccountCommand,
BindingResult result,
HttpServletRequest request,
Model model,
Locale locale) {
return "registerAccountView";
}
}
the point is that when I put this in the browser
http://127.0.0.1:7001/devices_admin/accounts/manageaccount.do
I am redirected to the jsp, but when I put
http://127.0.0.1:7001/devices_admin/accounts/saveaccount.do
I have this error
URL: /devices_admin/accounts/saveaccount.do
???error404.error???
calling it from a jsp gives me the same result:
<form:form commandName="dataAccountCommand"
name="dataAccountForm"
id="dataAccountForm"
method="post"
action="${pageContext.servletContext.contextPath}/accounts/saveaccount.do"
htmlEscape="yes">
</form:form>
You can not invoke a POST method directly from the URL bar of your Browser. If you put something in the URL bar you are invoking the GET mehtod.
Instead you have to create a page with a form
<form method="POST" action="http://127.0.0.1:7001/devices_admin/accounts/saveaccount.do">
...
</form>
Or you can install a REST client in your browser and make the call directly using the POST method.

Spring 3 : Binding same controller method to multiple form action

I have a controller method with RequestMapping.PUT and having a URI
#RequestMapping(value = "/add/email", method = RequestMethod.POST)
public String addNewAccountEmail(#Valid #ModelAttribute EmailClass emailObject, BindingResult bindingResult, Model model) {
return displayForm(model);
}
I have a form like :
<form:form id="add-user-email" action="/add/email" name="manageUserAddEmail" method="post" modelAttribute="accountEmail">
I want to have more form pointing to same action , but need to do different operations inside addNewAccountEmail method. So how can I achieve this in Spring ? Basically any parameter which can make me differentiate functionalities or somehow I can have multiple methods having same RequestMapping URL and Method ?
I can only use RequestMethod.POST as I have similar requirements for other methods as well.
Basically I do not want the URL to change in Browser when invoking actions, that is why I want all form actions to point to same action URL.
You could point all of your forms at the same controller method and then differentiate the form-specific functionality within that method by looking for form-specific request parameters.
Each form would need to add its own request parameter to identify it - such as:
<input type="hidden" name="form1_param" value="1"/>
And then you can vary the behaviour inside the method by inspecting the HttpServletRequest:
#RequestMapping(value = "/add/email", method = RequestMethod.POST, )
public String addNewAccountEmail(#Valid #ModelAttribute EmailClass emailObject, BindingResult bindingResult, Model model, HttpServletRequest request) {
if (request.getParameter("form1_param") != null) { // identifies 1st form
// Do something
} else if (request.getParameter("form2_param") != null) { // indentifies 2nd form
// Do something else
}
...
}
It would be cleaner however to have multiple controller methods mapped to the same path, but specify different params in the RequestMapping - to differentiate the different forms.
#RequestMapping(value = "/add/email", params="form1_param", method = RequestMethod.POST)
public String addNewAccountEmail1(#Valid #ModelAttribute EmailClass emailObject, BindingResult bindingResult, Model model) {
// Do something specific for form1
return displayForm(model);
}
And also:
#RequestMapping(value = "/add/email", params="form2_param", method = RequestMethod.POST)
public String addNewAccountEmail2(#Valid #ModelAttribute EmailClass emailObject, BindingResult bindingResult, Model model) {
// Do something specific for form2
return displayForm(model);
}
Etc.
#RequestMapping accepts arrays as parameters (with an or semantic).
#RequestMapping(
value = "/add/email",
method = { RequestMethod.POST, RequestMethod.PUT } )

Spring MVC instantiates a new Bean instead of reusing the old one in the Model (#ModelAttribute)

I think my problem is rather simple, but it's been 2 days and I can't figure it out:
I am new to Spring MVC and I am trying to implement a simple #Controller that handles a form.
GET request: I add a new PortfolioBean attribute to the Model.
POST request: I expect to receive a #ModelAttribute with the same PortfolioBean.
#Controller
public class FormController {
#RequestMapping(value = "/form", method = RequestMethod.GET)
public String getForm(Model model) {
PortfolioBean portfolio = new PortfolioBean();
model.addAttribute("portfolio", portfolio);
return "index";
}
#RequestMapping(value = "/form", method = RequestMethod.POST)
public String postForm(#ModelAttribute("portfolio") PortfolioBean portfolio) {
System.out.println("Received portfolio: " + portfolio.getId());
return "showMessage";
}
}
Here is my JSP view:
...
<form:form action="form" commandName="portfolio" method="post">
Name : <form:input path="name" />
Nick Name : <form:input path="nickName" />
Age : <form:input path="age" />
Mobile : <form:input path="mobNum" />
<input type="submit" />
</form:form>
And here is my PortfolioBean:
public class PortfolioBean {
private String name;
private String nickName;
private int age;
private String mobNum;
private static int count = 0;
private int id;
public PortfolioBean() {
count++;
id = count;
System.out.println("NEW BEAN: " + id);
}
// setters & getters
}
As you can see, I added a static count variable to assign incremental IDs, and a println("NEW BEAN!") on the constructor.
My problem is that when I POST the form, I don't receive my original Bean object, instead Spring instantiates a new one, but I want my old Bean :(
Log:
GET /form
NEW BEAN: 1
POST /form
NEW BEAN: 2
Received portfolio: 2
Model attribute only exist in the context of one request. Towards the end of handling the request, the DispatcherServlet adds all the attributes to the HttpServletRequest attributes.
In your first request, you add a Model attribute and it becomes available for use in your jsp.
In your second request, because of the #ModelAttribute, Spring will try to create an instance from your request's request parameters. This will be a completely different instance as the previous one no longer exists.
If you want to reference the old object, you need to store it in a context that spans multiple requests. You can use HttpSession attributes for that purpose, either directly or through flash attributes. You might want to look into RedirectAttributes and #SessionAttributes.

Passing json object to spring mvc controller using Ajax

I am trying to send a json via Ajax request to a Spring mvc controller without success.
The json string has the following form:
{"Books":
[{'author':'Murakami','title':'Kafka on the shore'},{'author':'Murakami','title':'Norwegian Wood'}]}
The controller that parses the json wraps it through this java bean:
class Books{
List <Map<String, String>> books;
//...get & set method of the bean
}
The controller method has the following form:
#RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }, value = "/checkBook.do")
public ModelAndView callCheckBook(
#RequestBody Books books){....}
Unfortunately this does not work, I get the following error when invoking the method:
"Null ModelAndView returned to DispatcherServlet with name..."
Where am I getting wrong?
Thank you in advance!
Regards
create a Model class
class Books
{
private string author;
private string title;
// gets and sets
}
And Also create Wrapper class like this
class BookWrapper{
private List<Books> Books; // this name should matches the json header
}
Now in controller
#RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }, value = "/checkBook.do")
public ModelAndView callCheckBook(
#RequestBody BookWrapper Books){....}
in Ajax call create a seralizeArray of you forum this will give you json object and then it will bind to the wrapper class

Retrieving values from jsp without using pojo variables

We can get the values of a submitted form in a jsp page in controller using request.getParamenter(xxxx),by using commandName or by using hidden fields.
is there any other way to get values from a form of jsp in a controller?
Spring provides several ways of databinding parameters in your request to actual objects in Java. Most of the databinding is specified using annotated methods or by annotating paramters within methods.
Lets consider the following form:
<form>
<input name="firstName"/>
<input name="lastName"/>
<input name="age"/>
</form>
In a Spring controller the request parameters can be retreived in several ways.
#RequestParam Documentation
#RequestMapping("/someurl)
public String processForm(#RequestParam("firstName") String firstName,
#RequestParam("lastName") String lastName,
#RequestParam("age") String int,) {
.....
}
If our request parameters are modeled in a class Person.java we can use another technique, #ModelAttribute.
Person.java
public class Person(){
String firstName;
String lastName;
int age;
//Constructors and Accessors implied.
}
#ModelAttribute Documentation
#RequestMapping(value="/someUrl")
public String processSubmit(#ModelAttribute Person person) {
//person parameter will be bound to request parameters using field/param name matching.
}
These are two of the most commonly used methods Spring uses to provide databinding. Read up on others in the Spring MVC Documentation.
public String myMethod(#RequestParam("myParamOne") String myParamOne) {
//do stuff
}
You can directly map fields to controller method by annotation #RequestParam or you can directly bind object using #ModelAttribute.
public ModelAndView method(#RequestParam(required = true, value = "id") Long id) {
}
public ModelAndView method(#ModelAttribute("pojo") POJO pojo, BindingResult results) {
}

Resources