2
votes

pourquoi mon formulaire ne transmet-il pas d'informations dans Spring Boot

Bonjour, je passe des informations dans un formulaire et tout fonctionne bien, mais lorsque je remplis le formulaire, il ne transmet pas les informations et j'obtiens cette erreur.

Il y a eu une erreur inattendue (type = Erreur interne du serveur, statut = 500). Causé par: org.hibernate.exception.ConstraintViolationException: impossible d'exécuter l'instruction Causé par: java.sql.SQLIntegrityConstraintViolationException: La colonne 'movie_id' ne peut pas être nulle

le code que j'utilise est le suivant:

<div class="container">   
<table class="table table-hover">
    <tr>
        <th>Id</th>
        <th>Name</th>
    </tr>
    <tr th:each="LatestMovies : ${latestMovies}">
        <td th:text="${LatestMovies.id}"></td>
        <td th:text="${LatestMovies.movieName}"></td>
        <td>
       <form th:action="@{/save}" method="post" th:object="${newMovie}">
<p><input type="text" id="movie_id" th:field="*{movie_Id}"/></p>
<p><input type="text" id="movie_name" th:field="*{movie_Name}"/></p>
<p><input type="submit" value="save" /></p>
    </form>
</td>

    </tr>
</table>

Et p>

 <form th:action="@{/save}" method="post" >
    <p><input type="text" id="movie_id" name="movie_id" value="" /></p>
    <p><input type="text" id="movie_name" name="movie_name" value="" /></p>
    <p><input type="submit" value="save" /></p>
     </form>

Je crois que tous les autres codes sont corrects car si j'essaie de rendre les informations de la base de données, je n'ai aucun problème.

Mettre à jour

Voici le code HTML complet.

@PostMapping("/save")
public String save(Movie movie) {
    savedMovie.save(movie);
    return "redirect:/LatestMovies";
}


2 commentaires

Comme le dit l'erreur, votre movie_id est nul lorsque vous essayez d'enregistrer dans la base de données. Vérifiez pourquoi movie_id est nul


cul vous pouvez voir que je passe des informations dans le formulaire pour ce champ


3 Réponses :


1
votes

Vous avez oublié de marquer le paramètre de méthode avec l'annotation @RequestBody .


3 commentaires

comme ça? "Public String save (@RequestParam Movie movie) {"


Oui, mais utilisez plutôt @RequestBody.


comme ça? "public String save (@RequestBody Movie movie) {" avec ceci j'obtiens cette erreur maintenant Il y a eu une erreur inattendue (type = Type de média non pris en charge, état = 415).



3
votes

Votre contrôleur attend un objet Movie, mais il reçoit quelque chose d'autre, qui produit alors un objet Movie nul. Vous devez utiliser th: object dans votre formulaire afin d'envoyer correctement la classe respective. Tout d'abord, ajoutons un nouveau @ModelAttribute à votre contrôleur, afin que votre formulaire puisse automatiquement mapper votre objet Movie dans votre formulaire.

Contrôleur

<div class="container">   
<table class="table table-hover">
   <tr>
      <th>Id</th>
      <th>Name</th>
   </tr>
   <tr th:each="LatestMovies : ${latestMovies}">
      <td th:text="${LatestMovies.id}"></td>
      <td th:text="${LatestMovies.movieName}"></td>
      <td>
          <form th:action="@{/save}" th:object="${LatestMovies}" method="post">
              <p><input type="hidden" th:value="*{id}"/></p>
              <p><input type="hidden" th:value="*{movieName}"/></p>
              <p><input type="submit" value="Submit"/></p>
          </form>
      </td>
   </tr>
</table>

Maintenant, changeons votre formulaire, afin qu'il envoie réellement un objet Movie.

@ModelAttribute(value = "newMovie")
public Movie newMovie() {
    Movie movie = new Movie();
    movie.setName("Test");
    return movie;
}

Notez que j'ai également changé le nom dans vos entrées, pour th: field . N'oubliez pas que pour que cela fonctionne, le nom de chaque champ doit correspondre exactement aux noms de vos objets.

Mettre à jour

Au cas où vous souhaitez définir une valeur par défaut pour votre formulaire, sans utiliser js et comme vous ne pouvez pas combiner th: field avec th: value , vous pourrait définir l'attribut de l'objet dans votre contrôleur.

<form th:action="@{/save}" method="post" th:object="${newMovie}">
    <p><input type="text" id="movie_id" th:field="*{movie_id}"/></p>
    <p><input type="text" id="movie_name" th:field="*{movie_name}"/></p>
    <p><input type="submit" value="save" /></p>
</form>

Mise à jour 2

Si vous voulez mettre l'itération actuelle d'une liste Thymeleaf dans votre formulaire, vous pouvez faire ce qui suit.

// In order to use th:object in a form, we must be able to map a new entity to that form.
// In this case we return a Movie entity.
@ModelAttribute(value = "newMovie")
public Movie newMovie() {return new Movie();}


16 commentaires

J'adore votre réponse, vous venez de le faire fonctionner et j'ai essayé 100 approches différentes au cours des 3 derniers jours. Maintenant, je n'ai vu ce genre d'approche nulle part et je crois que 3 réponses au maximum ont voté pour dire qu'il n'y a aucun moyen de transmettre des informations à partir d'un formulaire dans Spring Boot sans javascript.


Merci pour votre commentaire! Je suis heureux de pouvoir vous aider :)


Désolé si je vous en demande un peu plus mais ... quand j'essaye d'ajouter une valeur à l'entrée, cela ne l'accepte pas. J'essaye ces 2 méthodes. "

" et

même en saisissant une information régulière comme value = "123" et ce n'est pas permettant de saisir une valeur prédéfinie


J'ai édité ma réponse avec les informations supplémentaires. Faites-moi savoir si cela résout votre demande. Si c'est le cas, un vote positif serait génial :).


une fois que j'aurai ma réputation jusqu'à 15 croyez-moi, vous l'aurez. Maintenant, j'ai mis à jour mon code html vers le code complet. Votre mise à jour fonctionne mais les informations que je veux saisir sont l'itération actuelle d'une liste de feuilles de thym.


Je pense que ma nouvelle mise à jour devrait faire l'affaire. Faites-moi savoir si cela aide.


cela n'aide pas en fait me donne des erreurs différentes mais ... peut-être que je l'insère mal. où dois-je utiliser ce code?


Pourriez-vous ajouter votre code html là où vous parcourez cette liste? De cette façon, je peux vous donner un exemple plus clair.


j'ai fait une mise à jour de mon corps html complet marqué comme mise à jour


maintenant j'obtiens ces erreurs: Causé par: org.attoparser.ParseException: Erreur lors de l'exécution du processeur 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagP‌ rocessor' (modèle: "LatestMovies" - ligne 24, col 39) et provoqué par: org.thymeleaf.exceptions.TemplateProcessingException: Erreur lors de l'exécution du processeur 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagP‌ rocessor' (modèle: "LatestMovies" - ligne 24, col 39) et causée par: java.lang.IllegalStateException: Aucun des deux BindingResult ni objet cible ordinaire pour le nom de bean 'LatestMovies' disponible comme attribut de requête


Ok, j'ai mis à jour mon code, au lieu d'utiliser th: field utilisez th: value lors de l'itération de la liste. Faites-moi savoir si cela vous aide.


les informations son chargement (je passe de caché à texte pour le vérifier mais ... maintenant nous sommes de retour à la colonne movie_id ne peut pas être nul, donc les informations ne passent pas du formulaire au backend


Eh bien, nous pourrions définir les valeurs en utilisant js , si c'est une option, je pourrais vous donner un exemple.


J'étais sur le point de le faire lorsque vous avez répondu et j'étais hypnotisé que cela pourrait être possible. ma solution était de créer un formulaire modal caché qui donnait l'option à l'utilisateur de "Êtes-vous sûr de vouloir ajouter"


si vous avez une solution plus simple, je suis à la hauteur des suggestions


Je viens de mettre à jour ma réponse dans votre autre question. Je crois que cela fera l'affaire et vous n'aurez pas besoin d'ajouter de js . :) stackoverflow .com / questions / 54271877 /…



0
votes

Cela se produit parce que l'objet vidéo que vous essayez d'envoyer du formulaire au contrôleur n'est pas correctement mappé . Cela a pour résultat que la contrainte du movie_id que vous avez dans votre table de films (PK non nul je suppose) soit violée en essayant d'y insérer une valeur non nulle . Si vous voulez que l'objet formé dans le formulaire de la page frontale soit lié dans un objet java, vous pouvez essayer ce

formulaire de page d'accueil

public class Movie{
  private String movie_id; // or int or long
  private String movie_name;
  //getters setters constructors ommitted
}

(vous devez importer sur votre page le formulaire de springframework taglib )

Enregistrer le code du contrôleur

@PostMapping("/save")
public String save(@ModelAttribute("movie") Movie movie) {
savedMovie.save(movie);
return "redirect:/LatestMovies";
}

Bien sûr, je suppose que votre objet a une structure similaire à celle illustrée ci-dessous

Classe de film

<form:form action="save" modelAttribute="movie" method="POST">
    <form:label path = "movie_id"> Movie id</form:label>
    <form:input path="movie_id" name="movie_id">
    <form:label path = "movie_name"> Movie name</form:label>
    <form:input path="movie_name" name="movie_name">
    <button type="submit">save</button>
</form:form>


1 commentaires

merci pour cette réponse. J'ai essayé cette approche mais j'ai maintenant utilisé le taglib qui pourrait être la raison pour laquelle cela n'a pas fonctionné. maintenant en disant cela. dans votre approche, comment pourrais-je créer des champs cachés qui sont saisis avec les valeurs d'une ancienne iterration de feuille de thym?