62 votes

Spring - Redirect après le POST (même avec des erreurs de validation)

Je suis à essayer de comprendre comment "conserver" le BindingResult de sorte qu'il peut être utilisé dans un OBTENIR via le Ressort <form:errors> balise. La raison pour laquelle je veux faire c'est à cause de Google App Engine SSL de limitations. J'ai un formulaire qui s'affiche via HTTP et le poste est à une URL HTTPS. Si je n'ai que de l'avant plutôt que de rediriger l'utilisateur serait de voir les https://whatever.appspot.com/my/form URL. J'essaie de l'éviter. Toutes les idées comment cette approche?

Ci-dessous est ce que j'aimerais faire, mais je ne vois que des erreurs de validation lorsque j'utilise return "create".

@RequestMapping(value = "/submit", method = RequestMethod.POST)
public final String submit(
    @ModelAttribute("register") @Valid final Register register,
    final BindingResult binding) {

    if (binding.hasErrors()) {
        return "redirect:/register/create";
    }

    return "redirect:/register/success";
}

70voto

Oscar Points 497

Depuis le Printemps 3.1 vous pouvez utiliser RedirectAttributes. Ajouter les attributs que vous souhaitez avoir à disposition avant de faire la redirection. Ajouter les deux, le BindingResult et l'objet que vous utilisez pour valider, dans ce Registre de cas.

Pour BindingResult vous allez utiliser le nom de: "org.springframework.la validation.BindingResult.[nom de votre ModelAttribute]".

Pour l'objet que vous utilisez pour valider, vous allez utiliser le nom de ModelAttribute.

Pour utiliser RedirectAttributes vous devez ajouter ceci dans votre fichier de configuration. Entre autres choses, vous dites de Printemps à l'utilisation de certaines nouvelles classes:

<mvc:annotation-driven />

Maintenant, les erreurs seront affichées partout où vous rediriger

@RequestMapping(value = "/submit", method = RequestMethod.POST)
public final String submit(@ModelAttribute("register") @Valid final Register register, final BindingResult binding, RedirectAttributes attr, HttpSession session) {

if (binding.hasErrors()) {
    attr.addFlashAttribute("org.springframework.validation.BindingResult.register", binding);
    attr.addFlashAttribute("register", register);
    return "redirect:/register/create";
}

return "redirect:/register/success";
}

58voto

Utku Özdemir Points 575

En plus de l'Oscar belle réponse, si vous êtes à la suivante qu' RedirectAttributes approche, n'oubliez pas que vous êtes réellement en passant l' modelAttribute de la redirection de la page. Cela signifie que si vous créez une nouvelle instance de cette modelAttribute pour la redirection de la page (dans un contrôleur de), vous perdrez les erreurs de validation. Donc, si votre POSTE de contrôleur de la méthode est quelque chose comme ceci:

@RequestMapping(value = "/submit", method = RequestMethod.POST)
public final String submit(@ModelAttribute("register") @Valid final Register register, final BindingResult binding, RedirectAttributes attr, HttpSession session) {

if (binding.hasErrors()) {
    attr.addFlashAttribute("org.springframework.validation.BindingResult.register", binding);
    attr.addFlashAttribute("register", register);
    return "redirect:/register/create";
}

return "redirect:/register/success";
}

Ensuite, vous aurez probablement besoin de faire une modification dans votre registre créer une page OBTENIR contrôleur. À partir de ceci:

@RequestMapping(value = "/register/create", method = RequestMethod.GET)
public String registerCreatePage(Model model) {
    // some stuff
    model.addAttribute("register", new Register());
    // some more stuff
}

pour

@RequestMapping(value = "/register/create", method = RequestMethod.GET)
public String registerCreatePage(Model model) {
    // some stuff
    if (!model.containsAttribute("register")) {
        model.addAttribute("register", new Register());
    }
    // some more stuff
}

Source: http://gerrydevstory.com/2013/07/11/preserving-validation-error-messages-on-spring-mvc-form-post-redirect-get/

2voto

rjsang Points 867

Je me demande pourquoi vous avez besoin de la redirection. Pourquoi ne pas simplement soumettre à la même URL et le faire répondre différemment à un POST? Néanmoins, si vous voulez vraiment faire ceci:

 @RequestMapping(value = "/submit", method = RequestMethod.POST)
public final String submit(
    @ModelAttribute("register") @Valid final Register register,
    final BindingResult binding,
    HttpSession session) {

    if (binding.hasErrors()) {
        session.setAttribute("register",register);
        session.setAttribute("binding",binding);
        return "redirect:/register/create";
    }

    return "redirect:/register/success";
}
 

Puis dans votre méthode "create":

 model.put("register",session.getAttribute("register"));
model.put("org.springframework.validation.BindingResult.register",session.getAttribute("register"));
 

1voto

klonq Points 934

Le seul moyen de conserver des objets entre les demandes (c'est à dire une redirection) est de stocker l'objet dans un attribut de session. Donc, vous devez inclure "HttpServletRequest request" dans les paramètres de la méthode pour les deux méthodes (ie, get et post) et récupérer l'objet via la requête.getAttribute("binding"). Cela dit, et ne pas l'avoir essayé moi-même, vous pourriez avoir besoin de comprendre comment re-lier la liaison de l'objet de la nouvelle demande.

Un autre "non-plus agréable" façon est de simplement changer l'adresse URL du navigateur à l'aide de javascript

1voto

Lewis Points 1

Le problème est que vous redirigez vers un nouveau contrôleur, plutôt que de rendre la vue et de renvoyer la page de formulaire traitée. Vous devez faire quelque chose comme:

 String FORM_VIEW = wherever_your_form_page_resides

...

if (binding.hasErrors())
    return FORM_VIEW;
 

Je garderais les chemins en dehors de toute méthode en raison de la duplication de code de chaînes.

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