目录

  • 1、日期和字符串之间的转化
    • 1.1 JDK 8 之前的 Date 日期的格式转换
    • 1.2 JDK 8之后 LocalDateTime 新日期的格式转换
    • 1.3 Thymeleaf 中将 Date 日期转换为字符串
    • 1.4 Thymeleaf 中将 LocalDateTime 日期转换为字符串
  • 2、系统启动时访问页面
  • 3、访问某 URL 执行的过程
    • 3.1 前置知识
    • 3.2 组件路径和查询字符串执行过程
  • 4、目前 javaweb 项目开发的“套路”
    • 4.1 详细步骤
      • 4. 开发具体的业务模块:
  • 5、使用 druid 数据库连接池
  • 6、Idea 打包 jar 包

1、日期和字符串之间的转化

1.1 JDK 8 之前的 Date 日期的格式转换

Date 和 String 之间的转换 API:

// String -> java.util.Date
String dateStr1 = "2021-12-30 12:59:59";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {Date date1 = sdf.parse(dateStr1);
} catch (ParseException e) {e.printStackTrace();
}// Date -> String
Date date2 = new Date();
String dateStr2 = sdf.format(date2);

1.2 JDK 8之后 LocalDateTime 新日期的格式转换

只要你使用的是 MySQL 8.0 之后版本的数据库,里面的时间格式已经改成了 LocalDateTime,之前项目中涉及到的日期均需要改成 LocalDateTime 类型的。

参考文献:java8 — 新日期时间API篇,包括之前的所有相关的 LocalDateTime 内容都可以参考这篇文章。

LocalDateTime 和 String 之间的格式转换:

//java.time.LocalDateTime -> String
LocalDateTime date = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String dateStr = formatter.format(date);
System.out.println(dateStr);System.out.println("-----------------------------------");
//String -> java.time.LocalDateTime
String datetime =  "2020-01-13 21:27:30";
LocalDateTime ldt = LocalDateTime.parse(datetime, formatter);
System.out.println(ldt);

1.3 Thymeleaf 中将 Date 日期转换为字符串

thymeleaf中使用#dates这个公共的内置对象:

th:text="${#dates.format(topic.topicDate ,'yyyy-MM-dd HH:mm:ss')}"

1.4 Thymeleaf 中将 LocalDateTime 日期转换为字符串

但是,查找相关资料,将 LocalDateTime 日期转换为字符串均需要进行 maven 配置,所以这里暂时先不对日期格式进行转化。

th:text="${#temporals.format(localDateTime, 'dd-MM-yyyy HH:mm:ss')}"

参考文献:用thymeleaf将LocalDateTime类型的日期格式化为yyyy-MM-dd hh:mm:ss

2、系统启动时访问页面

  1. 系统启动时,我们访问的页面是: http://localhost:8080/pro23/page.do?operate=page&page=login
  2. 为什么不是: http://localhost:8080/pro23/login.html
  3. 答: 如果是后者,那么属于直接访问静态页面。那么页面上的 thymeleaf 表达式浏览器是不能识别的;我们访问前者的目的其实就是要执行 ViewBaseServlet 中的 processTemplete() ,也就是说,我们要经过 PageController 去访问后端进行视图渲染的组件,而不能直接访问静态页面。

3、访问某 URL 执行的过程

http://localhost:8080/pro23/page.do?operate=page&page=login 访问这个URL,执行的过程是什么样的?

3.1 前置知识

  • ServerIP(服务器端的 IP 地址):怎么保证访问你的服务器,不是访问别人的服务器嘞,要把域名地址解析成一个 IP 地址,每一台服务器都在网络上有唯一的 IP 地址。

  • URL 地址各个部分对应的含义如下面表格所示:

URL 地址 http:// localhost :8080 /pro23 /page.do ?operate=page&page=login
各部分含义 协议 ServerIP port context root(根目录) request.getServletPath() query string

3.2 组件路径和查询字符串执行过程

  1. DispatcherServlet 组件的 URL 映射表 urlPattern 为 *.do 拦截 /page.do
  2. 中央控制器中的 request.getServletPath() 得到 /page.do 这个字符串;
  3. 中央控制器解析处理字符串,将 /page.do 转化成 page
  4. 拿到 page 这个字符串,然后去 IOC 容器(BeanFactory)中寻找 id=page 的那个 bean 对象,然后我们就可以找到 PageController.java 这个 class 类;
  5. 获取 operate 的值,这里是 page 方法,因此得知,应该执行 PageController 中的 page() 方法;
  6. PageController 中的 page 方法定义如下:
public String page(String page){return page ;
}
  1. 在 queryString: ?operate=page&page=login 中获取请求参数,参数名是 page,参数值是 login,因此 page 方法传入的形参 page 值会被赋上 "login" ,然后 return "login" , return 给 谁??
  2. 因为 PageController 的 page 方法是 DispatcherServlet 通过反射调用的
    method.invoke(....) ;,因此,字符串 “login” 返回给中央控制器 DispatcherServlet
  3. DispatcherServlet 接收到返回值,然后处理视图:
    目前处理视图的方式有两种: 1. 带前缀redirect: 2. 不带前缀
    当前,返回 “login”,不带前缀
    那么直接执行视图渲染操作:super.processTemplate("login",request,response);
  4. 此时 ViewBaseServlet 中的 processTemplate 方法会执行,会帮助我们设置前缀、设置后缀、封装成 templateEngine 引擎,然后这个引擎帮我们工作,执行 process 方法 ,效果是:
    在 “login” 这个字符串前面拼接 "/" (其实就是配置文件中 view-prefixe 配置的值)
    在"login"这个字符串后面拼接 ".html" (其实就是配置文件中 view-suffix 配置的值)
  5. 最后进行服务器转发,属于内部转发。

4、目前 javaweb 项目开发的“套路”

4.1 详细步骤

  1. 导入 myssm.jar 包,这里也可以选择直接复制粘贴整个 myssm 文件夹到下一个项目,后面会对 myssm 中封装好的 DispatcherServlet 进行修改;
  2. 新建配置文件 applicationContext.xml 或者可以不叫这个名字,在 web.xml 中指定文件名
  3. web.xml 文件中配置:
  • 配置前缀和后缀,这样 thymeleaf 引擎就可以根据我们返回的字符串进行拼接,再跳转
<context-param><param-name>view-prefix</param-name><param-value>/</param-value>
</context-param>
<context-param><param-name>view-suffix</param-name><param-value>.html</param-value>
</context-param>
  • 配置监听器要读取的参数,目的是加载 IOC 容器的配置文件(也就是 applicationContext.xml)
<context-param><param-name>contextConfigLocation</param-name><param-value>applicationContext.xml</param-value>
</context-param>

4. 开发具体的业务模块:

(1)一个具体的业务模块纵向上由几个部分组成

  • html 页面
  • POJO 类
  • DAO 接口和实现类
  • Service 接口和实现类
  • Controller 控制器组件

(2)如果 html 页面有 thymeleaf 表达式,一定不能够直接访问,必须要经过 PageController

(3)在 applicationContext.xml 中配置 DAO、Service、Controller,以及三者之间的依赖关系

(4)DAO 实现类中 , 继承 BaseDAO,然后实现具体的接口, 需要注意, BaseDAO 后面的泛型不能写错。
例如:

public class UserDAOImpl extends BaseDAO<User> implements UserDAO{}

(5)Service 是业务控制类,这一层我们只需要记住一点:

  • 业务逻辑我们都封装在 service 这一层,不要分散在 Controller 层,也不要出现在 DAO 层(我们需要保证 DAO 方法的单精度特性)
  • 当某一个业务功能需要使用其他模块的业务功能时,尽量的调用别人的 service,而不是深入到其他模块的 DAO 细节

(6)Controller 类的编写规则

  1. 在 applicationContext.xml 中配置 Controller <bean id="user" class="com.atguigu.qqzone.controllers.UserController>
    那么,用户在前端发请求时,对应的 servletpath 就是 /user.do ,其中的 “user” 就是对应此处的 bean 的 id
  2. 在 Controller 中设计的方法名需要和 operate 的值一致
public String login(String loginId , String pwd , HttpSession session){return "index";
}

因此,我们的登录验证的表单如下:

<form th:action="@{/user.do}" method="post"><inut type="hidden" name="operate" value="login"/>
</form>
  1. 在表单中,组件的 name 属性和 Controller 中方法的参数名一致
<input type="text" name="loginId" />
public String login(String loginId , String pwd , HttpSession session){
  1. 另外,需要注意的是: Controller 中的方法中的参数不一定都是通过请求参数获取的,要除去浏览器发送请求自带的的参数,比如请求、响应、session 等
if("request".equals...) else if("response".equals....) else if("session".equals....){直接赋值
}else{此处才是从request的请求参数中获取request.getParameter("loginId") .....
}

(7)DispatcherServlet中步骤大致分为:

  1. 初始化方法中:从 application 作用域获取 IOC 容器
  2. 解析 servletPath , 在 IOC 容器中寻找对应的 Controller 组件
  3. 准备 operate 指定的方法所要求的参数
  4. 调用 operate 指定的方法
  5. 接收到执行 operate 指定的方法的返回值,对返回值进行处理 - 视图处理

(8)为什么 DispatcherServlet 能够从 application 作用域获取到 IOC 容器?
ContextLoaderListener 在容器启动时会执行初始化任务,而它的操作就是:

  1. 解析 IOC 的配置文件,创建一个一个的组件,并完成组件之间依赖关系的注入;
  2. 将 IOC 容器保存到 application 作用域。

5、使用 druid 数据库连接池

修改 BaseDAO,让其支持 propertie s文件以及 druid 数据源连接池,这里老师讲了两种方式,也不太清晰,具体的可以看我之前的 JDBC 中有关讲解:(尚硅谷)JDBC总复习

  1. 新建一个 jdbc.properties 配置文件放置在 src 文件夹下:

    配置文件的内容,这里的每一对配置中的 key 是固定格式的,不可以修改:
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/qqzonedb?useUnicode=true&characterEncoding=utf-8&useSSL=false
username=root
password=abc123# 初始化时建立物理连接的个数
initialSize=5
# 最大连接池数量
maxActive=10
# 最大等待时间
maxWait=3000
  1. 将 ConnUtil 获取连接的文件修改为:
public class ConnUtil {private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();/*** 使用Druid数据库连接池技术*/private static DataSource source;static{try {Properties pros = new Properties();InputStream is = ConnUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");pros.load(is);source = DruidDataSourceFactory.createDataSource(pros);} catch (Exception e) {e.printStackTrace();}}private static Connection createConn(){try {//            //1.加载驱动
//            Class.forName(DRIVER);
//            //2.通过驱动管理器获取连接对象
//            return DriverManager.getConnection(URL,USER,PWD);return source.getConnection();} catch (SQLException e) {e.printStackTrace();}return null ;}public static Connection getConn(){Connection conn = threadLocal.get();if(conn==null){conn =createConn();threadLocal.set(conn);}return threadLocal.get() ;}public static void closeConn() throws SQLException {Connection conn = threadLocal.get();if(conn==null){return ;}if(!conn.isClosed()){conn.close();//threadLocal.set(null);threadLocal.remove();}}
}

注意:

  1. 这里的这个 private static DataSource source; 要放置在 createConn() 方法外面,而不是像老师那样放置在方法内部,这样才能保证初始加载我们只创建了一个数据库连接池,而不是每次连接都创建一个数据库连接池(这样会更慢)。
  2. 这边需要将康师傅讲的 将ClassLoader.getSystemClassLoader().getResourceAsStream() 变成 ConnUtil.class.getClassLoader().getResourceAsStream();,否则就会报 500 错误,读取不到流文件,具体原因呢还不清楚为什么获取系统类加载器不可以,之后看完反射回来再说。

6、Idea 打包 jar 包

具体打包方法看 尚硅谷丨2022版JavaWeb教程(全新技术栈,全程实战),P68 18.00开始讲解如何打包的。

注意:

  1. 但是这里不建议删除,不建议打包,因为后面还要对这个 myssm 包内的文件进行修改,毕竟手写的不如人家框架里面封装好的考虑的全面,直接复制粘贴到下一个项目就可以了。

(尚硅谷)JavaWeb新版教程09-QQZone项目总结相关推荐

  1. 尚硅谷Nginx新版升级教程,带你轻松掌握高并发系统架构

    摘要:桃李春风一杯酒,江湖夜雨十年灯. "你说有没有一种可能, "你喜欢我,又不好意思说出口, "其实你可以直接说出来的, "我会让你知道什么叫心想事成.&qu ...

  2. 尚硅谷最新版JavaScript基础全套教程完整版(p79-p90)

    尚硅谷最新版JavaScript基础全套教程完整版(140集实战教学,JS从入门到精通) 一.函数的方法 1.call()和 apply()方法 -这两个方法都是函数对象方法,需要通过函数对象来调用 ...

  3. 04 frameset-iframe【尚硅谷JavaWeb教程】

    04 frameset-iframe[尚硅谷JavaWeb教程] JAVAWEB的学习笔记 学习视频来自:https://www.bilibili.com/video/BV1AS4y177xJ/?vd ...

  4. 06 CSS-盒子模型【尚硅谷JavaWeb教程】

    06 CSS-盒子模型[尚硅谷JavaWeb教程] JAVAWEB的学习笔记 学习视频来自:https://www.bilibili.com/video/BV1AS4y177xJ/?vd_source ...

  5. JavaScript(基础、高级)笔记汇总表【尚硅谷JavaScript全套教程完整版】

    目   录 前言 JavaScript(基础+高级)配套资料下载 JavaScript 基础 学习地址 学习笔记 day 05(P001-P006)[2016.11.22] day 06(P007-P ...

  6. 尚硅谷JavaScript高级教程(javascript实战进阶)学习笔记

    前言 这个是我学习过程中的笔记,分享给大家,希望对大家有用. 学习内容是尚硅谷JavaScript高级教程(javascript实战进阶),这里是视频链接. 我在前面有两篇对于web前端HTML和CS ...

  7. 尚硅谷Redis6基础教程-秒杀案例中库存遗留问题

    尚硅谷redis6基础教程中视频24-27的秒杀案例,使用Redis乐观锁解决了超卖问题,但是也产生了库存遗留问题.引入Lua脚本,解决了超卖和库存遗留.Lua脚本为什么解决了库存遗留问题???

  8. 尚硅谷Docker实战教程-笔记02【安装docker、镜像加速器配置】

    尚硅谷大数据技术-教程-学习路线-笔记汇总表[课程资料下载] 视频地址:尚硅谷Docker实战教程(docker教程天花板)_哔哩哔哩_bilibili 尚硅谷Docker实战教程-笔记01[理念简介 ...

  9. Vue数据代理+事件处理+事件修饰符的作用+计算属性的使用,尚硅谷Vue系列教程学习笔记(2)

    尚硅谷Vue系列教程学习笔记(2) 参考课程:<尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通> 参考链接:https://www.bilibili.com/video/ ...

最新文章

  1. java反射机制知识_Java反射机制讲解,程序员必须掌握的知识点
  2. nokia android 8,疑似诺基亚8再曝光:预装Android 8.0系统
  3. html旋转代码_用CSS实现一个抽奖转盘(附详细代码+思路)
  4. 01_基于应用拆分的技术架构
  5. 64位java_一文详解 Java 的八大基本类型!
  6. linux 验证邮箱账号,linux邮件服务器的身份验证(sasl)
  7. 统计mysql里每条SQL语句执行的时间
  8. System V 共享内存 和 系列函数
  9. 40.服务器搭建准备
  10. matlab界面语言修改
  11. 计算机机房需求调查表,机房建设需求调查表机房建设需求调查表.doc
  12. u盘遭受蠕虫 特洛伊木马攻击文件隐藏的解决办法
  13. [裴礼文数学分析中的典型问题与方法习题参考解答]5.1.13
  14. 使用hexo+github搭建免费个人博客详细教程
  15. itunes备份电脑C盘内存不够怎么办?
  16. imitate wechat - 1
  17. DGZX1564 - 水塔水位
  18. 百利天恒更新招股书:上半年收入约3亿元,持续加大研发投入
  19. excel数据分析--仪表板制作
  20. guid和mbr格式的区别;32位和64位操作系统的区别。

热门文章

  1. 华为s2600t java_华为服务器RH2288H V2连接 华为存储S2600T
  2. 无线传感器:智能建筑系统的眼睛和指尖
  3. 新东方APP技术架构演进, C端技术经验分享
  4. 利用CSS3的animation step属性实现wifi动画(结尾有彩蛋)
  5. Windows7+Windows10原版镜像集合
  6. UEFI BIOS —— SEC阶段分析
  7. 1z0-042题库笔记
  8. Screen Shots For OftenTap v1.0.0
  9. 对vSphere虚拟交换机的理解
  10. 关于烂代码的那些事(上中下)