首页 > 解决方案 > java.lang.IllegalArgumentException:迭代变量不能为空

问题描述

在此处输入图像描述> 被困在这几天了。我相信这个问题必须做

与班级本身。或者所讨论的类与其列所在的类之间的关系。

这是我的课程: Mod

package com.matt.Keyword.models;
    import javax.persistence.*;
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Size;


    @Entity
    @Table(name = "Mods")
    public class Mod {

        @Id
        @GeneratedValue
        private int id;

        @NotNull
        private Integer role;

        @NotNull
        @Size(min = 1, message = "An entry is required")
        private String entry;

        @Column(name = "user_id")
        private Integer userid;

        public Mod(Integer role, String entry) {
            this.role = role;
            this.entry = entry;
        }

        public Mod() {
        }

        public int getId() {

            return id;
        }

        public int getRole() {
            return role;
        }

        public void setRole(Integer role) {
            this.role = role;
        }

        public String getEntry() {
            return entry;
        }

        public void setEntry(String entry) {
            this.entry = entry;
        }

        public Integer getUserid() {
            return userid;
        }

        public void setUserid(Integer userid) {
            this.userid= userid;
        }

    }

帐户

package com.matt.Keyword.models;

    import javax.persistence.*;
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Size;

    @Entity
    public class Account {

        @Id
        @GeneratedValue
        private int id;

        @NotNull
        @Size(min = 3, message = "Try again")
        private String name;

        @NotNull
        @Size(min = 1, message = "A password is required")
        private String password;

        @Column(name = "user_id")
        private Integer userid;

        public Account(String name, String password) {
            this.name = name;
            this.password = password;
        }

        public Account() {
        }

        public int getId() {

            return id;
        }

        public String getName() {

            return name;
        }

        public void setName(String name) {

            this.name = name;
        }

        public String getPassword() {

            return password;
        }

        public void setPassword(String password) {

            this.password = password;
        }

        public Integer getUserid() {
            return userid;
        }

        public void setUserid(Integer userid) {
            this.userid = userid;
        }

    }

Account 和 Mod 类非常相似,并且与 user 类中的 user_id 列共享关系。

用户

package com.matt.Keyword.models;

import javax.persistence.*;
import javax.validation.constraints.Size;
import java.util.List;

@Entity
public class User {

    @Id
    @GeneratedValue
    @Column(name = "user_id")
    private int id;

    @Size(min=3, message = "Try again")
    private String email;

    @Size(min=1, message = "A password is required")
    private String password;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "user_id", referencedColumnName = "user_id")
    private List<Account> accounts;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "user_id", referencedColumnName = "user_id")
    private List<Mod> mods;

    public User(String email, String password) {
        this.email = email;
        this.password = password;
    }

    public User() {}

    public int getId() {

        return id;
    }

    public void setId(Integer id){
        this.id = id;
    }
    public String getEmail() {

        return email;
    }

    public void setEmail(String email) {

        this.email = email;
    }

    public String getPassword() {

        return password;
    }

    public void setPassword(String password) {

        this.password = password;
    }

    public List<Account> getAccounts() {
        return accounts;
    }

    public void setAccounts(List<Account> accounts) {
        this.accounts = accounts;
    }


    public List<Mod> getMods() {
        return mods;
    }

    public void setMods(List<Mod> mods) {
        this.mods = mods;
    }
    @Override
    public String toString()
    {
        return email + " " + password;
    }
}

当我从我的 mods 控制器加载索引页面时抛出异常。我正在使用百里香来渲染视图。这是我的模组控制器。Mods 数据库中保存了对象,并且在调试期间在此控制器中,传递给视图的属性包含已填充的 Mod 对象列表。 模组控制器

package com.matt.Keyword.controllers;


    import com.matt.Keyword.models.Mod;
    import com.matt.Keyword.models.User;
    import com.matt.Keyword.models.data.ModDao;
    import com.matt.Keyword.models.data.UserDao;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.validation.Errors;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;

    import javax.servlet.http.HttpSession;
    import javax.validation.Valid;

    //test commit note
    //second try
    //third try
    /**
     * Created by LaunchCode
     */
    @Controller
    @RequestMapping("mod")

    public class ModController {

        @Autowired
        private UserDao userDao;

        @Autowired
        private ModDao modDao;

        @RequestMapping(value = "")
        public String index(Model model, HttpSession session) {

            if (session.getAttribute("currentUser") == null) {

                return "redirect:/keyword/login";
            }

            session.getAttribute("currentUser");
            model.addAttribute("title", "Mods");
            model.addAttribute("mods", modDao.findAll());
            return "mods/index";

        }

        @RequestMapping(value = "add", method = RequestMethod.GET)
        public String displayModForm(Model model, HttpSession session) {

            if (session.getAttribute("currentUser") == null) {
                return "redirect:/keyword/login";
            }

            model.addAttribute("title", "Add a new mod");
            model.addAttribute(new Mod());
            return "mods/add";
        }

        @RequestMapping(value = "add", method = RequestMethod.POST)
        public String processAddModForm(@ModelAttribute @Valid Mod newMod,
                                            Errors errors, Model model, HttpSession session) {

            if (errors.hasErrors()) {
                model.addAttribute("title", "List of Mods");
                return "mods/add";
            }
            User currentUser = (User) session.getAttribute("currentUser");

            session.getId();

            currentUser.setId(currentUser.getId());

            newMod.setUserid(currentUser.getId());

            modDao.save(newMod);

            return "redirect:";

        }

    }

这是使用 thymeleaf 的 mod/index 页面。

模组/索引

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

    <body class="container">

    <h1 th:text="${title}">Default Title</h1>

    <p th:unless="${mods} and ${mods.size()}">No current mods</p>

    <nav th:replace="fragments :: navigation"></nav>

    <p th:text="${session.currentUser.email}"></p>

    <table class="table">
        <tr>
            <th>Type</th>
            <th>Entry</th>
        </tr>
            <div th:if="${mods} != null">
                <tr th:each="mod : ${mods}">
                    <div th:if="${mod.userid} == ${session.currentUser.id}">
                        <td th:text="${mod.role}"></td>
                        <td th:text="${mod.entry}"></td>
                    </div>
                </tr>
            </div>

    </table>
    </body>
    </html>

该异常似乎与 for th:each 语句有关。特别是使用“mod”迭代器变量。这是完整错误的堆栈跟踪: Trace

There was an unexpected error (type=Internal Server Error, status=500).
An error happened during template parsing (template: "class path resource [templates/mods/index.html]")
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/mods/index.html]")
    at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:241)
    at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parseStandalone(AbstractMarkupTemplateParser.java:100)
    at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:666)
    at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098)
    at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072)
    at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:362)
    at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:189)
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1370)
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1116)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1055)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.standard.processor.StandardEachTagProcessor' (template: "mods/index" - line 21, col 17)
    at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:393)
    at org.attoparser.MarkupParser.parse(MarkupParser.java:257)
    at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:230)
    ... 52 more
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.standard.processor.StandardEachTagProcessor' (template: "mods/index" - line 21, col 17)
    at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:117)
    at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95)
    at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633)
    at org.thymeleaf.engine.ProcessorTemplateHandler.handleOpenElement(ProcessorTemplateHandler.java:1314)
    at org.thymeleaf.engine.TemplateHandlerAdapterMarkupHandler.handleOpenElementEnd(TemplateHandlerAdapterMarkupHandler.java:304)
    at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler$InlineMarkupAdapterPreProcessorHandler.handleOpenElementEnd(InlinedOutputExpressionMarkupHandler.java:278)
    at org.thymeleaf.standard.inline.OutputExpressionInlinePreProcessorHandler.handleOpenElementEnd(OutputExpressionInlinePreProcessorHandler.java:186)
    at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler.handleOpenElementEnd(InlinedOutputExpressionMarkupHandler.java:124)
    at org.attoparser.HtmlElement.handleOpenElementEnd(HtmlElement.java:109)
    at org.attoparser.HtmlMarkupHandler.handleOpenElementEnd(HtmlMarkupHandler.java:297)
    at org.attoparser.MarkupEventProcessorHandler.handleOpenElementEnd(MarkupEventProcessorHandler.java:402)
    at org.attoparser.ParsingElementMarkupUtil.parseOpenElement(ParsingElementMarkupUtil.java:159)
    at org.attoparser.MarkupParser.parseBuffer(MarkupParser.java:710)
    at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:301)
    ... 54 more
Caused by: java.lang.IllegalArgumentException: Iteration variable cannot be null
    at org.thymeleaf.util.Validate.notNull(Validate.java:37)
    at org.thymeleaf.standard.expression.Each.<init>(Each.java:49)
    at org.thymeleaf.standard.expression.EachUtils.composeEach(EachUtils.java:169)
    at org.thymeleaf.standard.expression.EachUtils.internalParseEach(EachUtils.java:94)
    at org.thymeleaf.standard.expression.EachUtils.parseEach(EachUtils.java:65)
    at org.thymeleaf.standard.processor.StandardEachTagProcessor.doProcess(StandardEachTagProcessor.java:59)
    at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74)
    ... 67 more

任何帮助表示赞赏。提前感谢您有时间看一下。

mod 控制器中的调试器 如果您想下载并运行它,这里有一个链接到我的仓库。

会话中的休眠异常

编辑到 mod/index 控制器

标签: javaspringiteratoriterationthymeleaf

解决方案


这个问题被证明是一个相当棘手的问题。其决议的故事如下......

通过堆栈跟踪判断:

Caused by: java.lang.IllegalArgumentException: Iteration variable cannot be null

thymeleaf 模板中有一个迭代,其中有一个null变量被迭代。th:each我能找到的唯一用途是:

<div th:if="${mods} != null">
    <tr th:each="mod : ${mods}">
         ...
    </tr>
</div>

所以看起来这mods就是null问题th:each="mod : ${mods}"所在。

但是,使用<div th:if="${mods} != null">. 或者在那里?以下内容是否更有用:

<div th:if="${mods != null}">

IE。移动 以}使null检查在表达式内。

这没有帮助,因此modDao.findAll()检查了结果并找到了两个元素。所以它必须是别的东西。

回顾Thymeleaf 中的迭代基础知识表明,返回的集合可能不是可以迭代findAll()的受支持类型之一。th:each

所以这个集合被复制到Iterable一个不同的名字中,问题就解决了。

有趣的是,如果为迭代变量命名mod,问题仍然存在。原来mod是 hymeleaf 中的一个关键字,用于模块操作 ( %)。

最终,显然正确的代码存在两个问题:

  1. DAO 返回了一个集合,但不是一个可以被th:each.
  2. mod是 Thymeleaf 中的关键字,不应用作变量名。

推荐阅读