Reputation: 2725
Can't seem to figure this one out, regardless of what I do (looked at other stackoverflow issues). New to Spring, and trying to understand the system in more detail as I go.
The 'UserBean' I created along-with 'UserController' and 'newUserForm.jsp' is a small replica of 'FormBean', 'formController', and 'form.jsp' that was already in-place for the sample app. The sample app itself can be obtained from: http://www.infoq.com/presentations/Mastering-Spring-MVC-3
Here is UserBean.java package org.springframework.web.app.user;
import org.hibernate.validator.constraints.NotEmpty;
/**
* Created by apil.tamang on 1/12/16.
*/
public class UserBean {
@NotEmpty
private String firstName;
@NotEmpty
private String lastName;
@NotEmpty
private String email;
public UserBean(){
}
public UserBean(String firstName, String lastName, String email) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
@Override
public String toString() {
return "UserBean[" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
']';
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Here is the 'UserController.java' controller file:
package org.springframework.web.app.user;
import org.springframework.mvc.extensions.ajax.AjaxUtils;
import org.springframework.samples.mvc.form.FormBean;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.validation.Valid;
/**
* Created by apil.tamang on 1/12/16.
*/
@Controller
@RequestMapping("/user")
@SessionAttributes("userBean")
public class UserController {
@ModelAttribute
public void ajaxAttribute(WebRequest request, Model model) {
model.addAttribute("ajaxRequest", AjaxUtils.isAjaxRequest(request));
}
@ModelAttribute("userBean")
public UserBean createFormBean() {
return new UserBean();
}
@RequestMapping(method=RequestMethod.GET)
public void user() {
}
@RequestMapping(method=RequestMethod.POST)
public String processSubmitNewUser(@ModelAttribute("userBean") UserBean userBean,
@ModelAttribute("ajaxRequest") boolean ajaxRequest,
Model model, RedirectAttributes redirectAttributes){
String message="User data received. User details: "+userBean.toString();
if(ajaxRequest){
//prepare model for rendering success message in this request
model.addAttribute("message",message);
return null;
}else{
//store success message for rendering on the next request after redirect.
return "redirect:/user";
}
}
}
And here's the newUserForm.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ page session="false" %>
<c:if test="${!ajaxRequest}">
<html>
<head>
<title> Title of New User form.</title>
<link href="<c:url value="/resources/form.css" />" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="<c:url value="/resources/jquery/1.6/jquery.js" />"></script>
</head>
<body>
</c:if>
<div id="formsContent">
<%-- Wonder why the modelAttribute is needed! Probably to bind form
parameters to UserBean parameters --%>
<form:form id="newUserForm" method="POST" modelAttribute="userBean" cssClass="cleanform" action="/user/add">
<div class="header">
<h2> New User Form </h2>
<c:if test="${not empty message}">
<div id="message" class="success">${message}</div>
</c:if>
</div>
<fieldset>
<legend> Personal Info </legend>
<form:label path="firstName">
First Name
</form:label>
<form:input path="firstName"/>
<form:label path="lastName">
First Name
</form:label>
<form:input path="lastName"/>
<form:label path="email">
First Name
</form:label>
<form:input path="email"/>
</fieldset>
</form:form>
<script type="text/javascript">
$(document).ready(function(){
$("#newUserForm").submit(function(){
$.post(
$(this).attr("action"),
$(this.serialize(),
function(html){
$("$formsContent").replaceWith(html);
$('html,body').animate({
scrollTop: $('#message').offset().top
},500);
return false;
}
);
});
});
</script>
</div>
<c:if test="${!ajaxRequest}">
</body>
</html>
</c:if>
The following is the stack-trace in the browser:
type Exception report
message An exception occurred processing JSP page /WEB-INF/views/newUserForm.jsp at line 31
description The server encountered an internal error that prevented it from fulfilling this request.
exception
org.apache.jasper.JasperException: An exception occurred processing JSP page /WEB-INF/views/newUserForm.jsp at line 31
28: <fieldset>
29: <legend> Personal Info </legend>
30:
31: <form:label path="firstName">
32: First Name
33: </form:label>
34: <form:input path="firstName"/>
Stacktrace:
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:568)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:465)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:168)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1244)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:96)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
root cause
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'userBean' available as request attribute
org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:144)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:168)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:188)
org.springframework.web.servlet.tags.form.LabelTag.autogenerateFor(LabelTag.java:130)
org.springframework.web.servlet.tags.form.LabelTag.resolveFor(LabelTag.java:120)
org.springframework.web.servlet.tags.form.LabelTag.writeTagContent(LabelTag.java:90)
org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:84)
And to note, the following line was added to controller.xml to direct calls to /user to /newUserForm.jsp
<mvc:view-controller path="/user" view-name="newUserForm"/>
What is going on? I figure it must have to do something with modelAttribute="userBean" declared in the jsp file, but I couldn't be sure. Spent the last hour trying to figure it out, while realizing that an equivalent structure created for 'formBean' works just fine! Any help is welcome.
Upvotes: 2
Views: 838
Reputation: 1643
The problem is that your "UserController.java" is not picking by the spring.
Add the package name for Scanning in controllers.xml, like this:
<context:component-scan base-package="org.springframework.samples.mvc org.springframework.web.app.user" />
Or change the package name of org.springframework.web.app.user to org.springframework.samples.mvc.web.app.user
In UserController.Java return the form you want to load ie "newUserForm.jsp" like this:
@RequestMapping(method = RequestMethod.GET)
public String user() {
return "newUserForm";
}
Upvotes: 1