目录
为什么我们常常继承HttpServlet 而不是 Servlet
HttpServletResponse接口
HttpServletRequest
get post 请求有关的编码问题
默认欢迎网站
Http的状态码
常见的状态码:
disk cache 的作用
servlet之间调用方式
重定向
请求转发
附:哈希map的区别
为什么我们常常继承HttpServlet 而不是 Servlet
在说明这个之前,我们应该先了解servlet的继承体系。
以下是httpServlet的只要继承体系
先从顶层父类Servlet说起
在Servlet接口中有5个方法
这些方法在直接通过继承的方式的话,每次都需要写重写。通常而在servlet方法中我们时常只关心service方法。
于是通过适配器模式的设计可以有以下类。
在其子类GenericServlet中
对以上四个不常用的方法进行了空实现 ,如:
未对service方法进行实现
对于网页中时常通过get,post 的提交方式,让我们后端通过servlet进行获取。这是我们需要用到doGet ,doPost等表单提交的方法。
在这里HttpServlet 方法对其中serivice方法进行重写,主要针对表单提交方式的重写。
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();
long lastModified;
if (method.equals("GET")) {
lastModified = this.getLastModified(req);
if (lastModified == -1L) {
this.doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader("If-Modified-Since");
} catch (IllegalArgumentException var9) {
ifModifiedSince = -1L;
}
if (ifModifiedSince < lastModified / 1000L * 1000L) {
this.maybeSetLastModified(resp, lastModified);
this.doGet(req, resp);
} else {
resp.setStatus(304);
}
}
} else if (method.equals("HEAD")) {
lastModified = this.getLastModified(req);
this.maybeSetLastModified(resp, lastModified);
this.doHead(req, resp);
} else if (method.equals("POST")) {
this.doPost(req, resp);
} else if (method.equals("PUT")) {
this.doPut(req, resp);
} else if (method.equals("DELETE")) {
this.doDelete(req, resp);
} else if (method.equals("OPTIONS")) {
this.doOptions(req, resp);
} else if (method.equals("TRACE")) {
this.doTrace(req, resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[]{method};
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}
}
于是我们写servlet时就需要对 HttpServlet 进行继承。然后去重写其中我们常用的doGet,doPost的方法。
HttpServletResponse接口
主要功能:
- HttpServletResponse接口负责将Servlet运行结果以二进制形式写入到响应体
public class oneServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String str="hello Servlet";
//通过响应对象向tomcat借一个输出流使用
PrintWriter out = response.getWriter();
//通过输出流将结果以二进制的形式写入响应体
//这个意思就是把str内容写进response中
out.print(str);
}
2.HttpServletResponse 接口负责设置相应包中响应头中content-type属性 控制浏览器采用对应的解析器和编译器对响应体中二进制数据进行处理
3. 通过响应对象将地址写入到响应头中location
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通过响应对象将地址写入到响应头中location
String url = "http://www.baidu.com";
response.sendRedirect(url);
//1.tamcat发现响应头中location属性被赋值,此时将产生一个302状态并写道响应包中状态行
//2.tomcatz负责推送响应包返回发生请求的浏览器
//3.浏览器收到后,读取状态行中302状态码。此时浏览器直接读取响应头中location中地址并更新到浏览器的地址栏上
//4.由于在浏览器启动时,自动生成一个线程对象用于扫描地址栏,当发现地址改变时,会要求浏览器根据地址发生新的请求
}
HttpServletRequest
主要功能
1.读取请求包请求行的信息【url,method】
用getParmarter()获取想要的信息
2.读取请求浏览包中请求头或则求体中参数信息
3.代替浏览器向tomcat索要资源
值得注意的一点:
在html中 只有checkbox标签在提交表单时一个参数可以带多个值
在servlet后端 getParameter 只能接收一个值,要用上getParametervalues 将这些值装到string的数组中
get post 请求有关的编码问题
问题:
以get方式发送中文参数内容能被正常读取
以post方式发送中文请求,会的到乱码
产生原因:
二者都以二进制的形式发送 但:
tomcat服务器解析请求头 默认utf-8
请求体 由当前的请求对象解析 ios-8859-1
所以导致浏览器解析时错误
解决方案:在post请求方式下,应该先让请求对象使用utf-8进行解析,然后再读取
request .setCharacterEncoding("utf-8");
默认欢迎网站
一般用户在请求某个网页时,没有请求servlet的后端资源,可以设置一个默认资源网页
在自己的web.xml文件中可以设置
Http的状态码
介绍:
1.由http服务器生成的一个三位数字符号
2.状态码表示本次通信的状态同时可以要求浏览器接受到响应包之后的行为‘
3.状态码分为五个大类(1XX,2XX,3XX,4XX,5XX)
常见的状态码:
200:http服务器将浏览器请求的资源进行了返回302:http服务器通知浏览器到响应头中location中读取请求地址,并要求浏览器将得到请求地址更新到浏览器地址栏 (说白了就是提醒浏览器地址转换)404:找不到资源405:Http服务器通知浏览器本次索要的资源找到了,但是请求方式无法接收。500:Http服务器通知浏览器本次索要的资源文件已经找到,但由于资源文件在处理过程出现了异常因此无法提供服务。异常:并不是命令写错了,命令使用数据不满足条件。
disk cache 的作用
代表从本地缓存中拿请求地址
servlet之间调用方式
重定向
依赖命令: 请求其他网站地址 response.sendRedirect("url");
请求自己网站地址 response.sendRedirect("uri");
特征:重定向过程中至少发送两次请求
通过重定向调用的Servlet接收的请求方式(一定是get方式)因为其第二次发起请求是由浏览器发起的 ,因此一定是get
请求转发
依赖命令:
//通过请求对象获取资源申请对象
RequestDispatcher report = request.getRequestDispatcher("地址");
//将资源申请对象发送给tomcat
report.forword()
特征:请求转发过程中只发了一次
两个Servlet共享请求协议包
两个servlet请求方式保持一致
Servlet之间的共享方案 1.ServletContext接口1)ServletContext接口来自Servlet规范
2)ServletContext接口实现类有http服务器厂商提供
3)ServletContext接口修饰对象被称为全局作用域对象
4)来自同一个网站下Servlet都可以去使用全局作用域进行数据共享
在使用过程中,我们的web网站中的某个Servlet通过全局作用域对象向另一个servlet提供数据
具体方式:
运行OneServlet ------- 通过request向tomcat要当前网站全局作用域对象
ServletContext application =request.getServletContext();
---------随后将自己的数据添加到ServletContext对象中作为共享数据
appcalition.setAttribute("键","值");
运行TowServlet ---------通过request向tomcat要当前网站全局作用域对象
ServletContext application =request.getServletContext();
-------读取数据
application.getAttribute("key");
生命周期:
由于ServletContext是我们向服务器讨要的,于是对于其生命周期就不同于servlet:
其生命周期自tomcat创建起,到tomcat关闭,一直存在,并且一个网站中有且只有一个全局作用域对象。
所以开发中尽量避免往里面存数据。
2.cookie介绍:
1)来自于Servlet规范中提供一个工具类
2)如果两个Servlet为同一个浏览器提供服务,此时借助于用户的cookie实现数据共享
3.HttpSession接口 4.HttpServletRequest接口



