1. 设置编码
1) doGet请求方式:
get方式目前不需要设置编码(基于tomcat8)
tomcat8 之前 , 设置编码:
如果是get请求发送的中文数据 , 转码稍微有点麻烦
String name = req.getParameter("name");
byte[] bytes = name.getBytes(); // 将参数打散
String s = new String(bytes, "UTF-8"); // 重新设置编码方式即可
//这样存入数据库的就不是乱码
2)doPost请求方式
// 使用这种方式设置编码 , 防止中文乱码
req.setCharacterEncoding("UTF-8");
/* 但是注意一定要在获取参数之前的使用这个方法 , 因为服务器是第一次获取参数的时候解析所有参
数,如果你没有在第一次获取参数之前就设置字符编码 , 那么这个方法是无效的.
但是这种方法只是在post方法里面使用才有效 , doGet无效!!!
*/
2. Servlet的继承关系
1) 继承关系
javax.servlet.Servlet 接口
javax.servlet.GenericServlet 抽象类
javax.servlet.Http.HttpServlet 实现子类
2) 相关方法
javax.servlet.Servlet 接口
void init(config) - 初始化方法
void service(request , response) - 服务方法
void destory - 销毁方法
service 方法 , 当客户端发送请求了 , 那么就会自动调用我们的service 方法 .
javax.servlet.GenericServlet 抽象类
public abstract void service 还是一个抽象方法
javax.servlet.Http.HttpServlet 实现子类
protected void service(request , response ) 实现方法
大概就是这样的 , 他就看的是你的请求方式 , 然后去调对应的方法 , 是post 那么就去调对应的dopsot方法。
我们进去看这个dopost方法
这个是javax.servlet.Http.HttpServlet类中的dopsot 方法 , 我们可以看到其实大概就是一个报错信息.其实这就是我们的405的报错的原因。因为我们发送请求的方式是get(method不写默认是get) ,但是你在Servlet里面又没有重写doget方法 , 重写的是dopost方法. 因为子类找不到 , 所以根据继承关系会去对应父类找 , 所以那么就调用javax.servlet.Http.HttpServlet 里面的doget 方法了 , 然后就抛出异常信息了405了。
小结:
-
继承关系:HttpServlet -> GenericServlet -> Serivce
-
Servlet 中的核心方法: init() , service() , destroy() , 我们的service方法其实 是tomcat容器调用的。
-
服务方法: 当有请求过来时 , service 方法会自动响应(其实是tomcat容器调用的) 在HttpServlet 中我们会去分析请求的方式:到底是get 、post 、head 还是 delete等等 然后再决定调用的是哪个do开头的方法 那么在HttpServlet中这些do方法默认都是405的实现风格--要我们子类去实现对应 方法 , 否则就会报405.
-
因此 , 我们在新建Servlet时 , 我们才会去考虑请求方法 , 从而决定重写哪个do方法
Servlet 的生命周期
1) 生命周期:从出生到死亡的过程 , 对应的Servlet中的三个方法.init() , service() ,
destroy()
2) 默认情况下:第一次接收请求时 , 这个Servlet会进行实例化(调用构造方法) 、初始(init())、
然后服务(service())、关闭容器(执行destroy()).
从第二次开始 , 每一次都是服务.
当容器关闭时 , 其中的所有的Servlet方法实例会被销毁、调用销毁方法
实例化 , 是tomcat 利用反射做的实例化.
3) 通过调用相关的方法发现:
单例 , 线程不安全....
Servlet 实例tomcat只会创建一个 , 所有的请求都是一个实例去响应的.
默认情况下 , 第一次请求时 , tomcat 才会去实例化 , 初始化 , 然后再去服务.
好处: 提高系统启动速度
缺点: 第一次响应的速度比较慢 , 响应时间比较长 .
默认情况下 , 如果需要提高系统的启动速度 , 当前的默认情况就是这样.第一次请求再创建
Servlet实例.
4) Servlet 的初始化时机
默认是第一次接收请求时, 实例化 , 初始化
但是为了提高第一次接收请求响应的速度 , 我们可以设置它的响应时机.在启动的系统的时
就去加载对应的类.
我们可以通过设置 <load-on-startup> 设置先后顺序 , 最靠前的是 0</load-on-startup>
5) Servlet 类 在容器中是单例的 , 线程不安全的. 正是因为是单例的 , 所以我们访问的变量,方
法是同一个 , 就可能出现不同线程 , 做同一个条件判断的时候会出现不同的结果.导致程序异常,这
种线程问题 . 在Java的多线程中讲的更加详细 , 比较经典的有售票问题……。
最好不要去定义一些成员变量 , 导致成员变量值被修改后出现一些程序异常!不可避免一定要定义,
请尽量不要拿去做条件判断 !
你访问那个页面 , 是向服务器发送请求 , 然后让服务器做出相应的反应. 比如把你需要的那个界面响
应给你.
HTTP协议
1、介绍
HTTP: HyperText Transfer Protocol 超文本传输协议 , HTTP最大的作用就是确定了请求和
响应数据的格式.浏览器发送给服务器的数据:请求报文; 服务器返回给浏览器的数据;响应报文
2、请求报文
1) Http 称为超文本传输协议
2) Http 是无状态的
3) Http 请求响应包含两个部分:请求和响应
请求:
请求包含三个部分
1. 请求行
2. 请求(消息)头
3. 请求主体
1) 请求行是三个信息: 1.请求的方式 2. 请求的URL 3. 请求的主体
2) 请求的消息头中包含了很多客户端需要告诉服务器的的信息 , 比如浏览器型号、版本、
能接收请求的类型.
3) 请求体 , 三种情况
get方式 , 没有请求体 , 但是有一个queryString
post方式 , 有请求体 , form data
json 格式 , 有请求体 , request payload
3、响应
响应包含三个信息: 1. 响应行 2. 响应头 3.响应体
1) 响应行包含三个信息: 1.协议 2. 响应状态码(200 , 404 , 405 , 500) 3. 响应状态
2) 响应消息头: 响应的实际内容(比如请求页面时, 响应的是一个表单)
会话
1) Http 是无状态的
- Http 无状态:服务器无法判断这两次请求是同一个客户端发过来的 , 还是不同的客户端发过来的
- 无状态带来的现实问题: 第一次请求时添加商品到购物车 , 第二次请求是结账; 如果这两次请求服务
器无法区分是同一个用户的 , 那么就会导致混乱.
- 通过会话跟踪技术来解决无状态的问题.
2) 会话跟踪技术
- 客户端第一次发送请求给服务器 , 服务器获取session , 获取不到 ,则创建新的 , 然后响应给客户
端
- 下次客户端给服务器发请求时,会把session 带个服务器 , 那么服务器就获取到这个客户端的
session Id , 这样服务器就能分辨不同的请求的客户端了.
相关Session 的 API
req.getSession(false);
req.getSession(true);
session.getId() -> 获取sessionID
session.isNew -> 获取session 是否是新的
session.getMaxInactiveInterval() -> session 的非激活时间最大间隔时长 默认1800秒 , 客
户端一直没有操作
session.setMaxInactiveInterval() -> session 设置非激活时间最大间隔时长