4 votes

La valeur d'un formulaire Spring MVC est toujours nulle

Je suis nouveau dans le domaine de Spring MVC, mais pas dans celui du développement web en Java. J'essaie de créer un exemple simple de formulaire->contrôleur.

J'ai un formulaire, un contrôleur de formulaire (configuré dans un contexte XML collé ci-dessous) et mon modèle (un simple bean). Lorsque je soumets le formulaire, la valeur de mon entrée de texte est toujours nulle, peu importe. Avez-vous une idée ?

Configuration du ressort du contrôleur de forme :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- controllers -->

    <bean name="/home.html" class="atc.web.view.controller.HomeController" />

    <!--bean name="/mirror.html" class="atc.web.view.controller.MirrorController" -->

    <bean name="/url-cache.html" class="atc.web.view.controller.URLCacheFormController">
        <property name="synchronizeOnSession" value="true" />
        <!--property name="sessionForm" value="false"-->
        <property name="commandName" value="urlForm"/>
        <property name="commandClass" value="atc.web.view.model.URLBean"/>
        <property name="validator">
            <bean class="atc.web.view.validators.URLValidator"/>
        </property>
        <property name="formView" value="mirror"/>
        <property name="successView" value="url-cache.html"/>
        <property name="URLCachingService" ref="urlCachingService" />
    </bean>

    <!-- end controllers -->

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- custom beans -->

    <bean id="breakcrumbInjectionFilter" class="atc.web.view.filter.BreadcrumbInjectionFilter">
        <property name="contextPrefix" value="/home-web" />
    </bean>

    <!-- end custom beans -->
</beans>

La JSP qui contient mon formulaire est la suivante :

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="/WEB-INF/jspf/core/taglibs.jspf" %>
<html>
<head><title>Simple tools</title></head>
<style>
.error s {
    color:#FF0000;
}
</style>
<body>
<%@ include file="/WEB-INF/jspf/nav/nav.jspf" %>
    Errors: <form:errors path="url" cssClass="error"/>
    <form:form method="post" commandName="urlForm">
        <form:input path="url" />
        <input type="submit" align="center" value="Execute" />
    </form:form>
</body>
</html>

Voici la source complète de mon contrôleur :

public class URLCacheFormController extends SimpleFormController {
    private URLCachingService cachingService;

    private static Logger log = Logger.getLogger(URLCacheFormController.class);

    public ModelAndView onSubmit(Object command) throws ServletException {
        log.debug(String.format("URLCachingFormController received request with object '%s'", command));
        URLBean urlBean = (URLBean) command;
        try {
            URL url = new URL(urlBean.getUrl());
            URLCache cache = cachingService.cacheURL(url);
            cache.cacheToTempFile();

        } catch (IOException e) {
            log.error("Invalid URL...", e);
        }
        return new ModelAndView(new RedirectView(getSuccessView()));
    }

    protected Object formBackingObject(HttpServletRequest request) throws ServletException {
        log.debug("formBackingObject() ");
        return new URLBean();
    }

    public void setURLCachingService(URLCachingService cachingService) {
        this.cachingService = cachingService;
    }
}

Tout ce qui précède produit le HTML suivant :

<html>
<head></head>
<body>
<div><span><a href="home.html">Home </a></span><span> | <a href="url-cache.html">Page Mirror</a></span></div>
<div id="breadcrumb"><span>Your trail:<a href=""/></span></div>Attrs:<div/>
<form id="urlForm" method="post" action="/home-web/url-cache.html">
<input id="url" type="text" value="" name="url"/>
<input type="submit" align="center" value="Execute"/>
</form>
</body>
</html>

Je remplace maintenant doSubmitAction(Object command) mais je ne trouve toujours pas la méthode. Le formulaire est soumis, mais l'instant d'après, je me retrouve avec un formulaire vierge (après formBackingObject(HttpServletRequest request) est appelé).

C'est-à-dire que lorsque je soumets, l'appel de journalisation sur la ligne 1 de doSubmitAction dans le contrôleur de formulaire n'est jamais exécuté. Le validateur s'exécute et échoue (il ajoute correctement les messages d'erreur) parce que la valeur qu'il vérifie est toujours nulle. (ou, plus exactement, elle n'est jamais fixée). . L'appel à formBackingObject se produit cependant toujours. L'attribut request de mon formulaire (l'entrée 'url' du formulaire) est toujours nul.

Mise à jour : OK, donc après un débogage sérieux comme suggéré par serg555, et la suppression de la validation, je peux confirmer que le problème semble être avec le mappage des paramètres de la demande - comme la valeur de "url" du formulaire - à ma commande/bean ; c'est-à-dire que l'URL n'est jamais défini sur mon bean, ou le bean est recréé.

Veuillez m'aider.

2voto

serg Points 43893

Je ne sais pas où est le problème, laissez-moi vous montrer mon contrôleur qui fonctionne et peut-être que vous serez en mesure de comprendre ce qui ne va pas :

public class TestController extends SimpleFormController  {

    public TestController () {
        setFormView("testView");
        setSuccessView("testView");
        setCommandClass(TestCmd.class);
        setCommandName("cmd");
    }

    protected Object formBackingObject(HttpServletRequest request)throws Exception {
        Object o = super.formBackingObject(request);
        TestCmd cmd = (TestCmd) o;

        return cmd;
    }

    public ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object obj, BindException errors) throws Exception {

        TestCmd cmd = (TestCmd) obj;

        log.debug("test value = " + cmd.getTestValue());

        return super.onSubmit(request, response, obj, errors);
    }

}

Forme :

<form method="post" action="/test.html">
    <form:input path="cmd.testValue"/>
    <input type="submit">
</form>

Dans App-servlet.xml :

    <bean id="urlMapping"
        class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="alwaysUseFullPath" value="true" />
        <property name="mappings">
            <props>
                <prop key="/test.html">testController</prop>
            </props>
        </property>
    </bean>
    <bean id="testController"
        class="com.sample.TestController">
        <property name="synchronizeOnSession" value="true" />
        <property name="validator">
            <bean class="com.sample.TestValidator"/>
        </property>
    </bean>

Valideur :

public class TestValidator implements Validator {

    public boolean supports(Class clazz) {
        return (TestCmd.class.equals(clazz));
    }

    public void validate(Object obj, Errors errors) {
        TestCmd cmd = (TestCmd) obj;
        if (obj == null) {
            // nothing
        } else {

            ValidationUtils.rejectIfEmptyOrWhitespace(errors, "testValue", null, "<b>Value</b> is required");

        }
    }

}

Commandement :

public class TestCmd {

    private String testValue;

    public TestCmd() {
    }

    public String getTestValue() {
        return testValue;
    }

    public void setTestValue(String testValue) {
        this.testValue = testValue;
    }

}

1voto

Jacob Mattison Points 32137

OK, vous avez vérifié qu'une url définie dans le contrôleur est bien transmise à la JSP, ce qui suggère que le mappage est correct vers le bean de commande.

Une dernière chose. Si le code "onSubmit" n'est jamais atteint, il se peut que le contrôleur ait un problème pour déterminer s'il s'agit d'une soumission de formulaire. Il pourrait être utile d'ajouter un attribut de nom au bouton submit, et de remplacer "isFormSubmission" pour vérifier si ce nom est présent (c'est-à-dire si le bouton submit a été cliqué). Si c'est le cas, isFormSubmission devrait retourner true. (Cela ne devrait pas être nécessaire -- par défaut, le contrôleur suppose que toute requête POST est une soumission de formulaire -- mais si cela aide, vous en saurez plus sur le problème, et vous aurez une solution de contournement, au moins).

1voto

atc Points 1553

La cause était le fait que mon form bean n'adhérait pas au contrat Java Bean - le setter retournait au lieu d'être void et ne pouvait donc pas être apparié par Spring pour être invoqué.

0voto

HVT7 Points 31

Essayez de mettre le code suivant dans le fichier aplication-context.xml. Cela pourrait être votre solution si vous avez votre formulaire encType=multipart/form-data.

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10000000"/>
</bean>

Essayez également de supprimer le type de contenu de la page jsp. Dans mon cas, cela m'a aidé... !

0voto

naXa Points 862

J'ai déjà passé beaucoup de temps à enquêter sur un problème similaire. J'ai finalement trouvé le coupable dans la méthode d'initialisation d'un Binder :

@InitBinder
void allowFields(final WebDataBinder binder) {
    binder.setAllowedFields("name");
}

Cette méthode définit une restriction sur les champs qui sont autorisés à être liés. Tous les autres champs restent non liés, ce qui se traduit naturellement par null valeurs.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X