简体   繁体   中英

Spring webapp form field value always returns null

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?

ContactForm.java

public class ContactForm {

    private String bodyOfEmail;

    // accessors

}

ContactValidator.java

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<ObjectError> 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<FieldError>  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");
    }

}

ContactController.java

@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!");    // <-- 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
    }
}

servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans ...>

  <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

  <!-- Scans within the base package of the application for @Components to configure as beans -->
  <!-- @Controller, @Service, @Configuration, etc. -->
  <context:component-scan base-package="skincare.web"/>

  <!--Enables many annotations and searches for @Controller annotated methods etc.. -->
  <context:annotation-config />

  <!--JSR-303 (Bean validation) support will be detected on classpath and enabled automatically-->
  <mvc:annotation-driven />

  <bean id="mailSender"                       class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host"                     value="localhost" />
    <property name="port"                     value="25" />
  </bean>

  <!-- forms -->
  <bean name="creditCardBrandForm"            class="skincare.web.model.CreditCardBrandForm" />
  <bean name="creditCardForm"                 class="skincare.web.model.CreditCardForm" />
  <bean name="contactForm"                    class="skincare.web.model.ContactForm" />

  <!-- validators -->   
  <bean name="creditCardBrandValidator"       class="skincare.web.validator.CreditCardBrandValidator" />

  <bean name="creditCardValidator"            class="skincare.web.validator.CreditCardValidator" >
    <property name="creditCardBrandService"   ref="creditCardBrandService" />
  </bean>

  <bean name="contactValidator"               class="skincare.web.validator.ContactValidator" />

  <!-- controllers -->      
  <bean id="homeController"                   class="skincare.web.controller.HomeController" />

  <bean id="creditCardBrandController"        class="skincare.web.controller.CreditCardBrandController">
    <property name="creditCardBrandService"   ref="creditCardBrandService" />
    <property name="creditCardBrandValidator" ref="creditCardBrandValidator" />
  </bean>

  <bean id="creditCardController"             class="skincare.web.controller.CreditCardController">
    <property name="creditCardBrandService"   ref="creditCardBrandService" />
    <property name="creditCardService"        ref="creditCardService" />
    <property name="creditCardValidator"      ref="creditCardValidator" />
  </bean>

  <bean id="contactController"                class="skincare.web.controller.ContactController">
    <property name="contactValidator"         ref="contactValidator" />
    <property name="fromAddr"                 value="nobody@reply.org" />
    <property name="toAddr"                   value="prez@whitehouse.gov" />
    <property name="subjectOfEmail"           value="a msg from a concerned citizen" />
    <property name="mailSender"               ref="mailSender" />
  </bean>

  <!-- resolvers -->  
  <bean id="jspViewResolver"   class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
  </bean>

  <bean id="messageSource"     class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basename" value="customMessages"/>  <!-- in src/main/resources -->
  </bean>

</beans>

contact.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c"      uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt"    uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form"   uri="http://www.springframework.org/tags/form" %>
<html>
<style>
.error {
    color: #ff0000;
}
</style>
<head>
  <title>Contact</title>
</head>
<body>
  <h1>What is your concern?</h1>
  <form:form modelAttribute="contactForm" method="post">
 <!--   <form:errors path="*" cssClass="errorblock" element="div" />  -->
    <table>
      <tr>
        <td><form:label  path="bodyOfEmail"> bodyOfEmail: </form:label></td>
        <td><form:input  path="bodyOfEmail" /></td>
        <td><form:errors path="bodyOfEmail" cssClass="error" /></td>
      </tr>
      <tr>
        <td><input type="submit" value="Send" /></td>
      </tr>
    </table>
  </form:form>
  <br>
</body>
</html>

So can anyone spot where I've gone wrong?

TIA,

Still-learning Steve

Once I had the problem, I found that encoding defined in my form tag which created the problem. I removed it and now I am able to retrieve values from the input elements in JSP at controller

It was :

<form:form  name="searchForm" modelAttribute="newRequest" class="form-horizontal" method="post" enctype="multipart/form-data">

I changed to below and am able to retrieve the values..

 <form:form  name="searchForm" modelAttribute="newRequest" class="form-horizontal" method="post" >

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM