Note that there are some explanatory texts on larger screens.

plurals
  1. POSpring webapp form field value always returns null
    primarykey
    data
    text
    <p>I'm pulling out what little hair I have left over this simple problem: I've built a Maven/Java7/Spring3/MySQL/Tomcat webapp that compiles and deploys. My credit card brand and credit card forms/validators/controllers work flawlessly for inserting rows into their respective tables. But my contact form gets displayed but the value returned for bodyOfEmail is always null. It must be some fiendishly subtle spelling error or configuration error but I can't spot it - can anyone else shed some light on this?</p> <p>ContactForm.java</p> <pre class="lang-java prettyprint-override"><code>public class ContactForm { private String bodyOfEmail; // accessors } </code></pre> <p>ContactValidator.java</p> <pre class="lang-java prettyprint-override"><code>public class ContactValidator implements Validator { private static final Logger logger = Logger.getLogger( ContactValidator.class); //constructors public ContactValidator() {} //stuff public boolean supports(Class candidate) { return ContactForm.class.isAssignableFrom(candidate); } public void validate(Object obj, Errors errors) { logger.debug("entering"); ContactForm form = (ContactForm) obj; if( errors.hasErrors() ) { // could be a data binding error, could be all sorts of things logger.debug( "number of errors found:" + errors.getErrorCount()); if( errors.hasGlobalErrors()) { logger.debug( " number of global errors found:" + errors.getGlobalErrorCount()); java.util.List&lt;ObjectError&gt; globalErrorList = errors.getGlobalErrors(); ListIterator gelIter = globalErrorList.listIterator(); while( gelIter.hasNext()) { logger.debug( " gel:" + gelIter.next().toString()); } } if( errors.hasFieldErrors()) { logger.debug( " number of field errors found:" + errors.getFieldErrorCount()); java.util.List&lt;FieldError&gt; fieldErrorList = errors.getFieldErrors(); ListIterator felIter = fieldErrorList.listIterator(); while( felIter.hasNext()) { logger.debug( " fel:" + felIter.next().toString()); } } } else { //no basic field errors detected, now apply business logic validation // validate textarea field String naughtyChars = "xxxx"; if( form.getBodyOfEmail().matches(naughtyChars)) { errors.rejectValue("bodyOfEmail", "validation.negative", "bodyOfEmail contains naughty characters"); } } logger.debug("exiting normally"); } } </code></pre> <p>ContactController.java</p> <pre class="lang-java prettyprint-override"><code>@RequestMapping(value="/contact") @Controller public class ContactController { private static final Logger logger = Logger.getLogger(ContactController.class); ContactValidator contactValidator; // comes in from bean private String fromAddr; // these all come in from bean private String toAddr; private String subjectOfEmail; JavaMailSender mailSender; //getters and setters public ContactValidator getContactValidator() { return contactValidator; } public void setContactValidator(ContactValidator contactValidator) { this.contactValidator = contactValidator; } public String getFromAddr() { return fromAddr; } public void setFromAddr(String fromAddr) { this.fromAddr = fromAddr; } public String getToAddr() { return toAddr; } public void setToAddr(String toAddr) { this.toAddr = toAddr; } public String getSubjectOfEmail() { return subjectOfEmail; } public void setSubjectOfEmail(String subjectOfEmail) { this.subjectOfEmail = subjectOfEmail; } public JavaMailSender getMailSender() { return mailSender; } public void setMailSender(JavaMailSender mailSender) { this.mailSender = mailSender; } //stuff @RequestMapping( method=RequestMethod.GET) // home path public String displayContactForm( ModelMap model) { logger.debug("entering"); model.addAttribute( "contactForm", new ContactForm()); logger.debug("exiting normally"); return "contact"; // maps to /WEB-INF/views/index } @RequestMapping( method=RequestMethod.POST) // home path public String processContactForm( @ModelAttribute("contactForm") @Valid ContactForm contactForm, BindingResult result) { logger.debug("entering"); String boody = contactForm.getBodyOfEmail(); if( boody == null) { logger.debug("body of email is null, bad!"); // &lt;-- this is the problem System.out.println("body of email is null, bad!"); } contactValidator.validate( contactForm, result); if( result.hasErrors()) { //binding and/or validation failed on one or more fields, re-display form with errmsgs showing logger.debug( "VALIDATE FOUND ERRORS"); logger.debug( result.toString()); return "contactFailed"; } SimpleMailMessage message = new SimpleMailMessage(); message.setFrom( this.getFromAddr()); message.setTo( this.getToAddr()); message.setSubject( this.getSubjectOfEmail()); message.setText( contactForm.getBodyOfEmail()); // message.setText( "forced in"); try{ this.mailSender.send(message); } catch( MailException ex) { //log it and go on logger.debug( "MAIL BROKEN"); logger.debug( ex.getMessage()); return "contactFailed"; } logger.debug("exiting normally"); return "contactSent"; // maps to /WEB-INF/views/index } } </code></pre> <p>servlet-context.xml</p> <pre class="lang-xml prettyprint-override"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;beans ...&gt; &lt;!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure --&gt; &lt;!-- Scans within the base package of the application for @Components to configure as beans --&gt; &lt;!-- @Controller, @Service, @Configuration, etc. --&gt; &lt;context:component-scan base-package="skincare.web"/&gt; &lt;!--Enables many annotations and searches for @Controller annotated methods etc.. --&gt; &lt;context:annotation-config /&gt; &lt;!--JSR-303 (Bean validation) support will be detected on classpath and enabled automatically--&gt; &lt;mvc:annotation-driven /&gt; &lt;bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"&gt; &lt;property name="host" value="localhost" /&gt; &lt;property name="port" value="25" /&gt; &lt;/bean&gt; &lt;!-- forms --&gt; &lt;bean name="creditCardBrandForm" class="skincare.web.model.CreditCardBrandForm" /&gt; &lt;bean name="creditCardForm" class="skincare.web.model.CreditCardForm" /&gt; &lt;bean name="contactForm" class="skincare.web.model.ContactForm" /&gt; &lt;!-- validators --&gt; &lt;bean name="creditCardBrandValidator" class="skincare.web.validator.CreditCardBrandValidator" /&gt; &lt;bean name="creditCardValidator" class="skincare.web.validator.CreditCardValidator" &gt; &lt;property name="creditCardBrandService" ref="creditCardBrandService" /&gt; &lt;/bean&gt; &lt;bean name="contactValidator" class="skincare.web.validator.ContactValidator" /&gt; &lt;!-- controllers --&gt; &lt;bean id="homeController" class="skincare.web.controller.HomeController" /&gt; &lt;bean id="creditCardBrandController" class="skincare.web.controller.CreditCardBrandController"&gt; &lt;property name="creditCardBrandService" ref="creditCardBrandService" /&gt; &lt;property name="creditCardBrandValidator" ref="creditCardBrandValidator" /&gt; &lt;/bean&gt; &lt;bean id="creditCardController" class="skincare.web.controller.CreditCardController"&gt; &lt;property name="creditCardBrandService" ref="creditCardBrandService" /&gt; &lt;property name="creditCardService" ref="creditCardService" /&gt; &lt;property name="creditCardValidator" ref="creditCardValidator" /&gt; &lt;/bean&gt; &lt;bean id="contactController" class="skincare.web.controller.ContactController"&gt; &lt;property name="contactValidator" ref="contactValidator" /&gt; &lt;property name="fromAddr" value="nobody@reply.org" /&gt; &lt;property name="toAddr" value="prez@whitehouse.gov" /&gt; &lt;property name="subjectOfEmail" value="a msg from a concerned citizen" /&gt; &lt;property name="mailSender" ref="mailSender" /&gt; &lt;/bean&gt; &lt;!-- resolvers --&gt; &lt;bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"&gt; &lt;property name="prefix" value="/WEB-INF/views/" /&gt; &lt;property name="suffix" value=".jsp" /&gt; &lt;/bean&gt; &lt;bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"&gt; &lt;property name="basename" value="customMessages"/&gt; &lt;!-- in src/main/resources --&gt; &lt;/bean&gt; &lt;/beans&gt; </code></pre> <p>contact.jsp</p> <pre class="lang-xml prettyprint-override"><code>&lt;%@ page contentType="text/html;charset=UTF-8" language="java" %&gt; &lt;%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %&gt; &lt;%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %&gt; &lt;%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %&gt; &lt;%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %&gt; &lt;html&gt; &lt;style&gt; .error { color: #ff0000; } &lt;/style&gt; &lt;head&gt; &lt;title&gt;Contact&lt;/title&gt; &lt;/head&gt; &lt;body&gt; &lt;h1&gt;What is your concern?&lt;/h1&gt; &lt;form:form modelAttribute="contactForm" method="post"&gt; &lt;!-- &lt;form:errors path="*" cssClass="errorblock" element="div" /&gt; --&gt; &lt;table&gt; &lt;tr&gt; &lt;td&gt;&lt;form:label path="bodyOfEmail"&gt; bodyOfEmail: &lt;/form:label&gt;&lt;/td&gt; &lt;td&gt;&lt;form:input path="bodyOfEmail" /&gt;&lt;/td&gt; &lt;td&gt;&lt;form:errors path="bodyOfEmail" cssClass="error" /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;input type="submit" value="Send" /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/table&gt; &lt;/form:form&gt; &lt;br&gt; &lt;/body&gt; &lt;/html&gt; </code></pre> <p>So can anyone spot where I've gone wrong?</p> <p>TIA,</p> <p>Still-learning Steve</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload