GoF单例设计模式
第一章 GoF设计模式概述
1-1 什么是设计模式
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。
使用设计模式的目的:为了代码可重用性、可维护性。
1-2 GoF概述
《Design Patterns: Elements of Reusable Object-Oriented Software》(即后述《设计模式》一书),由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 合著(Addison-Wesley,1995)。这几位作者常被称为"四人组(Gang of Four)"。
1-3 Gof设计模式共多少种
23种
第二章 单例模式
2-1 单例模式概述
单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类,一个类只有一个实例(只有一个对象)。
2-2 单例模式之饿汉式
2-3 单例模式之懒汉式
2-4 实际项目开发中的应用
实际项目开发使用 饿汉式
懒汉式会涉及到线程的安全性问题
Servlet
第一章Servlet初识
1-1 Servlet在web开发中的作用
servlet:接收请求,做出响应
1-2 Servlet的创建步骤
见代码注释
1-3 Servlet家族继承结构
1-4 Servlet中Service方法的应用
总结:service方法已经由父类帮我们写好,就是用来根据请求方式分配请求的,我们不要对他进行重写.
1-5 Servlet的生命周期(以及load-on-startup的用法)
☆☆☆☆☆
什么是servlet的生命周期,表示的是servlet的对象从创建到销毁的全过程.
(1) 启动服务器,servlet对象没有创建.
(2) 当我们的浏览器发出请求,用到指定servlet的时候,servlet对象才创建.servlet对象在创建完毕后,是以单例的形式存储在了服务器的内存中.当第2~第n次访问的时候就不重新创建对象了,而是使用第一次访问创建的那个(单例).
(3) 当servlet对象创建完毕后,马上调用init方法执行初始化操作.
(4) 我们以后的请求真正是由doGet/doPost方法来进行处理.
(5) 关闭服务器,servlet对象销毁.
(6) 如果只正常关闭服务器,servlet对象在销毁前,要调用destroy方法进行最后的处理工作.
(7) 加入load-on-startup可以更改servlet的创建时机,由以前的用到时才创建更改为启动服务器的时候就创建(从单例来考量,是由懒汉式转为饿汉式)
(8) 注意:servlet是单例,但是是一种假单例.
真单例:new不出来第二个对象
假单例:我们用的是以单例的形式存在的对象,但是可以手动new出来其他对象.servlet在外部类new出来新对象没有任何意义.
第二章web开发的常见问题
2-1服务器启动时报错,如何进行错误排查
如果服务器中没有项目存在,启动服务器报错,说明服务器本身出现了问题.有可能是某些配置文件被我们破坏掉.在某些情况下文件被破坏掉了没有办法排查,所以最简单的方式是从新解压一份tomcat服务器,重新集成到eclipse.
如果服务器中有项目存在,启动服务器报错,说明是项目的问题,就去查看项目中的web.xml文件配置有没有错误.
(1) url-pattern前面没加/
(2) servlet-name没有匹配项
(3) servlet-class配置错误,服务器启动不报错,但是访问返回500响应码
2-2修改哪些文件,必须重新启动服务器
(1) 修改前端文件,不用重新启动服务器
(2) 修改后端servlet文件,不用重新启动服务器,但是需要等待java文件重新编译成class文件重新加载的过程.
在本阶段,老师在修改完servelt文件之后,为了保证程序测试的正确性,每一次都会重新启动服务器.
(3) 修改web.xml文件,必须重新启动服务器.
注意:我们在对项目进行移入移除的过程中,必须首先关闭服务器.
2-3使用快捷方式创建Servlet类的方式
以上形式会快速的为我们搭建一个servlet类以及servlet相关配置
在以后的实际项目开发中,该形式只做第一个模板来使用.
使用该形式有一个非常大的弊端:每次生成servlet,web.xml中的注释全都被干掉了.
2-4使用run on server的方式快速发布项目测试简单应用
以上形式会自动的将项目部署到服务器中,自动启动服务器,自动打开eclipse中自带的浏览器,自动输入资源访问地址,自动敲回车,显示结果.
但是这种方式我们以后的实本际项目开发根就不用!!!
因为这种形式使用的是eclipse中自带的浏览器,eclipse中自带的浏览器很垃圾,测试简单的应用还可以,一些相对复杂的应用测试不到效果.更重要的是,本来是错误的程序,eclipse中自带的浏览器有可能会测试成功.
我们可以使用该形式,生成访问路径,然后将访问路径copy到我们本地的浏览器中进行测试,省掉了一个敲路径的时间.
但是在本阶段,不要使用这种形式,练习敲路径!!!
2-5 copy项目及修改项目名的注意事项
2-6 web项目导入jar包的方式及注意事项
在这里插入图片描述
将jar包复制粘贴到WEB-INF/lib文件夹下之后,jar包会自动的构建到我们的项目中.
需要注意的是,我们将来的学习会在项目中导入大量的jar包,每次导入jar包后,需要看到jar包构建成功了,我们才能够使用jar包中的类库.
我们以后的jar包都需要存放在WEB-INF/lib下,自己创建的lib包就不能使用了.
WEB-INF/lib未来只存放jar包!!!
2-7清理开发环境及清理浏览器缓存的方式
清理tomcat项目环境,将项目移除后,启动一下空的服务器,项目才能够从webapps文件夹中彻底移除.
清除浏览器缓存的方式
ctrl+shift+delete
2-8原有项目丢失tomcat开发环境,如何重新导入
删除tomcat的顺序
先删除 右键delete
然后删除
最后删除
项目重新集成tomcat环境
完成以上操作以后,tomcat的开发环境就回到项目中了
2-9实际项目开发中TODO的使用(tasks视图的使用)
2-10 360浏览器的访问问题
使用360安全浏览器
启动服务器后,由此浏览器第一次发送的get方式的请求
doGet方法执行两次
第三章get与post提交方式
3-1 get与post提交方式
http: get提交方式和post提交方式
get请求方式:
(1) 在浏览器地址输入地址,敲回车访问服务器,为get请求方式,servlet中由doGet方法来处理请求.
(2) 点击超链接,链接到后台servlet. 为get请求方式,servlet中由doGet方法来处理请求.
(3) 提交form表单, 为get请求方式,servlet中由doGet方法来处理请求.
post请求方式:
(1)提交form表单.method=”post”
3-2 请求参数的传递与接收
传递参数的方式:
url?key1=value2&key2=value2&key3=value3
例如
接收参数方式
作为提交表单操作
表单元素中的name属性为key
我们提供的值为value
3-3 get提交和post提交的区别
get提交
(1) 参数传递
a. 显示的将参数挂在url路径的后面
b. 安全性 低
c. 大量参数的传递可能传递的不全
(2) 参数的中文的支持性
对于我们的示例,get请求提交的中文参数servlet接收到之后,显示的仍然是中文,没有出现乱码.
但是以上结果,完全在于是我们的tomcat9的环境完美支持get请求中文参数的传递.
如果企业里面使用的是较低版本的tomcat,那么中文参数有可能会出现乱码.
我们要为get请求方式设置utf-8的字符编码
在tomcat conf/server.xml 6x行
URIEncoding=”UTF-8”就可以解决tomcat版本低get中文参数出现乱码的问题
(3) 执行效率
get请求执行效率较高
post提交
(1) 参数传递
a. 参数没有显示的挂在url路径的后面
(参数是以http协议请求体打包的形式进行传递)
b. 安全性 高
c. 不用担心大量参数传递的问题(地址栏不显示,不用担心超出浏览器地址栏的字符数)
(2) 参数的中文的支持性
经过示例,post提交,中文参数出现了乱码问题,servlet接收参数前,需要对接收的参数进行字符编码处理.
以上代码仅针对post请求参数处理.
(3)执行效率
与get请求方式比较起来,执行效率相对较低.
3-4 实际项目开发中对于get和post提交方式的使用
在我们的实际项目开发中,对于get提交和post提交如何选择:
如果不涉及到安全性问题,如果不涉及到大量的参数的传递问题,一律使用get方式提交效率较高,否则一律创建表单使用post方式提交.
在我们实际项目开发中,servlet模板习惯于这样来改造:
第四章url-pattern的使用
4-1 url-pattern的表现方式
/abc/myServlet1.do:精确路径匹配
/abc/:部分路径匹配
/:通配符匹配
.do:后缀名匹配
注意:
(1).do前面不加/
(2)/abc/.do的形式不存在
(3)abc/.do的形式不存在
如果使用的是后缀名形式的匹配,只有一种形式 *.do
4-2 url-pattern的优先级
如果浏览器发出的请求路径与web.xml中的多个url-pattern都匹配,那么只执行一个servlet来处理我们的请求.选择哪个servlet来处理我们的请求完全在于url-pattern路径的优先级.
精确路径匹配 > 部分路径匹配 > 统配符匹配 >后缀名匹配
第五章响应流
5-1 响应流的创建和基本使用
使用响应流为浏览器做出响应
5-2 使用响应流响应中文信息
5-3 练习:使用响应流响应学生信息列表
domain:领域模型(实体类)
所有属性都是私有的,所有的存取操作都是由setter和getter来操作的
5-4 实战:完成登录操作,如果登录成功,则在页面上打印学生信息列表,如果登录失败,则在页面打印失败信息。
用户表 tbl_user
id int 6
username varchar 255
password varchar 255
学生表 tbl_student
id varchar 255
name varchar 255
age int 3
第六章转发和重定向
6-1 转发代码示例
(1)转发到普通页面
(2)转发到WEB-INF下面的页面
(3)转发到另一个servlet
6-2 重定向代码示例
(1)重定向到普通页面
(2)重定向到WEB-INF下面的页面
(3)重定向到另一个servlet
6-3 转发和重定向原理
6-4 练习:使用Servlet做连续转发和重定向的操作
第七章ServletContext对象(上下文对象)
7-1 上下文对象概述及生命周期
上下文对象是项目中的全局管理者(上下文对象在项目中只有一个)
上下文对象可以应用在每一个servlet中,为每一个servlet提供相应的服务.
每一个servlet都可以随时随地的取得上下文对象并使用.
上下文对象的生命周期
创建:当服务器启动,服务器会自动的为我们创建一个上下文对象,该上下文对象就是以单例的形式存储在服务器上.
销毁:服务器关闭,上下文对象销毁.
7-2 上下文对象的取得方式
见代码注释
7-3 上下文对象的常用方法
(1)获得全局初始化参数
getInitParameter(String key)
搭配web.xml中的配置
encoding
utf-8
(2)作为域对象存取数据
在servlet中,域对象一共有3个,上下文是其中一个,域对象是用来做存取值操作的.不同的域对象,存值之后的取值范围也是不同的.
上下文域对象的取值范围是3个域对象中最广的.
当我们将值存储到上下文域中,只要上下文对象还在,那么里面的值就还在.
application.setAttribute(String key,Object value)
application.getAttribute(String key) Object
application.removeAttribute (“key”)
(3)获取项目发布路径
getRealPath("/")
第八章ServletConfig对象
8-1 ServletConfig对象概述
ServletConfig对象是Servlet对象的配置对象.
Servlet对象在创建完毕后,系统会马上为我们创建出来一个相应的ServletConfig对象作为Servlet对象的配置对象.
ServletConfig对象是可以有多个的(每有一个servlet对象,就有一个ServletConfig对象)
在我们实际项目开发中,如果是对于企业级的项目开发,那么ServletConfig对象肯定用不到.
ServletConfig对象主要是针对于将来的表现层框架的开发而使用的.
8-2 ServletConfig对象取得方式
ServletConfig config = this.getServletConfig();
8-3 ServletConfig对象常用方法
(1)获得web.xml中配置的servlet-name
String name = config.getServletName();
System.out.println(name);*/
(2)根据key获取value
getInitParameter(String key)
/ServletConfig config = this.getServletConfig();
String encoding = config.getInitParameter(“encoding”);
System.out.println(encoding); //utf-8
request.setCharacterEncoding(encoding);
response.setContentType(“text/html;charset=”+encoding);/
配合web.xml中的配置(注意配置在servlet-class的下方)
(3)取得上下文对象
ServletContext application=this.getServletConfig().getServletContext();
也可以写成 ServletConfig config= this.getServletConfig();
8-4 搭配init方法的注意事项
super.init(config)不能去掉,如果去掉了这一行,config对象就不能创建了.上下文对象也拿不到了.
第九章web开发中文乱码解决方式总结
9-1 get请求参数字符编码的处理
conf/server.xml 6x 端口号
URIEncoding=”UTF-8”
9-2 post请求参数字符编码的处理
request.setCharacterEncoding(“UTF-8”);
9-3响应流字符编码的处理
response.setContentType(“text/html;charSet=utf-8”);
9-4通过jdbc往数据库里面存值的字符编码的处理
要求数据
后台 utf-8
数据库安装的过程中,配置的是UTF-8环境
创建的数据库为UTF-8的格式
如果遇到安装数据库的过程中,配置的不是UTF-8的环境.
应急的措施
url? characterEncoding=UTF-8
9-5通用处理方式
String str11= new String(str1.getBytes(“ISO8859-1”),“utf-8”);
第十章web站点的默认欢迎页的设置
欢迎页的设置指的是,当我们的请求发送到服务器,路径仅仅只是显示到项目,没有指定具体的资源路径,那么我们配置的欢迎页会自动的响应出来.
• 我们可以同时配置多个欢迎页,按照从上向下的配置顺序,有哪个,就响应哪个.
• 不论我们配置的欢迎页是一种什么类型的页面,我们习惯于将欢迎页命名为index,因为index是我们web开发中一种约定俗成的初始页名字的叫法.
(3)欢迎页我们一般来讲都是配置的是前端资源,但是也可以配置成为后端资源.
这种用法很少见,但是如果要这么用,注意路径的写法,前面不加/
(4)常见应用方式
将欢迎页设置为index.html,然后index.html页面加载完毕后,再自动跳转到login.html
第十一章Servlet线程的安全性问题
在我们的实际项目开发中,没有需求会使用到servlet中的成员变量,所以为了线程的安全性问题,我们不使用成员变量就可以了.以后不用servlet中的成员变量了,使用局部变量,每根线程来了以后,局部变量为每一个线程独立的分配一份,
绝对不会出现线程安全问题。
第十二章 实战
12-1验证登录,当我们登录失败,提示"用户名密码不匹配",3秒以后跳转到登录页面,若登录成功,可查看学生列表
方式1:
常见的响应头-refresh
响应头格式:
refresh:秒数;url=跳转的路径
设置定时刷新:
response.setHeader(“refresh”,“3;url=/z1/login.htm”);
这种方式只能搭配响应流的形式来完成
response.setHeader("refresh","3;url=/z1/index.html");
PrintWriter out = response.getWriter();
out.write("<html>");
out.write("<body>");
out.write("3秒钟之后,跳转到登录页");
out.write("</body>");
out.write("</html>");
方式2:在页面完成头信息的设置
首先重定向到一个倒计时页面
response.sendRedirect("/z1/ts.html");
在该页面设置
<meta http-equiv="refresh" content="3;url=/z1/index.html">
登录成功后代码重构
12-2统计在服务器启动期间,系统被访问的总次数
int count = 0;
当用户登录成功后,访问总次数加1
count++;
count应该存储在哪?
根据我们的需求,第一次登录之前,count变量就应该有了,当服务器关闭,count变量销毁.
上下文域
12-3 完成注册操作
对于tbl_user表的添加操作
12-4 完成对于学生信息列表的删除操作
delete from tbl_student where id=?