Servlet 学习笔记
一、动态网页技术发展
- 静态网页技术
- HTML: 无法进行用户交互
- 动态网页技术
- CGI: 效率低
- ASP: html+javascript+com
- PHP:php+mysql+linux+apache(流行结构)
- JSP:html + java片段 + jsp + js
二、B/S结构与C/S结构比较
- C/S结构:服务器和客户端都需要开发,例如QQ,服务器和客户端都需要腾讯开发和升级。
- B/S结构:客户端是现成的,例如客户端为浏览器,只需要开发服务器,客户端为浏览器,不用开发。
三、Servlet技术(B/S)
3.1 什么是Servlet
- Applet: java客户端小程序
- Servlet:java服务器小程序
3.2 servlet运行环境
浏览器
Web服务器(Tomcat,jBoss)
-
数据库
3.3 Tomcat
- 免费的开源的servlet容器
- 位于服务器端
- 功能
- web服务器:即可以接收浏览器的http请求,转发给servlet处理并返回页面
- jsp和servlet的容器:存放jsp和servlet
- 修改默认端口
- /conf/server.xml
- 修改虚拟目录
- /conf/server.xml
- 在</Host>之前,加入
<Context path = "/MyWebSite" docBase="D:\MyWebSite" debug = "0">
- 修改管理员密码
- /conf/tomcat-users.xml
- 防止非法用户远程登录到tomcat并发布有害站点(例如关闭服务器)
3.4 Servlet开发方法
-
开发流程
- 在%TOMCAT_HOME%/webapps下WEB-INF的文件夹,写一个文件web.xml(该网站的配置信息),建立一个classes的子文件夹,也可以从别的目录ROOT下拷贝
- 开发servlet(见以下三种方法)
- 部署servlet(修改web.xml文件配置)
<servlet> <servlet-name>hello</servlet-name> <!—给servlet取名,可以随意取名--> <servlet-class>com.test.Hello</servlet-class> <!—指明servlet的路径,就是servlet的包+类名--> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <!—给servlet取名,与上面的名字相同--> <url-pattern>/hello<url-pattern> <!—浏览器中输入的url,可以随意取名--> </servlet-mapping>
- 启动Tomcat,访问你的servlet,在浏览器的地址栏中输入:http://127.0.0.1:8080/myWebSite/hello 回车就可以看到servlet的输出
-
三种开发方法
- 实现servlet接口
- 需要实现init service destroy方法
- 配置web.xml文件
- 继承GenericServlet
- 需要实现service方法,相对简单
- 配置web.xml文件
- 继承HttpServlet(目前用的最多的方法)
- 需要重写doGet,doPost方法
- 表单提交数据get和post请求的区别
- 从安全性看get < post。get提交的数据会在浏览器的地址栏显示
- 从提交的内容大小看get<post。get提交的数据不能大于2K,而post提交的数据理论上不受限制,但是实际编程中建议不要大于64K
- 从请求响应速度看get>post。get请求服务器立即处理请求,而post请求可能形成一个队列请求
3.5 Servlet生命周期
- servlet部署在容器里(我们使用的是Tomcat,也可是别的,比如jboss,weblogic...),它的生命周期由容器来管理。
- servlet的生命周期分为以下几个阶段:
- 装载servlet,由相应的容器来完成
- 创建一个servlet实例
- 调用servlet的init()方法,该方法只会在第一次访问servlet时被调用一次
- 服务:调用servlet的service()方法,一般业务逻辑在这里处理,该方法在访问该servlet时,会被调用
- 销毁:调用servlet的destroy()方法,销毁该servlet实例,该方法在以下情况被调用:
a. tomcat重新启动
b. reload该webapps
c. 重新启动电脑
3.6 Servlet共享数据方法
3.6.1 同一用户的不同页面共享数据
即同一个账号的用户,如何在不同的http页面之间(即不同的servlet之间)共享信息
-
cookie技术(客户端)
- 什么是cookie
-
Name Value String String Name Value String String
-
- cookie可以用来做什么
- 保存用户名、密码,在一定时间不用重新登录
- 记录用户访问 网站的喜好,比如有无背景音乐、网页的背景色是什么
- 网站的个性化,比如定制网站的服务、内容
- cookie使用
- cookie有点像一张表,分两列,一个是名字,一个是值,数据类型都是String
- 如何创建一个cookie(在服务器端创建的)
Cookie c=new Cookie(String name, String val);
- 如何将一个cookie添加到客户端
response.addCookie(c);
- 如何读取cookie(从客户端读到服务器)
request.getCookie();
- cookie其他说明
- 可以通过IE—工具—internet选项—隐私—高级来启用或是禁用cookie
- 由于cookie的信息是保存在客户端的,因此安全性不高
- cookie信息的生命周期可以在创建时设置(比如30s),从创建那一时刻起,就开始计时,到时该cookie的信息就无效了
- 什么是cookie
-
sendRedirect()跳转
sendRedirect("welcome?name="+user+"&pass="+psw);
- 其中welcome是sevlet的url,?后面是两个传递的变量name和pass,第二个变量需要加AND符号&
- 传送较快,但只能传字符串,不能传类
- 传送的变量会在浏览器url中显示,密码等敏感信息不能传送
-
隐藏表单提交
- hidden 不会显示在页面上,但是后台servlet可以获取该值
<form action=login> <input type=hidden name=a value=b> </form>
- hidden 不会显示在页面上,但是后台servlet可以获取该值
-
session技术(服务器端)
-
什么是session
- 当用户打开浏览器,访问某个网站时,服务器就会在服务器的内存为该浏览器分配一个空间,该空间被这个浏览器独占。这个空间就是session空间,该空间中的数据默认存在时间为30min,你也可以修改该值。一个浏览器实例拥有一个session。
-
如何理解session
-
可以把session看做一张表,这张表有两列,而表有多少行理论上没有限制,每一行就是session的一个属性。每个属性包含有两个部分,一个是该属性的名字String,另外一个是它的值Object。
Name Value String Object
-
-
如何使用session
- 得到session
HttpSession hs=request.getSession(true);
- 向session添加属性
hs.setAttribute(String name,Object val);
- 从session得到某个属性
String name=hs.getAttribute(String name);
- 从session中删除掉某个属性
hs.removeAttribute(String name);
- 注销session中的内容(比较安全的一种方式)
ht.setMaxInactiveInterval(0);
- 得到session
-
session注意事项
- session中属性存在的默认时间是30min,你也可修改它存在的时间:
(a)修改web.xml 全局修改改Tomcat/conf文件夹下面的web.xml,仅改某一个webapp的默认时间,则修改webapp下面的web.xml(b)在程序中修改 - 上面说的这个30min指的是用户的发呆时间,而不是累计时间
- 当某个浏览器访问网站时,服务器会给浏览器分配一个唯一的session id,并以此来区分不同的浏览器(即客户端)
- 因为session的各个属性要占用服务器的内存,因此软件公司都是在迫不得已的情况下才使用
- session中属性存在的默认时间是30min,你也可修改它存在的时间:
-
session应用实例
- 网上商城中的购物车
- 保存登陆用户的信息
- 将某些数据放入到session中,供同一用户的各个方面使用
- 防止用户非法登陆到某个页面
-
-
cookie和session比较
- 存在的位置
- cookie保存在客户端,session保存在服务器端
- 安全性
- cookie的安全性比session要弱
- 网络传输量
- cookie通过网络在客户端与服务器端传输,而session保存在服务器端,不需要传输
- 生命周期
- cookie的过期时间是从创建开始计算的,session的过期时间是从最近一次使用时间开始计算的;
- 关机会导致session生命周期结束,而对cookie没有影响;
- sessionCookie与persistentCookie
- sessionCookie
- session是以cookie或URL重写为基础的,默认使用cookie来实现,系统会创造一个名为JSESSIONID的输出cookie,称为sessionCookie
- 存储于浏览器内存中的,并不是写到硬盘上的,这也就是我们刚才看到的JSESSIONID,我们通常情是看不到JSESSIONID的,但是当我们把浏览器的cookie禁止后,web服务器会采用URL重写的方式传递Sessionid,我们就可以在地址栏看到sessionid=KWJHUG6JJM65HS2K6之类的字符串
- persistentCookie
- 通常所说的cookie,存储在硬盘上
- sessionCookie
- 内在联系
- 大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个session id就消失了,再次连接服务器时也就无法找到原来的session。如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求头,把原来的session id发送给服务器,则再次打开浏览器仍然能够找到原来的session
- 存在的位置
3.6.2 不同用户之间共享数据
-
ServletContext
-
ServletContext、cookie与session区别
-
ServletContext使用方法
- 得到ServletContext实例
this.getServletContext();
- 添加属性setAttribute(String name, Object ob);
- 得到值getAttribute(String name); 返回Object
-
Name Value String Object Name Value String Object
- 得到ServletContext实例
-
ServletContext生命周期
- ServletContext中的生命周期从创建开始,到服务器关闭而结束。
-
ServletContext注意事项
- ServletContext长时间占用服务器内存,建议不要向ServletContext中添加过大的数据,切忌。
- 总之如果是涉及到不同用户共享数据,而这些数据量不大,同时又不希望写入数据库中,我们就可以考虑使用ServletContext来实现。
-
ServletContext应用实例
- 网站计数器
- 网站在线用户显示
- 简单的聊天系统
-
3.7 servlet数据库操作
-
采用JDBC连接数据库
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testdb","test","020048");
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("select password from userinfo where username='"+ uname+"'");
- 注意在finally语句中逆序关闭
-
采用连接池方式连接数据库
- 配置连接池
在 /conf/server.xml中添加代码 or 在Tomcat中直接配置
-
类似线程池,给数据库连接预先分配连接池,以提高性能。原先每次连接数据库都需要加载驱动得到一根连接,分配连接池后,如果连接池中有空闲的连接,就直接将其分配给请求客户端;如果没有空闲连接,则请求客户端在队列池中等待空闲连接;
- 使用连接池
- 引入
javax.sql
,javax.naming
包 Context ctt=new javax.naming.InitialContext();
DataSource ds=(DataSource)ctt.lookup(“java:comp/env/数据源名”);
conn=ds.getConnection();
- 引入
- 配置连接池
-
sql注入漏洞
select * from users where username='abc'and password = '123' or 1='1'
- 当用户输入的密码为"123' or 1='1'"时,数据库所有数据泄露
-
分页技术详解
- 需要定义四个变量:
- int pageSize:每页显示多少条记录
- int pageNow:希望显示第几页
- int pageCount:一共有多少页
- int rowCount:一共有多少条记录
- 数据库操作
select top pageSize 字段名列表 from 表名 where id not in(select top pageSize*(pageNow-1) id from 表名)
- 需要定义四个变量:
-
注意事项
- 需要将连接数据库的jar包,拷贝到tomcat服务器。具体有两种方法:
- 将jar包拷贝到tomcat目录下的lib文件夹里
- 在webapps目录的WEB-INF文件下建立一个lib文件夹,然后将jar包拷贝到该文件夹下
- 两种方法的区别:
- 所有webapps都可以使用jar【公用lib库】
- 只有放入jar的那个webapps能使用jar【私用lib库】
- 需要将连接数据库的jar包,拷贝到tomcat服务器。具体有两种方法:
3.8 网站框架改进
- Model1模式(界面和业务逻辑混合)
代码冗余
框架层次模糊
-
代码可读性、可维护性差(界面改动会影响业务逻辑)
- MV模式(M:Model,V:view)
-
进行分层,将界面层和业务逻辑层分离
-
- MVC模式(M:Model,V:view,C:controller)