with root cause org.springframework.expression.spel.SpelEvaluationException* field ‘records‘ cannot

当前端同一个html页面被后台不同的控制访问时,可能因为不同的控制器传的参数不同,导致报错,需要在可能没有传参数的参数上添加问号?

1、 前言

1.1 idae中spring boot项目使用thymeleaf模板,前端HTML页面获取后台Controller中的Model存放的数据

1.2 项目在登录后跳转到后台显示查询到数据库数据的页面(首先是还没有查询,需要进入页面后点击按钮才去查询并显示)

1.3 这里就直接报错误了,最开始我只能通过把查询到的数据显示到页面(就是刚刚登录成功,就跳转去查询数据)的方式解决错误,后面我发现一个好玩的方法,在这里介绍一下。

2、 错误信息

2.1主要错误
2021-11-20 20:40:36.536 ERROR 10352 — [nio-8082-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: “class path resource [templates/main.html]”)] with root cause
org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field ‘records’ cannot be found on null
at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:213) ~[spring-expression-5.3.12.jar:5.3.12]

2.2其他的小错误
The operator ‘SUBTRACT’ is not supported between objects of type ‘null’ and ‘java.lang.Integer’
SpelEvaluationException: EL1030E: The operator ‘ADD’ is not supported between objects of type ‘null’ and ‘java.lang.Integer’

3、 错误原因

3.1 前端页面通过 ${page.current} 获取后台Cotroller中查询的分页数据,获取失败。因为我最开始只是通过login请求登录成功了,并没有去查询数据,所以分页数据为空。

3.2 那个2.2中的小错误是我解决办法过程中产生出来的。那个错误其实就是相加或者相减过程中,不能是null和数字进行计算。这里使用的是三元运算符判断并赋默认值
((page?.current)==null?1:page.current)

<!--The operator 'SUBTRACT' is not supported between objects of type 'null' and 'java.lang.Integer'-->
<li th:class="${page?.current==1?'disable':''}" class="prev"><a aria-label="Previous" th:href="@{/showemp(pn=${((page?.current)==null?0:page.current)-1})}"><span aria-hidden="true">&laquo;</span></a></li>
<li th:class="${num==page?.current?'active':''}" th:each="num:${#numbers.sequence(1,((page?.current)==null?1:page.pages))}"><a th:href="@{/showemp(pn=${num})}">[[${num}]]</a></li>
<!--SpelEvaluationException: EL1030E: The operator 'ADD' is not supported between objects of type 'null' and 'java.lang.Integer'-->
<li th:class="${page?.current==page?.pages?'disable':''}" class="next"><a aria-label="Next" th:href="@{/showemp(pn=${((page?.current)==null?0:page.current)+1})}"><span aria-hidden="true">&raquo;</span></a></li>

4、 解决办法

4.1 添加问号,在每一个从后端获取的值中添加一个问号?

4.2 类似如下的page是后台model里面存放的分页数据

<a th:href="@{/delete/{id}(id=${book.id},pn=${page?.current})}" type="button" class="btn btn-danger btn-sm">删除</a>
<a th:href="@{/update/{id}(id=${book.id})}" type="button" class="btn btn-info btn-sm">更改</a></td>
Page<Book> page = new Page<>(pn,20);
Page<Book> bookPage = bookService.page(page, null);
model.addAttribute("page",bookPage);

5、 部分前端和后台代码

5.1 分页数据后台代码

@Controller
public class CrudController {
    @Autowired
    BookServiceImpl bookService;

    @GetMapping("/showemp")
    public String selectAll(@RequestParam(value = "pn",defaultValue = "1")Integer pn,
                            Model model){
        Page<Book> page = new Page<>(pn,20);
        Page<Book> bookPage = bookService.page(page, null);
        model.addAttribute("page",bookPage);
//        System.out.println(bookPage.getCurrent());
//        System.out.println(bookPage.getRecords().size());
        /**
         * 2021-11-18 21:02:01.321 ERROR 9272 --- [nio-8082-exec-4] org.thymeleaf.TemplateEngine             : [THYMELEAF][http-nio-8082-exec-4] Exception processing template "main": An error happened during template parsing (template: "class path resource [templates/main.html]")
         *
         * org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/main.html]")
         * 	at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:241) ~[thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
         * Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "page.getCurrent()" (template: "main" - line 86, col 17)
         * 这里不能使用重定向:否则前端数据不能通过thymeleaf获取
         */
//        return "redirect:/main";
        return "main";
    }
}

5.2 登录后台代码

@Controller
public class LoginController {

    @Autowired
    BookServiceImpl bookService;

    @GetMapping("/login")
    public String toLoginPage(){
        return "login";
    }

    @PostMapping("/login")
    public String LoginValidation(Book book,
                                  RedirectAttributes redirectAttributes,
                                  Model model,
                                  HttpSession session){
        String name = book.getName();
        String password = book.getPassword();
        Map<String,Object> map = new HashMap<>();
        map.put("name",name);
        map.put("password",password);
        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
        queryWrapper.ge("name",name );
        queryWrapper.ge("password",password);
        Book one = bookService.getOne(queryWrapper);
//        if (one.toString()!=null){
        if (one!=null){
//        if (!StringUtils.isEmpty(one.toString())){
            /**
             * org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'records' cannot be found on null
             * 如果直接从登录界面进入这个页面是错误的,因为这里用到了showemp这个请求的page分页查询的数据,直接进入是没有查询的,page分页数据为null
             * 所以只能先发送showemp请求查询到page分页数据才能成功的到达main页面。
             */
//            return "redirect:/main";
            session.setAttribute("login",name);
            //模拟服务器错误:5xx.html测试
//            int a = 12/0;
//            return "redirect:/showemp";
            return "redirect:/main";
        }
        String msg = "账号或密码错误";
        model.addAttribute("msg",msg);
        return "login";
    }
}

5.3 前端显示分页数据的HTML页面(最开始登录没有显示,需要点击 显示按钮

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>员工信息显示</title>

    <link rel="canonical" href="https://getbootstrap.com/docs/4.0/examples/dashboard/">

    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">

    <!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 -->
    <!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 -->
    <!--[if lt IE 9]>
    <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
    <![endif]-->


</head>
<body>
<!--员工数据表格显示-->
<div class="container table-responsive" style="margin-top: 50px">
    <table class="table table-bordered">
        <caption class="caption"><a th:href="@{/showemp}">显示员工信息</a> | <a th:href="@{/add}">添加</a></caption>
        <thead>
            <tr>
                <th>序号</th>
                <th>ID</th>
                <th>Name</th>
                <th>Password</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            <tr th:each="book,statu:${page?.records}">
                <th>[[${statu.count}]]</th>
                <td th:text="${book.id}"></td>
                <td>[[${book.name}]]</td>
                <td>[[${book.password}]]</td>
                <td>
                    <a th:href="@{/delete/{id}(id=${book.id},pn=${page?.current})}" type="button" class="btn btn-danger btn-sm">删除</a>
                    <a th:href="@{/update/{id}(id=${book.id},pn=${page?.current})}" type="button" class="btn btn-info btn-sm">更改</a>
                </td>
            </tr>
        </tbody>
    </table>
    <div class="row-fluid">
        <div class="span6">
            <div>当前第 [[${page?.current}]] 页 总计 [[${page?.pages}]] 页 共 [[${page?.total}]] 条记录</div>
        </div>
        <div class="span6">
            <nav  aria-label="Page navigation">
                <ul class="pagination">
                    <!--The operator 'SUBTRACT' is not supported between objects of type 'null' and 'java.lang.Integer'-->
                    <li th:class="${page?.current==1?'disable':''}" class="prev"><a aria-label="Previous" th:href="@{/showemp(pn=${((page?.current)==null?0:page.current)-1})}"><span aria-hidden="true">&laquo;</span></a></li>
                    <li th:class="${num==page?.current?'active':''}" th:each="num:${#numbers.sequence(1,((page?.current)==null?1:page.current))}"><a th:href="@{/showemp(pn=${num})}">[[${num}]]</a></li>
                    <!--SpelEvaluationException: EL1030E: The operator 'ADD' is not supported between objects of type 'null' and 'java.lang.Integer'-->
                    <li th:class="${page?.current==page?.pages?'disable':''}" class="next"><a aria-label="Next" th:href="@{/showemp(pn=${((page?.current)==null?0:page.current)+1})}"><span aria-hidden="true">&raquo;</span></a></li>
                </ul>
            </nav>
        </div>
    </div>
</div>

<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<!-- <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js" integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" crossorigin="anonymous"></script> -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值