Path on spring form select not working - java

I am having an issue getting the jsp to render properly. The path on my select tag seems to be the culprit, but I cannot track don't why.
I get the error: Error 500: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute
And my code is:
Controller.java
#Controller
#RequestMapping("view")
#SessionAttributes({"analyticFormBean"})
public class RolesAnalyticsController {
#RenderMapping
public String defaultRenderer(RenderRequest request, RenderResponse response, ModelMap map){
logger.entering(SOURCE_CLASS, "defaultRenderer");
request.setAttribute("reportList", getReportList());
logger.exiting(SOURCE_CLASS, "defaultRenderer", VIEW_JSP);
return VIEW_JSP;
}
View.jsp
<form:form id="reportForm" method="POST" action="${submitReportQuery}">
<form:select path="query" id="reportSelection" onchange="javascript:checkForFields()">
<form:option value="NONE" label="--- Select ---"/>
<form:options items="${reportList}" />
</form:select>
<input type="submit" value="Submit" name="Submit" ><br>
<div class="fieldPlaceholder" id="fieldPlaceholder"></div>
Bean.java
public class AnalyticFormBean {
private int reportID;
private String query;
private String queryResult;
private String[] listOfQueries;

You're missing two things,
the backing bean has to be actually added to the ModelMap at some point, so you need a map.addAttribute("analyticFormBean", new AnalyticFormBean()) (or with whatever initial values you want added to it, etc.)
You have to tell the form tag the name of the backing object <form:form commandName="analyticFormBean" etc>

I dont see you using the bean in the form... you need to add it to the form.
<form:form commandName="analyticFormBean" .......>

Related

using search functionality in thymeleaf with request parameters

I have a page where I get a list of entries. Now, I want to be able to search from those list.
my current url for retrieving list is this /show/products. I want to add a search form in this page so that I can search with request parameter.
Yes, I can use ajax but I have to do it with request parameters.
So if I search for a product name, then - /show/products?name=someName
<form ui-jp="parsley" th:action="#{/show/products(name=${pName})}" th:object="${pName}" method="get">
<div class="row m-b">
<div class="col-sm-6">
Search by Name:
<input id="filter" type="text" th:field="*{pName}" class="form-control input-sm w-auto inline m-r"/>
<button class="md-btn md-fab m-b-sm indigo">
<i class="material-icons md-24"></i>
</button>
</div>
</div>
</form>
And this is what I tried in controller:
#GetMapping("/show/products")
public String getProduct(Model model,
#RequestParam(required = false) String name,
#ModelAttribute String pName) {
List<Product> products = this.productService.getAllProducts(name)
model.addAttribute("products", products);
return "show_product";
}
I am getting this error:
Neither BindingResult nor plain target object for bean name 'pName' available as request attribute
at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:153)
at org.springframework.web.servlet.support.RequestContext.getBindStatus(RequestContext.java:897)
You are trying to use variable pName (Model attribute) as a form object.
In your view you are passing a model attribute to form like this th:object="${pName}" but instead you need to pass a form object.
A form object is not a class but rather a simple java object (POJO). You can think of form object as your form but on server side.
Before you can use form object in your view, you need to create it and add it to the Model.
you will define it like this
public class MyFormObject{
private String pName;
public String getPName(){
return pName;
}
public void setPName(String pName){
this.pName = pName;
}
}
now your controller method will become
#GetMapping("/show/products")
public String getProduct(Model model,
#ModelAttribute("myFormObject") MyFormObject myFormObject,
BindingResult result) {
List<Product> products = this.productService.getAllProducts(myFormObject.getPName());
model.addAttribute("products", products);
return "show_product";
}
Then you can pass the form object to your form like this
<form ui-jp="parsley" th:action="#{/show/products}" th:object="${myFormObject}" method="get">
<div class="row m-b">
<div class="col-sm-6">
Search by Name: <input id="filter" type="text" th:field="*{pName}" class="form-control input-sm w-auto inline m-r"/>
<button class="md-btn md-fab m-b-sm indigo"><i class="material-icons md-24"></i></button>
</div>
</div>
</form>
You need to read the documentation, all these are explained there in detail.

How to add validation to a spring boot java form

I currently have the following method within my controller that takes the users form input and passes it to an SQL query to return a list of matches.
#RequestMapping(value = "/resultsPage", method = RequestMethod.GET)
public ModelAndView newSearch(HttpServletRequest request)
{
int id = Integer.parseInt(request.getParameter("id"));
List<newobject> listSearch = newDAO.loadSearch(id);
ModelAndView model = new ModelAndView("results");
model.addObject("listSearch", listSearch);
return model;
}
I have added #NotNull to the ID filed in the newObject however I am unsure on how to modify my method above to check the variable entered (or not entered) by the user.
I am also unsure how to display the error on the html page. My existing code is below:
<form method="get" th:action="#{/results}">
<input id="search" name="id" class="search" placeholder="Ref..."
type="text" maxlength="10" title="Numerical values only" />
<button type="submit" method="post" style="display:none;" id="search">Search</button>
</form>
Can anyone give me some advice on how I would add the validation as I am just getting errors with everything I try.

how to show fetched values from database in spring <form:input>?

I need to show the fetched values from database which are stored in an arraylist using spring form:input tag. However i found that the 'value' attribute isn't supported. Please help!
I guess you are expecting something like this.
//Assumes you have the following in your class
public class Students{
private String name;
private List<String> Departments;
/* getters/setters */
}
In the HTML would be.
<form:input path="departments[0]" />
<form:input path="departments[1]" />
For more details about click http://www.javacodegeeks.com/2013/07/spring-mvc-form-handling-vol-5-select-option-options-tags.html
Please first retrieve the list from the datebase and set the list on the model attribute in the controller see the example set the
#Controller
public class UserController {
#RequestMapping(method = RequestMethod.GET)
public String userHome(Model model, EventBean event, UserService userService,ImageBean image)
{
List<Event> events = userService.viewNews(); //retrieve the list from datebase
model.addAttribute("event", event); //add bean object
model.addAttribute("events", events); //add list in model attribute
return "home";
}
}
your jsp page
<form:form modelAttribute="event"> <!--set the model attribute here -->
<form:input path="news" value="${events.get(0).news}" />
</form:form>
This is my code,please have a look and say what i might be doing wrong,
JAVA
public ModelAndView userEditProfile(#ModelAttribute("userDetails") UserFormbean registration,BindingResult result,HttpServletRequest request){
ModelAndView mav=null;
HttpSession httpSession=null;
List userProfileList=new ArrayList();
httpSession=request.getSession();
if (httpSession != null) {
UserFormbean formbean=(UserFormbean)httpSession.getAttribute("UserRegistrationFormBean");
userProfileList= userRegistrationService.getUserProfileInfo(formbean);
mav=new ModelAndView("EditProfile");
mav.addObject("userProfileInfoList", userProfileList);
}
return mav;
}
JSP::
-----
<c:if test="${not empty userProfileInfoList}">
<c:forEach var="temp" items="${userProfileInfoList}">
<div>
<form:label path="userRegistration.email"><spring:message code="label.email"/></form:label>
<form:input path ="userRegistration.email" value="${temp.get(0).UserRegistration.email}"/>
<form:errors path="userRegistration.email"/>
</div>
<div>
<form:label path="userRegistration.firstName"><spring:message code="label.firstname"/></form:label>
<form:input path ="userRegistration.firstName" value="${temp.get(0).UserRegistration.firstName}"/>
<form:errors path="userRegistration.firstName"/>
</div>
<div>
<form:label path="userRegistration.lastName"><spring:message code="label.lastname"/></form:label>
<form:input path ="userRegistration.lastName" value="${temp.get(0).UserRegistration.lastName}"/>
<form:errors path="userRegistration.lastName"/>
</div>
</c:forEach>
</c:if>

Binding problems using Spring MVC

I am using Spring MVC 3.1 to develop a Java web app. I have a JSP that has two paired radio buttons, an entry field, and a dropdown select box. I need these values to be available to my mapped controller, via a model class' fields.
The security and URL mapping works fine, as I've seen in debugger before. The issue is that when I tried to get the JSP data values populating my model, I get an error:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'cccForm' available as request attribute
Here is part of my JSP:
<c:url var="cccUrl" value="/registers/default/ccPreauth/authorize" />
<div class="mainWrapper">
<form:form id="cccForm" action="${cccUrl}" method="post" modelAttribute="cccForm">
...
<table>
<tbody>
<tr>
<th>Select an option.</th>
</tr>
<tr>
<td>
<div class="field-input">
<form:radiobutton id="paymentOption" path="paymentOption" value="authorizeCC" />
Collect Credit Card Information
</div>
<div class="field-input">
Authorization Amount $
<form:input path="authAmount" maxlength="10" size="10" class="extendWidth"/>
<span class="instructions">
<spring:message code="label.authorization.note" />
</span>
</div>
<div class="field-input">
<form:radiobutton id="paymentOption" path="paymentOption" value="cancelAuth" />
Choose a Reason and Cancel Credit Card Collection
</div>
<div class="field-input right">
<form:select id="selectedReason" path="selectedReason" >
<c:forEach items="${reasonList}" var="reason">
<option value=${reason.reasonText}>${reason.reasonText}</option>
<br />
</c:forEach>
</form:select>
</div></td>
</tr>
</tbody>
</table>
</div>
<div class="right">
<button class="btnBlue" id="submitButton" type="submit">
Here is part of my controller:
#Controller
#RequestMapping(value = "/registers/default/ccPreauth")
#SessionAttributes(ControllerConstants.DEFAULT_REGISTER_ATTR_NM)
public class CCCaptureController {
...
#RequestMapping(value="/authorize" )
public ModelAndView authorize(
final Authentication auth,
final #ModelAttribute("ccCapturePaymentRequest") CCCapturePaymentForm ccCapturePaymentRequest,
final BindingResult result,
final HttpServletResponse response) {
final ModelAndView mav = new ModelAndView(CC_PREAUTH_PAYMENT_VIEW);
return mav;
}
and finally, here is my model class:
public class CCCapturePaymentForm implements Serializable {
private static final long serialVersionUID = 6839171190322687142L;
#NumberFormat(style = Style.CURRENCY)
private BigDecimal authAmount;
private String selectedReason;
private String paymentOption;
public BigDecimal getAuthAmount() {
return authAmount;
}
public void setAuthAmount(BigDecimal authAmount) {
this.authAmount = authAmount;
}
public String getSelectedReason() {
return selectedReason;
}
public void setSelectedReason(String selectedReason) {
this.selectedReason = selectedReason;
}
public String getPaymentOption() {
return paymentOption;
}
public void setPaymentOption(String paymentOption) {
this.paymentOption = paymentOption;
}
}
Can anyone tell me what I need to get this to work correctly? Please don't stop at just the reason for the exception above - please verify and correct my code as I am on a tight schedule as usual and have little experience with Spring MVC. Thanks!
You have this in your form:
modelAttribute="cccForm"
So you should have this in your controller:
#ModelAttribute("cccForm") CCCapturePaymentForm ccCapturePaymentRequest
That's how you bind the form backing object with the model attribute.
I found the answer for those Spring MVC newbies...
I had to set the "cccForm" to a new instance of my next page's form inside the controller search method (that then tries to being up the page that was getting the error).
In a nutshell: I had to set the empty backing bean value in the preceding controller method so that the follow-on method and JSP page have it to work with.
Hope this helps someone else avoid my mistake.
Mark

Problems getting spring:bind status.errorMessage to populate

I've got a Groovy project using Spring framework and its validators doing sanity-checking on my forms' input values. I would like to have Spring populate error messages next to my input form fields via the built-in ${status.errorMessage}; however, I can only get it to populate "errorMessages" in my Model object (from the controller.) So let's take a look at some code.
login.jsp:
<form method="post" action="<c:url value="/login" />">
<spring:bind path="request.username">
<label for="username"><fmt:message key="login.username"/>:
<input type="text" id="username" size="20" maxlength="50" name="username" value="${request.username}"/>
</label>
<%-- This part does NOT display the validation errors. --%>
<c:if test="${status.error}"><span class="error">${status.errorMessage}</span></c:if>
</spring:bind>
<spring:bind path="request.password">
<label for="password"><fmt:message key="login.password"/>:
<input type="password" id="password" size="20" maxlength="30" name="password" />
</label>
<%-- This part does NOT display the validation errors. --%>
<c:if test="${status.error}"><span class="error">${status.errorMessage}</span></c:if>
</spring:bind>
<input id="login" type="submit" value="Login"/>
</form>
<%-- This part does display the validation errors. --%>
<c:if test="${ec > 0}">
<p>
<c:forEach items="${errorCodes}" var="error">
<span class="error"><fmt:message key="${error.defaultMessage}"/></span><br/>
</c:forEach>
</p>
</c:if>
LoginController.groovy:
#RequestMapping(method = RequestMethod.GET, value = '/')
ModelAndView defaultView() {
ModelMap model = new ModelMap()
model.addAttribute('request', new LoginRequest())
new ModelAndView('login', model)
}
#RequestMapping(method = RequestMethod.POST, value = '/login')
ModelAndView login(
LoginRequest loginRequest, HttpServletResponse response,
HttpSession session, BindingResult br, ModelMap model
) {
validator.validate(loginRequest, br)
if (br.hasErrors()) {
model.addAttribute('request', loginRequest)
return returnWithError(br, model, 'login')
}
...
}
private ModelAndView returnWithError(BindingResult br, ModelMap model, String redirectTo) {
br.allErrors.each {error ->
log.error(error.toString())
}
def objectErrors = br.allErrors.findAll {e -> e instanceof ObjectError}
model.addAttribute('ec', br.errorCount)
model.addAttribute('errorCodes', objectErrors)
new ModelAndView(redirectTo, model)
}
LoginRequestValidator.groovy:
#Override
void validate(Object o, Errors errors) {
ValidationUtils.rejectIfEmpty(errors, 'username', 'username.empty', 'username.empty')
ValidationUtils.rejectIfEmpty(errors, 'password', 'password.empty', 'password.empty')
}
Which part of the Spring Magic [TM] am I missing?
I think your BindingResult object should be the argument immediately following your LoginRequest object. See http://static.springsource.org/spring/docs/3.0.x/reference/mvc.html#mvc-ann-requestmapping and specifically Example 15.1. Invalid ordering of BindingResult and #ModelAttribute
Review the Javadoc on #RequestMapping as I find it the best on the subject:
http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/web/bind/annotation/RequestMapping.html
Try the following:
ModelAndView login(
#Valid LoginRequest loginRequest, HttpServletResponse response,
HttpSession session, BindingResult br, ModelMap model
) {}
See What does the #Valid annotation indicate in Spring?
If that doesn't work you should try translating some of your code to plain Java and running the debugger to see whats happening (I know its not an answer but just an idea).
Maybe you will find these post from kgiannakakis very usefull.
It explains the purpose of these functionnality and how to deal with is explained in Spring 3.1 documentation.
Adding something like that will probably do the trick, isn't it ?
#Controller
public class MyController {
#InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(new FooValidator());
}
#RequestMapping("/foo", method=RequestMethod.POST)
public void processFoo(#Valid Foo foo) { ... }
}
Take a look at SpringSource blog and especially these post about new features around data binding. It could add some new look about your validation process.

Categories

Resources