web-dev-qa-db-fra.com

Botte de printemps + thymeleaf dans IntelliJ: ne peut pas résoudre les vars

J'écris une application de formulaire Web courte utilisant Spring Boot et Thymeleaf sur IntelliJ, mais il semble que dans le fichier html, tous les champs du modèle ne puissent pas être résolus. Voici mon code:

Classe de contrôleur:

@Controller
public class IndexController{

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index(){
        return "index";
    }

    @RequestMapping(value="/", method = RequestMethod.POST)
    public String addNewPost(@Valid Post post, BindingResult bindingResult, Model model){
        if(bindingResult.hasErrors()){
            return "index";
        }
        model.addAttribute("title",post.getTitle());
        model.addAttribute("content",post.getContent());
        return "hello";
    }
}

Classe modèle:

public class Post {

    @Size(min=4, max=35)
    private String title;

    @Size(min=30, max=1000)
    private String content;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

Alors est l'index.html:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en">

    <title>Spring Framework Leo</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>

<h3>Spring Boot and Thymeleaf</h3>


    <form action="#" th:action="@{/}"  th:object="${post}" method="post">
        <table>
            <tr>
                <td>Title:</td>
                <td><input type="text" th:field="*{title}" /></td>
                <td th:if="${#fields.hasErrors('title')}" th:errors="*{title}">Title error message</td>
            </tr>
            <tr>
                <td>Content:</td>
                <td><input type="text" th:field="*{content}" /></td>
                <td th:if="${#fields.hasErrors('content')}" th:errors="*{content}">Content error message</td>
            </tr>
            <tr>
                <td><button type="submit">Submit post</button></td>
            </tr>
        </table>
    </form>

Il y a toujours des lignes rouges sous "post", "titre" et "contenu", mais je ne sais pas comment le résoudre. Est-ce un problème d'IntelliJ ou juste un problème de code?

16
Shuhan Liu

C'est un problème avec IntelliJ: IDEA-132738

En gros, IntelliJ ne parvient pas à localiser les variables du modèle lorsque Spring Boot a été utilisé pour tout configurer automatiquement.

15
Andrew
  1. Si votre version d'IntelliJ est <2017.3 , c'est, comme Andrew a écrit , une erreur connue IDEA-132738 . Il existe une solution de contournement pour se débarrasser des marques d'erreur dans l'EDI. IntelliJ prend également en charge la génération semi-automatique du code mentionné ci-dessous:

Vous pouvez utiliser Alt+Enter raccourci permettant d’appeler l’intention "Déclarer une variable externe dans une annotation de commentaire" afin de supprimer "l'attribut de modèle non résolu" dans vos vues.

Ajoutez le code suivant à votre fichier html:

<!--/* Workaround for bug https://youtrack.jetbrains.com/issue/IDEA-132738 -->
    <!--@thymesVar id="post" type="your.package.Post"-->
    <!--@thymesVar id="title" type="String"-->
    <!--@thymesVar id="content" type="String"-->
<!--*/-->

Si vous utilisez des objets d'extensions construits automatiquement par ThymeLeaf, tels que #temporals à partir de thymeleaf-extras-Java8time pour la conversion d'objets Java.time:

<span th:text="${#temporals.format(person.birthDate,'yyyy-MM-dd')}"></span>

et IntelliJ ne peuvent pas les résoudre, utilisez un code similaire et ajoutez simplement # devant le nom de l'objet:

<!--@thymesVar id="#temporals" type="org.thymeleaf.extras.Java8time.expression.Temporals"-->
  1. Si votre version d'IntelliJ est> = 2017.3 (cependant, certaines personnes se plaignent que cela ne fonctionne toujours pas pour elles), le problème doit être résolu (@FloatOverflow: "Je confirme que dans la version 2017.3 version 25.Oct.2017 le problème a été résolu"):

Statut 2017.3

La prise en charge des applications MVC autoconfigurées Spring Boot est terminée, tous les types de vue de configuration automatique fournis sont pris en charge.

Corriger les versions: 2017.3

15
Honza Zidek

Je veux ajouter une chose. Comme indiqué ci-dessus, le problème a été résolu dans IntelliJ 2017.3 . Je peux aussi le confirmer.

Cependant, j’ai remarqué que cela n’est vrai que si vous définissez tous vos attributs directement dans la fonction de contrôleur responsable, comme par exemple. ce:

@RequestMapping(value = "/userinput")
public String showUserForm(Model model){
    model.addAttribute("method", "post");
    model.addAttribute("user", new User());
    return "userform";
}

Si vous utilisez une sous-fonction dans laquelle vous définissez les attributs du modèle (voir Exemple ci-dessous), IntelliJ ne peut toujours pas trouver les attributs dans le modèle HTML.

Exemple :

@RequestMapping(value = "/userinput")
public String showUserForm(Model model){
    return doIt(model);
}

private String doIt(Model model) {
    model.addAttribute("method", "post");
    model.addAttribute("user", new User());
    return "userform";
}

Donc, assurez-vous de toujours placer votre code directement dans la fonction de vue!

3
user7346048

Dans mon cas, le problème était que j'avais les éléments suivants dans mon application.properties:

spring.thymeleaf.prefix=file:src/main/resources/templates/

spring.thymeleaf.cache=false

Une fois ces propriétés supprimées, les mappages de mvc de printemps sont à nouveau détectés par Intellij (dans la version Ultimate, j'utilise 2018.1). De plus, les objets thymeleaf fonctionnent maintenant.

J'ai utilisé ces propriétés pour prendre en charge le développement rapide, dans lequel une actualisation rechargerait les fichiers de modèle Thymeleaf.

Pour résoudre ce problème, j'utilise l'option -D suivante dans la configuration d'exécution de mon application Spring Boot pour indiquer à Spring Boot l'emplacement de mes fichiers de propriétés au cours du développement:

-Dspring.config.location=/dev/application/conf/application.properties
1
Ekkelenkamp