1.http协议
概念:超文本传输协议
作用:规范了浏览器和服务器的数据交互
特点:简单、快捷、无连接、无状态、HTTP1.1版本支持可持续链接
2.http的交互流程
(1)客户端与服务器端建立连接
(2)客户端发送请求数据到服务器(HTTP协议)
(3)服务器端接收到请求后,进行处理,然后将处理结果响应客户端(HTTP)
(4)关闭客户端和服务器端的连接(HTTP1.1后不会立即执行)
3.http协议之请求格式
请求格式结构:
请求头:请求方式,请求的地址和HTTP协议版本
请求行:消息报头,一般用来说明客户端要使用的一些附加信息
空行:位于请求和请求数据之间,空行是必须的
请求数据:非必须
4.HTTP协议之响应
响应格式的结构:
响应行(状态行):HTTP版本、状态码、状态信息
响应头:消息报头、客户端使用的附加信息
空行:响应头和响应实体之间
响应实体:正文、服务器返回给浏览器的信息
5.HTTP常见响应状态码含义
HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。
常见的状态码:
200 OK | 客户端请求成功 |
400 Bad Request | 客户端请求有语法错误,不能被服务器所理解 |
401 Unauthorized | 请求未经授权,这个状态码必须和www-Authenticate报头域一起使用 |
403 Forbidden | 服务器收到请求,但是拒绝提供服务 |
404 Not Found | 请求资源不存在,eg:输入了错误的URL |
500 Internal Server Error | 服务器发生不可预期的错误 |
503 Server Unavailable | 服务器当前不能处理客户端的请求,一段时间后可能恢复正常 |
6.servlet的生命周期
从第一次调用到服务器关闭
如果Servlet在web.xml中配置了load-on-startup,生命周期为从服务器启动到服务器关闭
(1)init()
init方法是对Servlet进行初始化的一个方法,会在Servlet第一次加载内容的时候被调用
(2)destory()
destory方法是在Servlet被销毁时执行,也就是服务器关闭时
(3)service()
service方法,真正处理请求的方法,可以处理get/post方式的请求,如果servlet中有Service方法,会优先调用service方法请求进行处理
(4)doGet()
处理get方式的请求
(5)doPost()
处理post方式的请求
注意:
如果在重写的service方法中调用父类的service方法(super.service(arg0,arg1)),则service方法处理完后,会再次根据请求方式响应doGet和doPost方法执行
我们一般不在重写的service中调用父类的sevice方法,避免出现405错误
7.servlet的常见错误
404错误:资源未找到
原因一:在请求地址中的servlet的别名书写错误
原因二:虚拟项目名称拼写错误
500错误:内部服务器错误
错误一:
java.lang.ClassNotFoundException:
解决:
在web.xml中校验servlet类的权限校验是否拼写错误
错误二:
因为service方法体的代码执行错误导致
解决:
根据错误提示对service方法体中的代码进行错误更改
405错误:请求方式不支持
原因:请求方式和servlet中的方式不匹配
解决:
尽量使用service方法进行请求处理,并且不要在service方法中调用父类的service
8.request对象
作用:request对象中封存了当前请求的所有请求信息
使用:
获取请求头数据
req.getMethod(); //获取请求方式
req.getRequestURL(); //获取请求URL信息
req.getRequestURI(); //获取请求URI信息
req.getScheme(); //获取协议
获取请求行数据
req.getHeader("键名"); //返回指定的请求头信息
req.getHeaderNames(); //返回请求头的键名的枚举集合
获取用户数据
req.getParameter("键名"); //返回指定的用户数据
req.getParameterValues("键名");//返回同键不同值的请求数据(多选),返回的数组
req.getParameterNames(); //返回所有用户请求数据的枚举集合
注意:
request对象由tomcat服务器创建,并作为实参传递处理请求servlet的service方法
public class requestServlet extends HttpServlet{ @Override protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { //获取请求头数据 //获取请求方式 String method = req.getMethod(); //获取请求URL StringBuffer url = req.getRequestURL(); //获取URI String uri = req.getRequestURI(); //获取协议 String h=req.getScheme(); //获取请求行数据 //获取指定的请求行信息 String value=req.getHeader("***"); //获取所有请求行的键的枚举 Enumeration e = req.getHeaderNames(); while(e.hasMoreElements()){ String name=(String) e.nextElement(); String value2=req.getHeader(name); } //获取用户数据 String name=req.getParameter("***"); String pwd=req.getParameter("***"); String[] favs=req.getParameterValues("***"); if(favs!=null){ for(String fav:favs){ System.out.println(fav); } } //获取所有的用户请求数据的键的枚举集合---req.getParmeterNames() } }
9.response对象
作用:用来响应数据到浏览器的一个对象
使用:
设置响应头
setHeader(String name,String value); //在响应头中添加响应信息,但是同键会覆盖
addHeader(String name,String value); //在响应头中添加响应信息,但是不会覆盖
设置响应状态
sendError(int num,String msg); //自定义响应状态码
设置响应实体
resp.getWrite().write(String str); //响应具体的数据给浏览器
设置响应编码格式:
resp.setContentType("text/html;charset=utf-8");
总结:
service请求处理代码流程:
设置响应编码格式
获取请求数据
处理请求数据
数据库操作(MVC思想)
响应处理结果
10.请求乱码问题解决
(1)使用String进行重新编码
uname=new String(uname.getBytes("iso8859-1"),"utf-8")
(2)Get方式请求
在service方法中使用:req.setCharacterEncoding("utf-8");
在tomact服务器目录下的conf文件下找到server.xml文件,打开进行如下配置:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" useBodyEncodingForURI="true" />
(3)Post方式请求
在service方法中使用:req.setCharacterEncoding("utf-8");
11.流程总结
(1)Servlet的使用流程:
设置请求编码格式
设置响应编码格式
获取请求信息
处理请求信息
响应处理结果
(2)数据流转流程
浏览器----->服务器----->数据库
浏览器<-----服务器<-----数据库
12.请求转发
作用:实现多个servlet联动操作处理请求,这样避免代码冗余,让servlet的职责更加明确
使用:
req.getRequestDispatcher("要转发的地址").forward(req,resp);
地址:相对路径,直接书写servlet的别名即可
特点:
一次请求,浏览器地址栏信息不变
注意:
请求转发后直接return结束即可
13.重定向
问题:
如果当前的请求,Servlet无法进行处理怎么办?
如果使用请求转发,造成表单数据重复提交怎么办?
解决:
使用重定向
使用:
response.sendRedirect("路径")
本地路径为:uri
网络路径为:定向资源的URL信息
特点:
两次请求,浏览器地址栏信息改变
时机:
如果请求中有表单数据,而数据又比较重要,不能重复提交,建议使用重定向
如果请求被Servlet接收后,无法进行处理,建议使用重定向定位可以处理的资源
14.Cookie
作用:解决了发送的不同请求的数据共享问题
使用:
Cookie的创建和存储
创建Cookie对象
Cookie c=new Cookie(String name,String value);
设置Cookie
设置Cookie有限期
c.setMaxAge(3*24*3600);
设置有效路径
c.setPath(String uri);
响应Cookie信息给客户端
resp.addCookie(c);
Cookie的获取
获取Cookie信息数组
Cookie[] cks=req.getCookies();
遍历数组获取Cookie信息
使用for循环遍历即可,示例:
if(cks!=null){
for(Cookie c:cks){
String name=c.getName();
String value=c.getValue();
System.out.println(name+":"+value);
}
}
Cookie信息校验
判断请求中是否携带正确的Cookie信息
如果有则校验Cookie信息是否正确
如果校验正确则直接响应主页面给用户
如果检验不正确则响应登陆页面给用户
没有则请求转发给登陆界面
注意:
一个Cookie对象存储一条数据,多跳数据可以多个Cookie对象进行存储
特点:
浏览器的数据存储技术
存储数据声明在服务器端
临时存储:存储在浏览器的运行内存中,浏览器关闭即失效
定时存储:设置了Cookie的有效期,存储在客户端的硬盘中,在有效期内符合路径要求的请求都会附带该信息
默认Cookie信息存储好以后,每次请求都会覆盖,除非设置有效路径
15.Session
作用:解决同一用户不同请求处理的数据共享问题
原理:
用户第一次访问服务器,服务器会创建一个session对象给此用户,并将该session对象的JSESSIONID使用Cookie技术存储到浏览器中,保证用户的其他请求获取到同一个session对象,也保证了不同请求能够获取到共享的数据
特点:
存储在服务器
服务器进行创建
依赖Cookie技术
有效期:一次会话
在JSESSIONID和SESSION对象不失效的情况下为整个项目内
默认存储时间是30分钟
使用:
创建session对象/获取session对象
HttpSession hs=req.getSession();
如果请求中拥有session的标识符也就是JSESSIONID,则返回其对应的session对象
如果请求中没有session的标识符也就是JSESSIONID,则创建新的session对象,并将其JSESSIONID作为cookie数据存储到浏览器内存中
如果session对象失效了,也会重新创建一个session对象,并将其JSESSIONID存储在浏览器内存中
设置session存储时间
hs.setMaxInactiveInterval(int seconds);
注意:
在指定的时间内session对象没有被使用则销毁,如果使用了则重新计时
设置session强制失效
hs.invalidate();
存储和获取数据
存储:hs.setAttribute(String name,Object value);
获取:hs.getAttribute(String name)返回的数据类型为Object
注意:
存储的动作和取出的动作可以发生在不同的请求中,但是存储要先于取出执行
使用时机:
一般用户在登陆web项目时会将用户的个人信息存储到Session中,供该用户的其他请求使用
session失效处理:
将用户请求中的JSESSIONID和后台获取到的SESSION对象的ID进行比对,如果一致则session没有失效,如果不一致则证明session失效了。重定向到登陆界面,让用户重新登陆。
注意:
JSESSIONID存储在cookie的临时存储空间中,浏览器关闭即失效
16.ServletContext
作用:解决了不同用户的数据共享问题
原理:
ServletContext对象由服务器进行创建,一个项目只有一个对象,不管在项目的任意位置进行获取得到的都是同一个对象,那么不同用户发起的请求获取的也就是同一个对象,该对象由用户共同拥有。
特点:
服务器进行创建
用户共享
一个项目只有一个
生命周期:
服务器启动到服务器关闭
作用域:
整个项目内
使用:
获取ServletContext对象
第一种方式:
ServletContext sc=this.getServletContext();
第二种方式:
ServletContext sc=this.getServletConfig.getServletContext();
第三种方式:
ServletContext sc=req.getSession().getServletContext();
使用ServletContext对象完成数据共享
数据存储
sc.setAttribute(String name,Object value);
数据获取
sc.getAttribute("str")返回的是object类型
注意:
不同的用户可以给ServletContext对象进行数据的存取
获取的数据不存在返回null
获取web.xml中的全局配置
sc.getInitParameter(String name); 根据键的名字返回wed.xml中配置的全局数据的值,返回String类型,不存在返回null
sc.getInitParameterNames(); 返回键名的枚举
配置方式:一组<context-param>标签只能存储一组键值对数据,多组可以声明多个进行存储
<context-param>
<param-name>name</param-name>
<param-value>zhangsan</param-value>
</context-param>
作用:将静态数据和代码进行解耦
获取webroot下资源的绝对路径
String path=sc.getRealPath("/doc/*.txt");
获取的路径为项目根目录,path参数为项目根目录中的路径
获取webroot下资源的流对象
InputStream is = sc.getResourceAsStream(String path);
注意:
此种方式只能获取项目根目录下资源流对象,class文件的流对象需要使用类加载器获取
17.ServletConfig
作用:ServletConfig对象是Servlet的专属配置对象,每个Servlet都单独拥有一个ServletConfig对象,用来获取web.xml中的配置信息
使用:
获取ServletConfig对象
ServletConfig sc=this.getServletConfig();
获取web.xml中的配置数据
String code=sc.getInitParameter("config");
18.web.xml文件使用总结
作用:
存储项目相关的配置信息,保护Servlet。解耦一些数据对程序的依赖
使用位置:
每个Web项目中
Tomcat服务器中(在服务器目录conf目录中)
区别:
Web项目下的web.xml文件为局部配置,针对本项目的位置
Tomcat下的web.xml文件为全局配置,配置公共信息
内容(核心组件):
全局上下文配置(全局配置参数)
Servlet配置
过滤器配置
监听器配置
加载顺序:
Web容器会按ServletContext->context-param->listener->filter->servlet这个顺序加载组件,这些元素可配置在web.xml文件中的任意位置。