SSM简单项目遇到的几个问题(最后一个问题,虽然能运行,但是我找不出问题出在哪里)

news2024/11/25 2:46:32

这几个问题,干扰了我很长时间。

主要因为书本的例子,是通过controller层返回到jsp层。但是,最后一个SSM项目,它用的是controller返回信息给Service层,再由Service层返回Jsp层。

实训:编写一个模糊查询姓名的项目。在另一个show.jsp页面显示查询信息。

一步一步:

先通过controller层返回到JSP层。

第一个问题:(未找到迭代器,或者不是迭代器类型)

javax.servlet.ServletException: javax.servlet.jsp.JspTagException: Don't know how to iterate over supplied "items" in <forEach>

show.jsp对应的代码信息:

<%--querylist.account是有提示的。只有list.account没有提示。(说明list不是一个可迭代器对象)--%>

<c:forEach items="${queryList}" var="user">
    ${user.account}<br>
    ${user.password}<br>
    ${user.sex}<br>
    ${user.name}<br>
</c:forEach>

这是show.jsp对应的代码,这个信息表示querylist的遍历器没有这个对象。说明,存在的问题是querylist不是一个可迭代的对象。我们返回到定义这个queryList的Controller文件,发现:

//        问题出在user这里,queryList是一个集合对象,但是user是一个类对象,是用不了c:foreach
        model.addAttribute("queryList",user);

解决方式:将user更换成一个迭代器对象。(例如,前面我们定义的service层的方法是一个list类型,这就是一个迭代器对象。)(额外:在使用 Service层作为与JSP返回的层级时,怀疑之前一直报错的原因,就是Service层的返回类型被我换成了String类型)

修改之后,可以在show.jsp显示用户查询信息。

第二个问题:未找到bean  “query2”。明明定义了query2

我尝试将用户信息查询得到的信息放在query.jsp页面下面,也就是query.jsp提供查询功能,并将信息放在query.jsp的下面。

一开始我的尝试:就是将原本返回给show的方法,改为返回给query。

在query.jsp里面,将show.jsp的代码复制过来。但是,结果出现一个很大的问题,我找了很久才发现问题:

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'query2' available as request attribute

这个错误信息表明在处理请求时,Spring无法找到名为query2的bean。

JSP原本的代码是:(这里需要将query修改为input)

<form:form method="post" action="${pageContext.request.contextPath}/user/query" modelAttribute="query2">

因为,我们将查询和显示,在Controller分别用了两个方法表示,大概流程是这样的:

首先我们在浏览器输入/input。

/input里面返回POJO的信息给query.jsp 。通过query2的属性,将POJO和query.jsp的表单信息进行绑定。

接着在query.jsp里面,提交用户信息,action 为/query 。

/query里面返回从数据库获取的信息给query.jsp。但是,此时query.jsp里面,又会读取一次表单信息,而此时表单信息的属性query2并没有定义。于是,IDEA就提示报错,:找不到bean “query2”。

 

修改之后:

大概流程:

首先浏览器输入/input 。

它返回POJO的信息给query.jsp。注意此时POJO还没有和query.jsp的name进行绑定。所以数据库返回的数据此时为null。

它也返回数据库获取的数据给query.jsp。(同样是null)

在用户query.jsp,它提交action 为/input。

于是和上面的信息一样。此时user为{“null”,"null","null","李"}

最后返回给query.jsp。此时,jsp里面的querylist就存在信息了。此时querylist为{“2020”,“1234”,“男”,“李XX”}

第三个问题:测试 跟踪流程去发现问题 (挺重要的)

(学习这个方式,以后就不需要先对spring和Mybatis先进行整合并测试。)我想通过一些测试方法跟踪 这个流程的输出情况。通过查找资料,得出,可以通过日志方式输出。

方法:引入`org.slf4j.Logger`类

不是`org.apache.commons.logging.Log`类`。Log`类的`info`方法只接受一个参数,不能使用占位符`{}`来格式化消息。(在前面,我学过使用org.apache.commons.logging.Log`类,使用打印像logger.info("登录成功")   这样的信息)如果想要使用占位符来格式化消息,您可以将`Log`类更改为`org.slf4j.Logger`类,并使用`org.slf4j.LoggerFactory`来获取日志记录器(logger)对象。例如,您可以将代码修改为以下内容:
 

其实就是在controller类里面添加两句:

private static final Logger logger = LoggerFactory.getLogger(Query2Controller.class);

logger.info("User info: {}", user);  //测试user对象是否获取到数据。

//如果还想测试queryList是否获取数据,也可以这样写。

package controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import po.User;
import service.Query2;

@Controller
@RequestMapping("/user")
public class Query2Controller {

    private static final Logger logger = LoggerFactory.getLogger(Query2Controller.class);
    @Autowired
    private Query2 query2;

    @RequestMapping("/input")
    public String input(Model model, User user){
        logger.info("User info: {}", user);
        model.addAttribute("query2",user);
        model.addAttribute("queryList",query2.query2list(user));
        return "query";
    }
}

在添加方法之前,需要把有关依赖包导入进来。

又因为我们的项目是通过log4j的那个配置,文件输出日志信息,所以,需要对SLF4J和log4j进行绑定。

就两个依赖包:一个SLF4j的依赖包,和前面的输出日志信息搭配。

一个是绑定log4j的依赖包。实现在log4j的配置文件里面输出日志信息。

使用`log4j`作为日志记录实现,您需要在应用程序的类路径中添加`SLF4J`到`log4j`的绑定库。您可以通过添加以下依赖项来实现这一点:
<!-- for Maven -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.32</version>
</dependency>

此外,您还需要在应用程序的类路径中添加`log4j`库。您可以通过添加以下依赖项来实现这一点:
<!-- for Maven -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

最后,配置log4j的配置文件,

不过,这个文件,其实在创建项目的时候,在mybatis的学习里面,我们已经添加过了。

添加完依赖项后,您需要配置`log4j`以指定日志记录行为。您可以在应用程序的类路径中创建一个名为`log4j.properties`的文件,并在其中指定日志记录配置。例如,您可以在配置文件中添加以下内容:
# Global logging configuration
log4j.rootLogger=DEBUG, stdout

# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

在上面的示例中,我们配置了一个名为`stdout`的控制台日志记录器(appender),它将日志信息输出到控制台。您可以根据需要更改配置。

结果如下:

user info 这个的信息,就是我们获取的user对象信息。

通过控制台信息,我们再来分析:

这整个流程:

首先浏览器输入:/user/input   。进入input界面。

此时运行两个model.addribute,第一个user存放的信息是null.第一个querylist存放的信息也是null。此时显示querylist的信息是null.即空。

再将这些数据交给query.jsp

在query.jsp里面,它提交action为/user/input。它继续回到这个input界面。

此时再次运行两个model.addribute,不过,第一个存放的信息里面多了name的信息。第一个querylist存放的信息是一条完整的数据。

最后,显示querylist的信息。

这是第一次,浏览器访问input的信息:

这是第二次,在input界面,点击按钮之后的信息:(action:/input)

最后,回到一开始的问题。通过controller 提交给service层 然后再交给JSP层。

由service层返回JSP信息:(最开始的困惑)

在书本最后一个比较大的SSM项目里面,都是通过controller层返回service.方法。然后在service里面,返回return ".jsp" 。

这个和我们一开始学的通过 controller层返回数据有点不同。return "。jsp"

第一个问题:错误是说,线程问题,其实真正问题不是这个,

05-Jul-2023 16:42:54.580 淇℃伅 [mysql-cj-abandoned-connection-cleanup] org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading Illegal access: this web application instance has been stopped already. Could not load []. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
    java.lang.IllegalStateException: Illegal access: this web application instance has been stopped already. Could not load []. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
 

找到文件所在,原来是我的mybatis-context.xml文件部署,给部署到dao.userDao里面去了,应该部署指定mybatis/UserMapper.xml

第二个问题:未解之谜,从service层传递的model属性,在JSP里面,并没有提示到获取了model的属性,但是,仍然可以得到最后的结果。

 

 

我们来比较一下,通过controller层返回给JSP的数据:

 

原因出在哪呢?尝试通过日志跟踪输出,查看信息是怎么从service层到View层的。

在log4j文件下,输出如下信息。

 

最后,在service层输入:

在控制台能够得到 数据。说明,数据传输是没有问题。

那么为什么JSP的model属性 提示没有获取到呢???没有获取到,它又是怎么得到最后的结果的???

未解之谜 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/721302.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java基础教程】(三)程序概念篇 · 上:探索Java编程基础,注释、标识符、关键字、数据类型~

Java基础教程之程序概念 上 本节学习目标1️⃣ Java中的注释2️⃣ 标识符3️⃣ 关键字4️⃣ 数据类型4.1 整型&#x1f50d; 什么是变量&#xff1f;什么是常量&#xff1f;&#x1f50d;关于数据类型转换的规则&#xff1f; 4.2 浮点数&#x1f50d;关于Java的计算的缺陷 4.3…

chatGPT写综述

文献是任何学术研究的基础&#xff0c;但搜集和整合众多的信息&#xff0c;写成一篇健全的文献综述却是一项艰巨的任务。随着人工智能技术的发展&#xff0c;大型预训练语言模型&#xff08;LM&#xff09;&#xff0c;如OpenAI的ChatGPT变得越来越流行。本文将探讨如何使用Cha…

K8S的概念和基本应用

学习视频&#xff1a;Kubernetes基本概念和应用_哔哩哔哩_bilibili 零 . 架构概览 master节点&#xff1a;管理调度集群资源&#xff0c;一般为多节点构成&#xff0c;可以是物理机&#xff0c;也可以是虚拟机。worker节点&#xff1a;资源的提供者&#xff0c;一般为多节点构…

沟通的层次模型

沟通的层次模型 根据沟通的倾向性将沟通划分为五个层次&#xff0c;分别是情绪、感受、想法、态度和事实。 模型介绍 沟通的层次 第5层&#xff1a;沟通情绪-带着强烈情绪表达&#xff0c;尤其经常使用这些字眼&#xff1a;“总是”、“每次都”第4层&#xff1a;沟通感受-不…

【APP开发】uni-data-select真机下拉框不显示问题

官网示例&#xff1a;uni-data-select 因为外层container有样式&#xff1a; width: 100%; height: 100%; overflow: hidden; display: flex; flex-direction: column; 去掉最外层 class"container"之后就可以了&#xff0c;但具体原因不清楚 我是对比了Hello uni-…

python中多态的作用是什么?

在强类型语言(例如Java或C#)中&#xff0c;多态是指允许使用一个父类类型的变量或常量来引用一个子类类型的对象&#xff0c;根据被引用子类对象特征的不同&#xff0c;得到不同的运行结果。即使用父类的类型来调用子类的方法。 在Python中&#xff0c;多态指在不考虑对象类型…

js压缩base64图片

今天试了用js把base64编码格式的图片进行压缩&#xff0c;记录一下&#xff1a; base64图片转换地址 base64图片转换网址 代码如下 js&#xff1a; $(document).ready(function(){compressImg(targetObj.src, 0.5, useImg, targetObj) });let targetObj {// base64字符串 …

机器学习26:《数据准备和特征工程-IV》数据转换

特征工程 是确定哪些特征可能对训练模型有用&#xff0c;然后通过转换日志文件等数据来源中的原始数据来创建这些特征的过程。在本文中&#xff0c;笔者将重点讨论何时以及如何转换数字和分类数据&#xff0c;以及不同方法的权衡。 目录 1.数据转换的原因 1.1 数据兼容性的强…

并发容器(一)CopyOnWriteArrayList

我们知道&#xff0c;ArrayList&#xff0c;LikedList&#xff0c;HashMap都是线程不安全的容器 同步容器&#xff1a;Vector&#xff0c;HashTable&#xff0c;SynchronizedList是线程安全的&#xff0c;因为里面加了synchronized同步&#xff0c;所以这样的容器也叫同步容器…

Zabbix监控

Zabbix监控 1.Zabbix监控概述1.1 zabbix是什么1.2 zabbix监控原理1.3 Zabbix 6.0新特性1.4 Zabbix 6.0功能组件1.5 Zabbix与prometheus区别对比 2. 部署Zabbix6.02.1 安装NginxPHP2.2 部署Mariadb数据库2.3 安装zabbix Server服务端2.4 部署Web前端&#xff0c;进行访问2.5 部署…

对给定的两个日期之间的日期进行遍历

每日一练:对给定的两个日期之间的日期进行遍历 题目 对给定的两个日期之间的日期进行遍历&#xff0c;比如startTime是2014-07-11&#xff1b;endTime是2014-08-11 如何把他们之间的日期获取并遍历出来。 思路与分析 不难看出&#xff0c;选项的4段实现代码中&#xff0c;除…

产品经理必须懂的api接口文档编写规范,api接口文档入门

很多产品经理刚接触 API 接口工作时&#xff0c;脑子一片空白&#xff0c;不理解接口&#xff08;API&#xff09;是什么&#xff0c;更看不懂接口开发文档。那么&#xff0c;作为一个不懂技术的产品经理&#xff0c;该如何看懂接口文档。今天这篇文章就跟大家好好巴拉巴拉。 …

一次阿里云Schedulerx换成Spring定时任务的过程

1、当前现状 所有的任务已经迁移到阿里云Schedulerx&#xff1b;阿里云Schedulerx是按照调用次数收费&#xff0c;有些任务每秒调用一次&#xff0c;费用太高&#xff1b; 2、明确需求 需要把执行非常频繁的定时任务从阿里云迁移&#xff08;阿里云收费根据调用次数&#xff0c…

基于matlab使用迭代方法为语义分割网络生成对抗性示例(附源码)

一、前言 此示例说明如何使用基本迭代方法 &#xff08;BIM&#xff09; 为语义分割网络生成对抗性示例。 语义分割是将图像中的每个像素分配给类标签的过程&#xff0c;例如汽车、自行车、人或天空。语义分割的应用包括自动驾驶的道路分割和医疗诊断的癌细胞分割。 神经网络…

5、架构:通用 Schema 设计

作为前端开发一定会非常熟悉 AST 抽象语法树&#xff08;Abstract Syntax Tree&#xff09;&#xff0c;当浏览器加载 JS 代码时&#xff0c;它会首先将代码转换为一棵抽象语法树&#xff08;AST&#xff09;&#xff0c;然后再根据 AST 来渲染对应的 DOM 结构&#xff0c;对于…

接口自动化核心知识点浓缩,为面试加分

日常接触到的接口自动化从实际目标可以划分为两大类&#xff1a; 为模拟测试数据而开展的接口自动化 这种接口自动化大多是单次执行&#xff0c;目的很明确是为了功能测试创造测试数据&#xff0c;节约人工造数据的时间和人工成本&#xff0c;提高功能测试人员的测试效率。 …

Nuendo 12.0.70 资源下载及功能介绍

简介 Nuendo 12是一款屡获殊荣的影视、游戏和沉浸式环绕声音频后期制作软件&#xff0c;Nuendo 12在对白录音和编辑方面做了重大改进&#xff0c;为你的录音带来新声。Nuendo12把“对白”制作放到一个非常重要的位置&#xff0c;比以前更加贴近用户&#xff0c;它甚至起了一个…

读书笔记-《ON JAVA 中文版》-摘要19[第十八章 字符串-2]

文章目录 第十八章 字符串6. 常规表达式6.1 基础6.2 创建正则表达式6.3 量词6.4 CharSequence6.5 Pattern 和 Matcher6.5.1 find()6.5.2 组&#xff08;Groups&#xff09;6.5.3 start() 和 end()6.5.4 split()6.5.5 替换操作6.5.6 reset() 7. 扫描输入7.1 Scanner 分隔符7.2 用…

Python 解释器

文章目录 每日一句正能量前言交互式编程脚本式编程 每日一句正能量 不是因为生活太现实&#xff0c;而对生活失望&#xff1b;而是知道生活太现实&#xff0c;所以更要用心的活下去。给自己一个拥抱。 前言 Python 解释器是运行 Python 代码的工具&#xff0c;主要分为官方提供…

MySQL索引结构(面试题)、索引分类、语法

2索引 2.1 索引概述 2.1.1 介绍 ​ 索引&#xff08;index&#xff09;是帮助MySQL高效获取数据的数据结构(有序)。在数据之外&#xff0c;数据库系统还维护着满足 特定查找算法的数据结构&#xff0c;这些数据结构以某种方式引用&#xff08;指向&#xff09;数据&#xff…