1.设置编码
tomcat8之前,设置编码∶
1 ) get请求方式:
get方式目前不需要设置编码(基于tomcat8 )
如果是get请求发送的中文数据,转码稍微有点麻烦( tomcat8之前)
string fname = request.getParameter ( "fname" );
1.将字符串打散成字节数组
byte[] bytes = fname.getBytes ("ISO-8859-1");
2.将字节数组按照设定的编码重新组装成字符串
fname = new string (bytes , "UTF-8");
2 ) post请求方式:
request.setcharacterEncoding ( "UTF一8") ;
tomcat8开始,设置编码,只需要针对post方式
注意:
需要注意的是,设置编码这句代码必须在所有的获取参数动作之前
2.Servlet的继承关系——重点是服务方法service()
1.继承关系
javax.servlet.servlet接口
javax.servlet.Genericservlet抽象类
javax.servlet.http.Httpservlet抽象子类
2.相关方法
javax.servlet.servlet接口:
void init (config)-初始化方法
void service(request, response)-服务方法
void destory () -销毁方法
javax.servlet.GenericServlet抽象类∶
void service (request , response)-仍然是抽象的
javax.servlet.http.Httpservlet抽象子类︰
void service (request,response) -不是抽象的
javax.servlet.http.Httpservlet抽象子类∶
void service (request,response) -不是抽象的
1.string method = req.getMethod ();获取请求的方式
2.各种if判断,根据请求方式不同,决定去调用不同的do方法
if (method.equals("GET")) {
this.doGet(req, resp);
} else if (method.equals("HEAD")) {
this.doHead(req, resp);
} else if (method.equals("POST")) {
this.doPost(req, resp);
} else if (method.equals("PUT")) {
this.doPut(req, resp);
}
3.在Httpservlet这个抽象类中,do方法都差不多:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String msg = lStrings.getString("http.method_get_not_supported");
this.sendMethodNotAllowed(req, resp, msg);
}
3.小结:
1)继承关系:Httpservlet -> Genericservlet -> servlet
2) servlet中的核心方法: init() , service() , destroy ()
3)服务方法:当有请求过来时,service方法会自动响应(其实是tomcat容器调用的)
在Httpservlet中我们会去分析请求的方式∶到底是get、post、head还是delete等等然后再决定调用的是哪个do开头的方法。那么在Httpservlet中这些do方法默认都是405的实现风格-要我们子类去实现对应的方法,否则默认会报405错误。
4)因此,我们在新建servlet时,我们才会去考虑请求方法,从而决定重写哪个do方法
3.Servlet的生命周期
1)生命周期∶从出生到死亡的过程就是生命周期。对应servlet中的三个方法:init ( ) , service ( ) , destroy ()
2 )默认情况下∶
第一次接收请求时,这个servlet会进行实例化(调用构造方法)、初始化(调用init())、然后服务(调用service()),从第二次请求开始,每一次都是服务
当容器关闭时,其中的所有的servlet实例会被销毁,调用销毁方法
package com.atguigu.servlets;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import java.io.IOException;
/**
* @author pengyang
* @date 2022-05-12 17:01
*/
public class Demo02Servlet extends HttpServlet {
private Demo02Servlet() {
System.out.println("正在实例化....");
}
@Override
public void init() throws ServletException {
System.out.println("正在初始化....");
}
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("正在服务....");
}
@Override
public void destroy() {
System.out.println("正在销毁....");
}
}
3 )通过案例我们发现︰
- servlet实例tomcat只会创建一个,所有的请求都是这个实例去响应。
- 默认情况下,第一次请求时,tomcat才会去实例化,初始化,然后再服务.这样的优点是提高系统的启动速度,缺点是第一次请求时,耗时较长。因此,如果需要提高系统的启动速度,当前默认情况就是这样。如果需要提高响应速度,我们应该设置servlet的初始化时机
4 ) servlet的初始化时机: - 默认是第一次接收请求时,实例化,初始化。
- 我们可以通过来设置servlet启动的先后顺序,数字越小,启动越靠前,最小值0。
5 ) servlet在容器中是︰单例的、线程不安全的 - 单例:所有的请求都是同一个实例去响应
- 线程不安全:一个线程需要根据这个实例中的某个成员变量值去做逻辑判断。但是在中间某个时机,另一个线程改变了这个成员变量的值,从而导致第一个线程的执行路径发生了变化
- 我们已经知道了servlet是线程不安全的,给我们的启发是︰尽量的不要在servlet中定义成员变量。如果不得不定义成员变量,那么不要去:1.不要去修改成员变量的值。2.不要去根据成员变量的值做一些逻辑判断