Spring Mvc ModelAttribute with containing class reference not working? - spring

I want to to create different #Entity entities within the same Controller.
public class ContentContainer {
public Object content;
public ContentContainer(){}
public ContentContainer(Object object){
setContent(object);
}
public Object getContent() {
return content;
}
public void setContent(Object content) {
this.content = content;
}
}
Controller method
#RequestMapping(value="create", method=RequestMethod.GET)
public String GET(Model model) throws InstantiationException, IllegalAccessException {
Class<?> clazz = ????; // a Random POJO is chosen, i want to use POJOs!!
Object object = clazz.newInstance();
model.addAttribute("mymodel", new ContentContainer(object));
return "create";
}
#RequestMapping(value="create", method=RequestMethod.POST)
public #ResponseBody Object POST(#ModelAttribute(value="mymodel") ContentContainer cc) {
Object object = cc.getContent();
// object == NULL but why??
return object;
}
Thymeleaf page as was asked in another comment.
That#s why i posted this
some more
text
so i can post
this additional information
dont't know
why this is necessary.
Please excuse me.
But this has to be done
to obey the rules.
<head>
<title th:text="${title}">Entity create</title>
</head>
<body>
<form action="#" th:object="${mymodel}" th:action="#{${url}}" method="post">
<fieldset>
<table class="table table-striped">
<thead>
<tr>
<th style="width: 150px;">Fieldname</th>
<th style="width: 150px;">Input</th>
</tr>
</thead>
<tbody>
<tr th:each="v : ${values}">
<td><label th:for="${v}" th:text="${v}">Fieldname: </label></td>
<td><input type="text" th:field="*{__${v}__}" /></td>
</tr>
</tbody>
</table>
<div class="submit">
<button type="submit" name="create" th:text="#{entity.create}">Create</button>
</div>
</fieldset>
</form>
</body>
</html>
In the Post Method i get NULL for getContent
What am i missing?

I've just tested your thing.
In my JSP:
<form:form method="POST" action="./index.do" modelAttribute="testObject">
<h1>test for object </h1>
<table>
<tbody>
<tr>
<td><form:input path="object"/></td>
<td><input type="submit" value="test Object"/></td>
</tr>
</tbody>
</table>
</form:form>
And my testObject is similar to your ContentContainer
When I debug, I found no matter what I've given in my GET method for getting this page, the object contained in the container return by POST method has always the type String.
And can you post your JSP please, because in my test there is no convert or null error, maybe there's something wrong with your JSP about the modelAttribute.

Related

Delete mapping doesn't work, I'm getting 405 error

I have this controller:
#DeleteMapping("/delete/{id}")
public String deleteWallet(#PathVariable("id") long id, Model model) {
Wallet wallet = walletRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("Invalid wallet Id:" + id));
walletRepository.delete(wallet);
model.addAttribute("wallets", walletRepository.findAll());
return "redirect:/";
}
And this is HTML:
<table class="table table-striped table-hover" id="productTable">
<thead>
<tr class="success">
<th>Wallet Name</th>
<th>Initial Balance</th>
</tr>
</thead>
<tbody>
<tr th:each="wallet : ${wallet}">
<td th:text="${wallet.walletName}"></td>
<td th:text="${wallet.initialBalance}"></td>
<td>
<a th:href="#{/api/wallet/delete/{id}(id = ${wallet.id})}">Delete</a>
</td>
</tr>
</tbody>
But when I press delete button its says:
Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported]
I'm confused, my method is #DeleteMapping
Anyway, I found a way:
HTML:
<form th:action="#{/api/wallet/delete/{id}(id=${wallet.id})}"
th:object="${wallet}" method="post">
<input type="hidden" th:field="${wallet}">Delete</input>
<button type="submit" onClick="return confirm('sure?')"/>
</form>
Controller:
#PostMapping("/delete/{id}")
public String deleteWallet(#PathVariable("id") long id, Model model) {
walletService.deleteWalletById(id);
return "redirect:/";
}

Spring MVC Form Validation Neither BindingResult nor plain target object for bean name 'BanqueForm' available as request attribute

I have a probleme when validating a form with spring MVC
i have this exception
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'BanqueForm' available as request attribute
this is my controller
package org.gestion.banque.controllers;
import java.util.Map;
import javax.validation.Valid;
import org.gestion.banque.entities.Compte;
import org.gestion.banque.metier.IBanqueMetier;
#Controller
public class BanqueController {
#Autowired
private IBanqueMetier metier;
#RequestMapping(value="/index",method=RequestMethod.GET)
public String index(Model model){
model.addAttribute("BanqueForm", new BanqueForm());
return"banque";
}
#RequestMapping(value="/chargerCompte", method=RequestMethod.GET)
public String charger(Model m) {
m.addAttribute("BanqueForm", new BanqueForm());
return "banque";
}
#RequestMapping(value="/chargerCompte",method=RequestMethod.POST)
public String charger(#Valid BanqueForm bf,
BindingResult result,Model model){
if(result.hasErrors())
{
return "banque";
}
try {
Compte c=metier.ConsulterCompte(bf.getCode());
bf.setTypeCompte(c.getClass().getSimpleName());
bf.setCompte(c);
} catch (Exception e) {
bf.setException(e.getMessage());
}
model.addAttribute("BanqueForm", bf);
return "banque";
}
}
and this is my view
<body>
<div>
<f:form modelAttribute="BanqueForm" method="post" action="chargerCompte" >
<table>
<tr>
<td>Code :</td>
<td><f:input path="code"/></td>
<td><f:errors path="code"></f:errors> </td>
</tr>
<tr>
<td>
<input type="submit" value="OK" />
</td>
</tr>
</table>
</f:form>
</div>
<c:if test="${ not empty BanqueForm.exception}">
<div>${BanqueForm.exception} </div>
</c:if>
<c:if test="${not empty BanqueForm.compte}">
<div>
<table>
<tr>
<td>Solde :</td>
<td>${BanqueForm.compte.solde}</td>
</tr>
<tr>
<td>Solde :</td>
<td>${BanqueForm.compte.dateCreation}</td>
</tr>
<tr>
<td>Type de Compte :</td>
<td>${BanqueForm.typeCompte}</td>
</tr>
<c:if test="${BanqueForm.typeCompte=='CompteCourant'}">
<tr>
<td>Decouvert :</td>
<td>${BanqueForm.compte.decouvert}</td>
</tr>
</c:if>
<c:if test="${BanqueForm.typeCompte=='CompteEpargne'}">
<tr>
<td>taux :</td>
<td>${BanqueForm.compte.taux}</td>
</tr>
</c:if>
</table>
</div>
</c:if>
</body>
</html>
Add #ModelAttribute("BanqueForm") annotation when obtaining BanqueForm object. Something like this:
public String charger(#Valid #ModelAttribute("BanqueForm") BanqueForm bf,
BindingResult result, Model model) { ... }

share 'form fragment' between createForm.html, updateForm.html on thymeleaf

I use thymeleaf on spring.
I don't want to produce duplicated html page createForm.html and updateForm.html.
Maybe It requires copy & paste.
My code is below.
<form class="form-horizontal" role="form" th:action="${!template.new#{/templates}" method="post"
th:object="${template}">
...
</form>
When template is before saving(=create), action is '/templates'.
When tempalte is after saving(=update), action is '/templates/UUID/edit'.
=> It is rails convention.
You can also add this address to the ModelMap:
modelMap.add("address", "/templates")
th:action="#{${address}}"
HTML
<div class="form-group">
<label for="objectName">Name</label>
<input type="text" class="form-control" th:value="${object.name}" name="name"
id="objectName" placeholder="Name"/>
</div>
bottom HTML
<div class="table-responsive">
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>Name 1</th>
<th>Name 2</th>
<th>Name 3</th>
</tr>
</thead>
<tbody>
<tr data-th-each="eachObject : ${obj}">
<td><a data-th-text="${eachObject.name}" th:href="#PATH/edit?Name=}+${eachObject.name}">...</a></td>
<td data-th-text="${eachObject.name2}">...</td>
<td data-th-text="${eachObject.name3}">...</td>
<td><a th:href="#{/PATH/delete?objname=}+${eachObject.name}">delete</a></td>
</tr>
</tbody>
</table>
</div>
Controller
#RequestMapping(value = "/create",method = RequestMethod.GET)
public String createMethod(Model model) {
Object obj = new Object();
model.addAttribute("Object", obj);
return "htmlpage";
}
controller
#RequestMapping(value = "/form/save", method = RequestMethod.POST)
public String campaignPost(#ModelAttribute("object") Object obj, Principle prin, Model model){
service.save(obj);
}

Value is not getting pass from view to action method

i am new in mvc. i have design a form and when i am click the submit button then right action method is calling but form field's value are not getting pass.
here is my view code
<div id="mydiv">
#using (Html.BeginForm("Save", "Game", FormMethod.Post, new { #Id = "Form1" }))
{
<table border="0">
<tr>
<td>Name :</td>
<td><input name="name" type="text" /></td>
</tr>
<tr>
<td>Salary :</td>
<td><input name="salary" type="text" /></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Save" /> </td>
</tr>
</table>
}
</div>
here is my action method
public ActionResult Save(string str1, string str2)
{
return View("Message");
}
when save is getting called the str1 & str2 is being null please help me to pass value and also discuss various trick to pass value from view to action method. thanks
Change you controller
public ActionResult Save(string name, string salary)
{
return View("Message");
}
As you have to use variable name which you have defined in input
<input name="name" type="text" />
<input name="salary" type="text" />
If you want to return partial view.
return PartialView("Message", <<OptionalPartialViewModel>>);
You should start by learning about conventions in ASP.NET MVC. You should use models for communicating between controllers and views.
Create a model type first:
public class SalaryModel
{
public string Name { get; set; }
public string Salary { get; set; }
}
Create your form by using HTML helpers and strongly typing your view:
#model SalaryModel
<div id="mydiv">
#using (Html.BeginForm("Save", "Game", FormMethod.Post, new { #Id = "Form1" }))
{
<table border="0">
<tr>
<td>Name :</td>
<td>#Html.TextBoxFor(item => item.Name)</td>
</tr>
<tr>
<td>Salary :</td>
<td><input name="salary" type="text" /></td>
</tr>
<tr>
<td colspan="2">#Html.TextBoxFor(item => item.Salary)</td>
</tr>
</table>
}
</div>
Then you can get the form values inside the model:
[HttpPost]
public ActionResult Save(SalaryModel model)
{
return View("Message");
}
There's a great tutorial on ASP.NET MVC website that can help you with the basics.
MVC Bind form inputs to Action by their names. You should change your method params as the same of the form. Also, you are missing the HttpPost attribute:
[HttpPost]
public ActionResult Save(string name, string salary)
{
/*Do Stuff here*/
return View("Message");
}

How are Spring MVC Controllers being bound to JSP pages?

Hi I am new to spring and I am trying to develop a simple portlet that accepts users first and last name and saves it to db using hibernate.
Basically I cannot figure out how the jsps and controllers communicate; I am missing some chunk here.
This is my first controller that needs to be called (where do I mention so?)
package codes.controller;
import javax.portlet.RenderResponse;
import codes.base.User;
import codes.service.UserService;
#Controller(value="SimpleUserController")
#RequestMapping(value = "VIEW")
public class SimpleUserController {
// -- auto-wiring of service dependency
#Autowired
#Qualifier("userService")
private UserService userService;
// --maps the incoming portlet request to this method
#RenderMapping
public String showUsers(RenderResponse response) {
return "home";
}
#ExceptionHandler({ Exception.class })
public String handleException() {
return "errorPage";
}
// -- #ModelAttribute here works as the referenceData method
#ModelAttribute(value="user")
public User getCommandObject() {
return new User();
}
}
Initially I am displaying a home.jsp that will display the form with two input boxes and a submit button.
<%#include file="include.jsp" %>
<portlet:actionURL var="addUserActionUrl">
<portlet:param name="myaction" value="addUser" />
</portlet:actionURL>
<form:form name="home" commandName="user" method="post"
action="${addUserActionUrl}">
<table>
<tr>
<td>First Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="firstname" /></td>
</tr>
<tr>
<td>Last Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="lastname" /></td>
</tr>
<table align="right">
<tr>
<td> </td>
<td><input type="submit" value="SUBMIT" /></td>
</tr>
</table>
</table>
</form:form>
This JSP should call the action method in the AddUserController.java:
package codes.controller;
import javax.portlet.ActionResponse;
import javax.portlet.RenderResponse;
import codes.base.User;
import codes.service.UserService;
#Controller(value = "AddUserController")
#RequestMapping(value = "VIEW")
public class AddUserController {
#Autowired
#Qualifier("userService")
private UserService userService;
#RenderMapping(params = "myaction=addUser")
public String showRegisterPage(Model model) {
model.addAttribute("user", new User());
model.addAttribute("users", getUsers());
return "addUser";
}
public List<User> getUsers() {
return userService.getAllUsers();
}
#ActionMapping(params = "myaction=addUser")
public void addBook(#ModelAttribute(value = "user") User user,
BindingResult bindingResult, ActionResponse response,
SessionStatus sessionStatus) {
if (!bindingResult.hasErrors()) {
userService.addUser(user);
response.setRenderParameter("myaction", "users");
sessionStatus.setComplete();
} else {
response.setRenderParameter("myaction", "addUser");
}
}
}
This time this firstname+last name should be saved in the db AND the screen should refresh to show a new form that will have a dropdown with the current users' names in the database and another first name and last name form fields. If you select a username from the dropdown the form fields are populated and you can edit these values and click on UPdate button to save the values in DB. Otherwise you can add a new user to the database using submit button.
addUser.jsp:
<%#include file="include.jsp" %>
<portlet:actionURL var="addUserActionUrl">
<portlet:param name="myaction" value="addUser" />
</portlet:actionURL>
<portlet:renderURL var="homeUrl">
<portlet:param name="myaction" value="Users" />
</portlet:renderURL>
<script type="text/javascript" src="js/userRelated.js"></script>
<form:form name="addUser" commandName="user" method="post"
action="${addUserActionUrl}">
<form:select path="model">
<form:option value="NONE" label="--- Select ---" id="userList" onchange="showHide()"/>
<form:options items="${users}" />
</form:select>
<table>
<tr>
<td>First Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="firstname" /></td>
</tr>
<tr>
<td>Last Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="lastname" /></td>
</tr>
<table align="right">
<tr>
<td> </td>
<td><input type="submit" id="submit" value="SUBMIT" />SUBMIT</td>
</tr>
<tr>
<td> </td>
<td><input type="submit" id="update" value="SUBMIT" />UPDATE</td>
</tr>
</table>
</table>
</form:form>
I am hiding and unhiding the SUBMIT/UPDATE button using onchange of dropdown. How do I call different functions in the addUsercontroller depending on the button available?
by updating the action attribute of form element with javascript

Resources