javaweb用到的配置以及遇到的问题
版本
- MySQL: 8.02
- Tomcat :9.0.64
- JDK:11
- Maven:3.014 (Thymeleaf)
- idea:2021.032
MySQL8.0设置
- 保存在jdbc.properties即可
1 | public static final String DRIVER = "com.mysql.cj.jdbc.Driver" ; |
Edit水果信息执行顺序
点击名称,
, 然后把fid发送给EditServlet
,EditServlet 内通过fid查找数据并保存(setAttribute ),然后EditServlet 跳转到 edit.html , 通过thymeleaf 获取 对象并填入 数据
,修改好之后 点击 修改(实际是一个form表单) 提交表单,
,将数据发送给updateServlet, updateServlet内完成 数据库的更新 ,然后跳转到index(经过thymeleaf渲染的界面,而不是直接index.html) , 修改操作完成
requests传参⚠️parameters
注意添加 -parameters
,否则请求发过来的参数就会是arg0 ,arg1,arg2 ,arg3s…………, 无法获得具体的名称(导致参数全部为null , 无法加载页面,
原因:
private String index(String oper , String keyword , Integer pageNo , HttpServletRequest request )
-
FruitController index()方法在执行时 ,参数全部为空, 无法通过null的 request对象获取session,也就无法保存(
setAttribute
)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30private String index(String oper , String keyword , Integer pageNo , HttpServletRequest request ) {
HttpSession session = request.getSession() ;
if(pageNo==null){
pageNo = 1;
}
if(StringUtil.isNotEmpty(oper) && "search".equals(oper)){
pageNo = 1 ;
if(StringUtil.isEmpty(keyword)){
keyword = "" ;
}
session.setAttribute("keyword",keyword);
}else{
Object keywordObj = session.getAttribute("keyword");
if(keywordObj!=null){
keyword = (String)keywordObj ;
}else{
keyword = "" ;
}
}
// 重新更新当前页的值
session.setAttribute("pageNo",pageNo);
List<Fruit> fruitList = fruitService.getFruitList(keyword , pageNo);
session.setAttribute("fruitList",fruitList);
//总记录条数
int pageCount = fruitService.getPageCount(keyword);
session.setAttribute("pageCount",pageCount);
return "index" ;
}
)
完成这个操作后,获得到了具体的实参名称
可以正确加载页面!!!!
qqzone项目增加添加日志功能
—ByMyself
thymeleaf ||
thymeleaf 表达式里面的 被 | | 包裹住的内容表示里面是一个普通字符串
被${ }包裹住的是表达式,
比如:
@{|/addTopic.do?operate=addTopic&userBasicId=${session.userBasic.id}|}
@{|/updateTopic.do?operate=updateTopic&userBasicId=${session.userBasic.id}|}
由于这是一个字符串 ,所以不用 再用’ 包裹operate 的值
发送请求时 就是http://localhost:8080/pro22/addTopic.do?operate=addTopic&userBasicId=1
主要增加了
-
addTopic.html
<a th:href="@{|/addTopic.do?operate=addTopic&userBasicId=${session.userBasic.id}|}" class="right8" target="_blank" >发表新日志</a>
- a标签向后端传值
-
addTopic 方法 :
-
TopicController
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public String addTopic(Integer userBasicId,HttpSession session){
// 跳转到 addTopic.html 填入内容
UserBasic userBasic = userBasicDAO.getUserBasicById(userBasicId);
session.setAttribute("userBasic",userBasic);
return "frames/addTopic";
}
public String updateTopic(String title, String content,Integer Id,HttpSession session)
{
// 通过 DispacherServlet 接收来自addTopic.html的数据 ,并保存到数据库
UserBasic author=(UserBasic)session.getAttribute("userBasic");
Topic topic=new Topic(content,new Date(),title,Id,author);
topicDAO.addTopic(topic);
return "redirect:user.do?operate=login&loginId="+author.getLoginId()+"&pwd="+author.getPwd();
/* return "index"; 直接返回index 就不会登录,无法显示个人信息(账号, 以及日志等)*/
} -
TopicDAOImpl
1
2
3
4
5
6
7
8
9
public void addTopic(Topic topic) {
executeUpdate("insert into t_reply values(?,?,?,?,?)",
topic.getId(),
topic.getTitle(),
topic.getContent(),
topic.getTopicDate(),
topic.getAuthor().getId()) ;
}
-
-
大概执行顺序
-
在main.html点击发表新日志
<a th:href="@{/addTopic.do}" class="right8" >发表新日志2</a>
-
DispacherServlet接收
/addTopic.do
请求, 从请求中获取operate(此处是 addTopic) ,调用TopicController(通过beanFactory获取)addTopic方法, -
DispacherServle接收addTopic方法的返回值(
String returnStr = method.invoke(controllerBeanObj,parameterValues)
😉,然后通过thymeleaf模板引擎加载前端页面 -
在addTopic.html填入数据后,点击提交,将表单(
<form th:action="@{|/updateTopic.do?operate=updateTopic&userBasicId=${session.userBasic.id}|}">
>)发送到DicpacherServlet,beanFactory从application.xml读取到请求对应的controller(这里就是TopicController),然后找到operate对应的方法(这里就是updateTopic方法),将数据保存到数据库,返回登录页面
1
return "redirect:user.do?operate=login&loginId="+author.getLoginId()+"&pwd="+author.getPwd();
- 这里仍然是DispacherServle接收addTopic方法的返回值,然后thymeleaf模板引擎加载前端页面
-
添加日志操作完成
-
main.html
1 | <a th:href="@{|/addTopic.do?operate=addTopic&userBasicId=${session.userBasic.id}|}" class="right8" target="_blank" >发表新日志</a> |
addTopic.html
1 |
|
遇到的问题:
- addTopic方法的
return "frames/detail";
的frames 没有写s - 执行的顺序应该是main.html 点击添加,发送请求, 然后执行addTopic 跳转到addTopic.html,在addTopic.html修改完成后,提交form表单,发送请求到TopicController的updateTopic,在uodateTopic内将数据保存到数据库
- 第一次写的时候直接在addTopic方法里保存到数据库,但那是明显不可行的
- TopicDAOImpl 的addTopic 方法需要插入的表写错了,导致日期格式不正确
- insert into t_topic 写成了 insert into t_reply
qqzone bug1
setValue方法在给 topic
: private Date topicDate ;
赋值时 出现异常:
-
Can not set java.util.Date field com.atguigu.qqzone.pojo.Topic.topicDate to java.time.LocalDateTime
-
无法将LocalDateTime类型数据赋值给Date类型变量
原因 :应该属于mysql8.0驱动的bug,具体原因未知
正常情况下从表中查出datetime类型如下
出现bug时类型为LocalDateTime,值为2017-07-15T00:16:40.0,与pojo属性类型不匹配
采用的解决方法是在属性赋值前(setValue
)进行类型检查,如果是LocalDateTime类型就转换成java.util.Date类型
- 正确的代码已经在上面改过了
- 注意 :
propertyValue=(Date)propertyValue;
直接转换会==报错==class java.time.LocalDateTime cannot be cast to class java.util.Date (java.time.LocalDateTime and java.util.Date are in module java.base of loader 'bootstrap')
1 | if (propertyValue.getClass().toString().equals("class java.time.LocalDateTime")) |
==bug==解除,可以正常加载页面
遇到的问题
总结:java的properties文件赋值不要写分号,会一起读取进去
==背景==:在将登录MySQL需要用到的数据封装到jdbc.properties时,
- 通过静态代码块,加载类时自动执行(读取jdbc.properties中的数据)
1 | public static String DRIVER ; |
==异常==:出现加载驱动错误
java.sql.SQLException: No suitable driver found for "jdbc:mysql://localhost:3306/qqzonedb2?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&useSSL=false";
==原因==:java的properties文件不能写分号
-
properties在load()时会将分号一起读取进去
-
因为
jdbc.properties
配置文件中的jdbc.DRIVER
后面带了一个分号,所以通过load获取的Driver也有一个分号(上面的debug图片) -
注意上面的异常最后也是带了一个分号
-
删去分号,问题解决
Controller 内 DAOImpl or Service 对象不需要初始化的原因
在application注册
1 | <bean id="user" class="com.atguigu.book.controller.UserController"> |
下面的property , 就是给UserController 内的 userService 初始化 ,直接UserService userService ;
就行,不需要再new UserService();