Spring MCV 3 showErrors doesn't display anything - spring-mvc

I try to validate a simple form. The validation is well executed but the result page doesn't display the errors.
I use velocity to render the page.
I've used as example the PetClinic project from spring website.
Here is my controller when I hit the "post form" button:
#Controller
#RequestMapping("/subscription")
public class SubscriptionController {
#RequestMapping(value = "/newCustomer", method = RequestMethod.POST)
public String processSubmit(#ModelAttribute Customer customer, BindingResult result, SessionStatus status) {
new CustomerValidator().validate(customer, result);
if (result.hasErrors()) {
return "subscription";
}
else {
status.setComplete();
return "redirect:/admin";
}
}
}
When I go in debug, I see the errors. I'm successfully redirected on the subscription page but the errors are not displayed.
My webpage (simplified):
...
#springBind("customer")
#springShowErrors("<br/>" "")
<form class="form-horizontal" method="post" action="#springUrl("/subscription/newCustomer/")">
....
<!-- Button -->
<div class="controls">
<button class="btn btn-primary">#springMessage("website.subscription.signup")</button>
</div>
</form>
...
if you need anything else, don't hesitate to tell me. Thanks for your help! I'm stuck on this since several days.

EDIT :
I finally found the error. It was with the springBind tag. I didn't well understand that you need to bind the field to show the associated error. Here is the fixed code for one field for twitter bootstrap framework.
#springBind("customer.name")
<div class="control-group #if(${status.error})error#end">
<!-- Prepended text-->
<label class="control-label">#springMessage("website.subscription.name")</label>
<div class="controls">
<div class="input-prepend">
<span class="add-on"><i class="icon-user"></i></span>
<input class="input-xlarge"
placeholder="John Doe" id="name" name="name" type="text">
</div>
<p class="help-block">
#springShowErrors("<br/>" "")
</p>
</div>
</div>
springShowErrors(...) will show all the errors associated with the field name of the POJO customer.

Related

How to submit an exisitng object from the view via a from in Thymeleaf with Spring MVC?

In my Thymeleaf view, I have some objects shown on the page:
Here's the HTML
<form method="post" action="#" th:action="#{/basket}" th:object="${itemOrder}">
<div class="card-body">
<h4 class="card-title">
item title
</h4>
<h5 th:text="${item.price} + ' €'">item price</h5>
<input type="hidden" th:field="*{sku}"/> <br>
<input type="submit" value="Add to basket" />
</div>
</form>
<div class="container" th:if="${itemOrder != null}">
<h4>Item in the basket:</h4><br>
<h5 th:text="${itemOrder.price} + ' €'">item price</h5>
</div>
Under each element, I have a form to submit this element to the controller.
All Thymeleaf and Spring MVC guides are showing how to submit a form when a user provides data through input fields. Here, I don't need to take in any data from the user, all the data is available already. I just need to wrap existing data and submit it with a form. How can I make it with Thymeleaf and Spring MVC?
Here's the BasketController that should handle the form reu
#PostMapping("/basket")
public String processItemOrder(#ModelAttribute ItemOrder itemOrder, Model model) {
model.addAttribute("itemOrder", itemOrder);
return "basket";
}

No mapping found for HTTP request with URI - No dispatcherservlet / servletmapping error

I know this is a common question but I'm getting desesperated here, Im pretty newbie and have been stuck with this for a long time now... I know this is not a DispatcherServlet or Servlet Mapping error as I'm working on a really big project that has everything working already.
What I need to do is add a form on an already existing jsp page, here is what I have
CONTROLLER:
#Controller
#RequestMapping("/messaging")
public class MessagingController {
#GetMapping
public String messagingView(Principal principal, Model model) throws ServiceException {
model.addAttribute("messagingInformation", new MessagingInformation());
return foo; -> this returns me to the main jsp where I'm creating the form
}
#PostMapping(value = "/submitInformation") -> I've also tried with #RequestMapping(value = "/submitInformation", method = RequestMethod.POST)
public String submitInformation(#ModelAttribute(value = "messagingInformation") #Valid MessagingInformation messagingInformation) {
return "redirect:/messaging"; -> shouldn't this redirect me to the main jsp?
}
}
JSP:
<form:form action="messaging/submitInformation" modelAttribute="messagingInformation" method="POST">
<div class="row col-sm-12 margin-top-container">
<div class="col-sm-4">
<span class="titles-select-box uppercase-text">RECEIVER</span>
<input name="receiver" type="email" id="receiverId" name="receiverName"
placeholder="Receiver" multiple>
</div>
</div>
<div class="col-sm-12 no-padding-left">
<div class="button-container pull-right">
<input type="submit" value="Send" class="btn btn-default"
id="sendButton" />
</div>
</div>
</form:form>
I'm mainly getting --No mapping found for HTTP request with URI [/foo/messaging/submitInformation] in DispatcherServlet -- I've asked around and I shouldn't add nothing to any cofiguration file or anything, clearly it's something wrong on my side but I can't see it
Leaving this in case anyone finds out... I was requiered to do a manual build so the java changes would show up. This is done through Projects -> Build All

TempData Dictionary is null after Redirect to page

So I have this issue that I am not unable to solve the way I think it's supposed to be solved.
I have an ASP.NET Core 2.1 Razor pages project. The code is pasted below and my problem is the following:
On the index page, I have a search form. The city name I enter in the search form gets used in the SearchResults OnPost method.
The OnPost redirects to OnGet which retrieves some results from the database based on the city passed in from the search form. From my understanding, TempData should be able to retain the value for the city passed in from the form, however, whenever I try to read TempData["CityFromForm"] in the OnGet method, the TempData dictionary is empty, even though that in the OnPost method I used the TempData.Keep method.
My current solution for this is using in memory cache to store the city value and pass it to the method that fetches the data from the database, but I would like to know why the TempData approach is not working.
On the index page on that project, there is a search from in which I enter a city for which I want to search the data, like so:
#model SearchDataViewModel
<form asp-page="/Search/SearchResults" method="post" class="col s6">
<div class="row">
<div class="input-field col s12">
<input placeholder="Please enter a city" type="text" name="City" class="validate autocomplete" id="autocomplete-input" autocomplete="off" />
<label for="City">City</label>
</div>
</div>
<div class="row">
<div class="input-field col s6">
<input id="StartDate" name="StartDate" type="text" class="datepicker datepicker-calendar-container">
<label for="StartDate">Start date</label>
</div>
<div class="input-field col s6">
<input id="EndDate" name="EndDate" class="datepicker datepicker-calendar-container" />
<label for="EndDate">End date</label>
</div>
</div>
<input type="submit" hidden />
</form>
What matters in that form is the city. That form gets sent to the SearchResults razor page.
SearchResults.cshtml.cs
public IActionResult OnPost()
{
// Cache search form values to persist between post-redirect-get.
var cacheEntry = Request.Form["City"];
_cache.Set<string>("City", cacheEntry);
TempData["CityFromFrom"] = Request.Form["City"].ToString();
TempData.Keep("CityFromForm");
return RedirectToPage();
}
// TODO: Find a better way to persist data between onPost and OnGet
public async Task OnGet(string city)
{
City = _cache.Get<string>("City");
var temp = TempData["CityFromForm"];
// Here I'd like to pass the TempData["CityFromForm"] but it's null.
await GetSearchResults(City); // this method just gets data from the database
}
TempData keys are prefixed by "TempDataProperty-". So if you have a key named "City", you access it via TempData["TempDataProperty-City"].
See https://www.learnrazorpages.com/razor-pages/tempdata
You also have a typo in the line where you assign the tempdata value: TempData["CityFromFrom"] should be TempData["CityFromForm"], I suspect.
So here is what I came up with, basically I get a city string from the search form. In the OnPost method I redirect to page where I add a route value which OnGet method can use.
In SearchResults.cshtml I added a #page "{city?}"
The url ends up looking like: https://localhost:44302/Search/SearchResults?searchCity={city}
In SearchResults.cshtml.cs
public async Task OnGet()
{
City = HttpContext.Request.Query["searchCity"];
PetGuardians = await GetSearchResults(City);
}
public IActionResult OnPost(string city)
{
return RedirectToPage(new { searchCity = city });
}

Spring 3 checkbox list objects have null properties

I may be hopelessly lost here, but having come from a MVC.NET world I cannot for the life of me figure this one out. I'm not getting any error messages, but all object properties submitted on a form submission are null. The objects themselves are not null, just their properties.
All I want to do is have a series of objects, represented by checkboxes on the form, after the forms submits. It's a little tricky as you can can see because of a nested list arrangement. The view renders perfectly on the GET request, but seems to forget everything when posted to the server. Does anyone have any examples of such a set-up? Could anyone suggest why all my objects loose their bindings?
My Controller:
#RequestMapping(value="/Search", method = RequestMethod.GET)
public String search(Model model)
{
Period periods = new Period();
SearchModel search = new SearchModel();
search.periods = periods.BuildPeriodList();
model.addAttribute("periods", periods.BuildPeriodList());
model.addAttribute(search);
return "search";
}
#RequestMapping(value = "/Search", method = RequestMethod.POST)
public String search(#ModelAttribute("searchModel") SearchModel search, BindingResult result)
{
System.out.println(Arrays.deepToString(search.periods));
return "search";
}
My View:
<div id="searchPage">
<div id="searchForm">
<form:form action="Search" method="post" modelAttribute="searchModel">
<h2>Search</h2>
<h2>Periods</h2>
<c:forEach items="${periods}" var="period" varStatus="index">
<form:checkbox path="periods[${index.count - 1}]" id="${period.name}" name="${period.name}" value="${period.name}"/>
<label for="${period.name}">${period.displayName}</label>
<div class="subPeriods">
<c:forEach items="${period.subPeriods}" var="subPeriod" varStatus="subIndex">
<form:checkbox path="periods[${subIndex.count - 1}].subPeriods" id="${subPeriod.name}" name="${subPeriod.name}" value="${period.name}"/>
<label for="${subPeriod.name}">${subPeriod.displayName}</label>
</c:forEach>
</div>
</c:forEach>
<div class="clear"></div>
<h2>Extras</h2>
<form:checkbox path="hasImage" name="hasImage" id="hasImage"></form:checkbox>
<label for="hasImage">Image</label>
<form:checkbox path="hasPaper" name="hasPapaer" id="hasPapaer"></form:checkbox>
<label for="hasPaper">Paper Data</label>
<form:checkbox path="hasExtended" name="hasExtended" id="hasExtended"></form:checkbox>
<label for="hasExtended">Extended Info</label>
<input type="submit" name="search" value="Search"></input>
</form:form>
</div>
<div id="searchResults">
</div>
<div class="clear"></div>
It's due to some of your checkboxes being bound to your "periods" model, while others being bound to your SearchModel model. The path attribute of the form:checkbox element tells how to bind the information.
Either include this within your SearchModel, or have another #ModelAttribute("periods") in your POST method.
I'd recommend sticking to one model, plus I'm not sure if you can have more than one #ModelAttribute in a controller method, something to try, though.

ASP.NET MVC 3: HTTP Post parameter allways null after deployment

I've created a small website in ASP.NET MVC 3, and it works fine in debugenvironment.
After deployment (on a https website) the website gives problems and after figuring a while, it seems that the HTTPPOST parameters are allways null ...
I'll provide some information:
the .cshtml:
#using (#Html.BeginForm("Registration", "Home", FormMethod.Post)){
<div id="middle">
<div id="radio">
#foreach (var item in Model)
{
<input type="radio" id="#string.Format("radio{0}", item.ID)" name="radio" value="#item.ID" /><label for="#string.Format("radio{0}", item.ID)">#item.Description</label>
}
</div>
<div id="divOverig">
<label for="overig">
Overig:</label>
<input style="float:right; width:70%;" type="text" id="overig" name="overig" />
</div>
</div>
<div id="end">
</div>
<div id="left">
#Html.ActionLink("Terug", "Device")
</div>
<div id="right">
<input type="submit" id="next" value="Naar apparaat informatie" />
</div>
}
The controller:
public ActionResult Problem(string radio, string overig){ ... }
In debug environment the parameters are correctly filled and passed. On the webserver the parameter is allways empty.
When I change the POST in GET is works fine, but I want to use the POST (later in the website I use complex types).
Anyone a brilliant idea?
This problem is caused by the secure environment (https).
I put the website on a normal environment (http) and it works flawless ;)
Thanx for you're time.
decorate the ActionResult with HttpPost
[HttpPost]
public ActionResult Registration(string radio, string overig){ ... }

Resources