1、servlet容器如何处理请求资源路径?
比如,在浏览器地址栏输入 http://ip:port/web04/abc.html
浏览器会将"/web04/abc.html"作为请求资源路径,放到请求数据包(请求行)里面 发给servlet容器 。servlet容器收到之后,会采取如下的步骤来处理:
step1 , 依据 应用名("/web04")找到应用所在的文件夹 。
step2 , servlet容器会假设访问的是一个servlet,所以, 会比较web.xml文件中的<url-pattern> :
比较方式有三种:
1) 精确匹配 :
2) 通配符匹配 :
使用"*"匹配任意的0个或者多个字符。
比如:
<url-pattern>/*</url-pattern>
3) 后缀匹配 :
使用"*."开头,后接1个或者多个字符。
比如:
<url-pattern>*.do</url-pattern>
表示匹配所有以".do"结尾的请求。
step3 , 如何都不匹配, 容器会认为这是一个静态资源(html文件) ,然后查找相应的静态资源,如果找到,则 返回 ;找不到, 返回404 。
2、让一个servlet处理多种请求
step1, 使用 后缀匹配模式
step2, 分析 请求资源路径,依据分析结果,调用不同的分支来处理 。
//获得请求资源路径
String request.getRequestURI();
3、servlet的生命周期
(1)什么是servlet的生命周期?
servlet容器如何去创建servlet对象,如何为servlet对象分配资源,如何调用servlet对象的方法处理请求,以及如何销毁servlet对象的整个过程 。
(2)servlet生命周期的四个阶段:
1)实例化:
a, servlet容器调用servlet的构造器,创建相应的对象。
b, servlet容器会在以下两种情况下进行实例化操作:
情况1: 容器只有收到请求之后,才会将相应的servlet实例化 。
注意: 不管有多少个请求,容器在默认情况下,对于某个servlet,只会创建唯一的一个实例 。
情况2:容器在启动的时候,会检查servlet的配置,如果某个servlet配置了load-on-startup参数,则会马上进行实例化操作。
<load-on-startup>1</load-on-startup>
注意:
值要求是 一个大于等于零的整数 , 值越小 , 优先级越高 (即越先被容器创建)。
2)初始化
a, 容器在创建好servlet对象之后,会立即调用servlet对象的 init方法 。
b, GenericServlet已经实现了init方法(将容器创建好的ServletConfig对象保存下来了,并且提供了一个getServletConfig方法来方便地获取ServletConfig对象)。
c, Servlet初始化参数
step1, 在web.xml文件当中,使用<init-param>来配置 。
step2, String ServletConfig.getInitParameter(String paramName) ;
d, init方法应该如何override?
建议 override init() ,而不是 override init(ServletConfig)
e, init方法只会执行一次 。
3)就绪
a, 容器收到请求之后 ,调用servlet对象的service方法 。
b, HttpServlet已经实现了service方法 ,该方法会依据请求类型(get/post)分别调用 doGet/doPost方法 。
c, 我们如果要开发一个servlet,可以直接 override HttpServlet的service方法 或者 override HttpServlet的doGet/doPost方法 。
4)销毁
a, 容器在删除servlet对象之前,会调用 servlet对象的destroy方法 。
b,容器会依据自身的算法来决定什么时候删除servlet对象。
(3) servlet生命周期相关的几个接口与类
1)Servlet接口
a, init(ServletConfig config) : 初始化
b, service(ServletRequest req, ServletResponse res) : 就绪(处理请求)
c, destroy(): 销毁
2) GenericServlet抽象类 ,实现了Servlet接口中的部分方法( 实现了init,destroy方法 )。
3) HttpServlet 抽象类继承了 GenericServlet类 ,实现了service方法。
4) ServletConfig接口
String getInitParameter(String paraName);
4、jsp (java server page: java服务器端页面技术)
(1)什么是jsp?
sun公司制订的一种服务器端的动态页面技术规范。
因为直接使用servlet虽然也可以生成动态页面,但是过于繁琐(out.println),并且难以维护(如果要修改页面,就必须修改java源代码)。
jsp其实就是一个以".jsp"为后缀的文件,在该文件当中,可以添加html和少量的java代码,容器会将.jsp文件转换成一个.java文件(其实就是一个servlet类),然后调用这个servlet。
(2) 如何写一个jsp文件 ?
step1, 写一个以.jsp为后缀的文件 。
step2,在该文件当中,可以添加如下的内容:
1) html(css,javascript):直接写
2) java代码
a, java代码片断
<% java代码 %>
b, jsp表达式
<%= java表达式 %>
3) 隐含对象
a,什么是隐含对象?
在jsp文件里面,不写声明和创建,就可以直接使用的一些对象 ,比如out,request,response。
b,为什么可以直接使用这些隐含对象?
因为容器会自动生成声明和创建这些对象的代码。
4) 指令
a, 什么是指令?
告诉容器,在将.jsp文件转换成.java文件时,做一些额外的处理,比如导包。
b,指令的语法
<%@指令的名称 属性名称=属性值%>
c,page指令
import属性: 导包
比如: <%@page import="java.util.*"%>
contentType属性:设置response.setContentType的内容。
pageEncoding属性:告诉容器, jsp文件的编码。如果不设置这个属性,有些容器在读jsp文件时,会默认使用iso-8859-1去解码。
(3) jsp是如何执行的?
第一阶段: 容器要将jsp文件转换成一个java类(就是一个servlet) 。
1) html (css,javascript) ----->
service方法里,使用out.write输出 。
2) <% %> ----->
service方法里,照搬。
3) <%= %> ---->
service方法里,使用out.print输出。
第二阶段: 容器会调用servlet(即第一阶段生成的那个servlet)来处理请求 。
5、转发
(1)什么是转发?
一个web组件(servlet/jsp)将未完成的处理通过servlet容器转交给另外一个web组件继续完成 。
最常见的情况:一个servlet获得数据之后,转发给一个jsp,由这个jsp生成相应的页面。
(2)如何转发?
step1, 绑订数据到request对象上 。
//将obj绑订到request对象上,绑订名称
//由name来指定。
request.setAttribute(String name,Object obj);
比如:
request.setAttribute("emplist",emplist);
step2,获得转发器
//url:要转发的目的地的地址。
RequestDispatcher rd = request.getRequestDispatcher(String url);
比如:
request.getRequestDispatcher("emplist.jsp");
step3, 转发
rd.forward(request,response);
//依据绑订名称找到绑订的值。
//如果绑订值不存在,返回null。
Object request.getAttribute(String name);
比如:
request.getAttribute("emplist");
(3)编程需要注意的问题
a, 转发之前,不能够调用out.close方法 。
b, 转发之前,容器会清空response对象上缓存的数据 。
(4)特点
a,转发之后, 浏览器地址栏的地址不变 。
b,转发的 目的地必须是同一个应用内部的某个组件的地址 。
6、如何处理系统异常
方式一: 使用转发
比如
request.setAttribute("system_error","稍后重试");
request.getRequestDispatcher("system_error.jsp").forward(request,response);
方式二: 让容器来处理
step1,将异常抛出。
比如 throw new ServletException(e);
step2,编写一个错误处理页面比如 error.jsp
step3, 配置错误处理页面
<error-page>
<exception-type>javax.servlet.ServletException</exception-type>
<location>/error.jsp</location>
</error-page>
7、include指令
1)作用:告诉容器, 在将.jsp文件转换成.java文件时,将file属性指定的文件的内容插入到该指令所在的位置。
2)用法:
<%@include file="head.jsp"%>
8、路径问题
链接: <a href="del.do">
表单提交: <form action="modify.do">
重定向: response.sendRedirect("list.do")
转发: request.getRequestDispatcher("emplist.jsp")
(1)什么是 相对路径 ?
不以"/"开头的路径
(2)什么是 绝对路径 ?
以"/"开头的路径
(3)如何写绝对路径?
链接、表单提交、重定向从应用名开始写,
转发从应用名之后开始写。
//返回 "/appname"
String request.getContextPath();
(4) 在开发一个 web应用的时候,尽量优先使用绝对路径 。
9、摘要加密(扩展)
(1)什么是 摘要加密
摘要加密是一种 单向加密算法,即 明文依据摘要加密算法加密之后得到密文(也叫摘要),不能够反推出明文(没有使用密钥)。
有两个特点:
a, 不可逆性: 即依据密文(即摘要),不能够反推出明文。
b, 唯一性:即不同的明文,有不同的摘要。
10、转发与重定向的区别
(1) 转发的目的地有限制,只能是同一个应用内部某个组件的地址,而 重定向是任意的。
(2) 转发之后,浏览器地址栏的地址不变,而 重定向会变。
(3) 转发可以共享request对象,而 重定向不行。
request对象(当然也包括response对象)的生存时间非常短暂(一次请求与响应期间存在,即当请求到达容器时,容器创建这两个对象,一旦响应该发送完毕,容器会立即销毁这两个对象)。
转发是一次请求,所以转发所涉及的各个web组件都可以共享同一个request对象, 而重定向是两次请求,很显然不能共享同一个request对象。
11、状态管理
(1)什么是状态管理?
将浏览器与web服务器之间多次的交互当作一个整体来看待,并且将多次交互所涉及的数据(即状态)保存下来。
(2)如何进行状态管理
1)第一类方案: 将状态保存在客户端(浏览器)。
2)第二类方案: 将状态保存在服务器端(web服务器)。
(3) cookie
1)什么是cookie?
a, 属于客户端的状态管理技术。
b, 当浏览器访问web服务器时,服务器会将少量的数据以set-cookie消息头的方式发送给浏览器,浏览器会将这些数据保存下来;
当浏览器再次访问服务器的时候,会 将之前保存的这些数据以cookie消息头的方式发送给服务器。
2) 如何创建cookie?
(即让服务器发送set-cookie消息头给浏览器)
Cookie c = new Cookie(String name,String value); response.addCookie(c);
3) 查询cookie
//如果没有任何的cookie,会返回null。
Cookie[] request.getCookies();
//返回cookie的名字
String cookie.getName();
//返回cookie的值
String cookie.getValue();
4) 编码问题
cookie的名称和值都必须是合法的ascii字符。
中文很显示需要转换成ascii字符(即将中文转换成相应的ascii字符)。
//保存cookie时
String URLEncoder.encode();
//查询cookie时
String URLDecoder.decode();
5) 生存时间
cookie.setMaxAge(int seconds);
注意:
a,单位是 秒。
b, seconds > 0 : 浏览器会 将cookie保存在硬盘上,如果超过了指定的时间,浏览器会删除这个cookie。
seconds < 0 : 默认值,浏览器将cookie保存在内存里,除非浏览器关闭,否则cookie一直存在。
seconds = 0 : 删除cookie。
比如,要删除一个名称为"username"
的cookie,
Cookie c = new Cookie("username","");
c.setMaxAge(0);
response.addCookie(c);
6) cookie的路径问题
a,什么是cookie的路径问题?
浏览器在访问服务器的某个地址时,会比较cookie的路径是否与要访问的地址匹配,只有匹配的cookie才会发送给服务器。
b,cookie的默认的路径
等于创建该cookie的组件的路径,比如
/web06_2/app01/a1.jsp 创建了一个cookie,则该cookie的路径默认情况下等于
/web06_2/app01
c, 浏览器会比较要访问的地址与cookie 的路径:
要访问的地址必须是cookie的路径或者其子路径,浏览器才会将这个cookie发送给服务器。
d,修改cookie的路径
cookie.setPath(String path);
经常设置为:
cookie.setPath("/appname");
这样, 可以保证某个组件所创建的 cookie可以被同一个应用内部其它的组件访问到。
7)cookie的限制
a, 不安全
cookie是保存在浏览器端的,可以被用户查看到,所以,敏感数据一定要加密之后保存。
b, 可以被用户禁止
c, cookie能够保存的数据大小有限制。 (大约是4k)
d, 浏览器最多能保存大约300个左右的 cookie(具体的数量跟浏览器有关系)。
e, cookie只能够保存 字符串。
12、session(会话)
(1)session是什么?
a, 是 一种服务器端的状态管理技术(将状态保存在服务器上)。
b, 当浏览器访问服务器时,服务器会创建 一个session对象(该 对象有一个唯一的id,一般称之为sessionId)。接下来,服务器会将这个sessionId发送(默认情况下,会使用cookie的方式来发送,
即使用set-cookie消息头来发送)给浏览器。浏览器会将这个sessionId保存下来。
当 浏览器再次访问服务器时,会将sessionId发送给服务器,服务器会依据这个sessionId找到之前创建的session对象。
(2)如何获得session对象?
1)方式一
HttpSession s = request.getSession(boolean flag);
当flag = true时:
服务器会先查看请求当中是否有sessionId,如果没有sessionId,服务器就会创建一个session对象;如果有sessionId,服务器会依据这个
sessionId去查找对应的session对象,如果找到了,则返回,如果找不到,则创建一个新的session对象。
当flag = false时:
服务器会先查看请求当中是否有sessionId,
如果没有sessionId,服务器会返回null。如果有sessionId,服务器会依据这个sessionId去查找 对应的session对象,如果找到了,则返回,如果找不到,服务器会返回null。
2)方式二
HttpSession s = request.getSession(); 是request.getSession(true)的简写形式。
(3)HttpSession接口中声明的一些方法 String getId(); 返回sessionId
setAttribute(String name,Object obj); //如果绑订名对应的值不存在,会返回null。
Object getAttribute(String name);
removeAttribute(String name); //解除绑订
(4) session的超时
1)什么是sesson的超时?
服务器会将空闲时间过长的session对象删除掉。因为session对象会占用服务器的内存空间,所以,服务器会将一些不太使用的session对象删除。这样可以节省内存空间。
2)超时的时间如何设置
a, 大部分服务器默认的超时限制是30分钟。
b,可以修改服务器默认的超时限制,
比如, 可以修改tomcat的配置文件:
conf/web.xml
<session-config>
<session-timeout>30</session-timeout>
</session-config>
c, 也可以将以上配置放到某个应用的web.xml文件当中,此时,这个超时限制只对该应用起作用。
d, setMaxInactiveInterval(int seconds);
(5) 立即删除session invalidate();
2、session相关的案例
1)session验证
step1,在登录成功以后,在session对象上 绑订一些数据。比如:
session.setAttribute("user",User);
step2, 对于需要保护的资源,添加 session验证的代码,比如:
Object obj = session.getAttribute("user");
if(obj == null){
//没有登录
response.sendRedirect("login.jsp");
}
2)验证码
写一个CheckCodeServlet,生成一个验证码要求必须长度为5,并且随机从"A~Z,0~9"中选取。