Servlet
Servlet简介
Servlet是javaEE规范之一,是一个接口,是java提供的一个动态web资源开发技术,其中定义了五个方法。
interface Servlet {
public void service(ServletRequest servletRequest, ServletResponse servletResponse) ;
public void init(ServletConfig servletConfig) ;
public ServletConfig getServletConfig() ;
public String getServletInfo() ;
public void destroy() ;
}
Servlet的执行流程
- 服务器根据浏览器的请求得知访问的是项目中哪个Servlet类,根据@WebServlet注解中的值寻找,默认是第一次访问的时候被Tomcat服务器创建,可以使用@WebServlet的loadOnStartup参数修改成在服务器启动的时候创建。
- Servlet生命周期中涉及到三个方法,分别是init()、service()、destroy()
init方法在Servlet对象被创建的时候执行,只执行1次
service方法在Servlet被访问的时候调用,每访问1次就调用1次
destroy方法在Servlet对象被销毁的时候调用,只执行1次
Servlet生命周期
- 加载和实例化:默认情况下,当Servlet第一次被访问时,由容器创建Servlet对象
默认情况,Servlet会在第一次访问被容器创建,但是如果创建Servlet比较耗时的话,那么第一个访问的人等待的时间就比较长,用户的体验就比较差
@WebServlet(urlPatterns = "/demo1",loadOnStartup = 1)
loadOnstartup的取值有两类情况
(1)负整数:第一次访问时创建Servlet对象
(2)0或正整数:服务器启动时创建Servlet对象,数字越小优先级越高
- 初始化:在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象,完成一些如加载配置文件、创建连接等初始化的工作。该方法只调用一次
- 请求处理:每次请求Servlet时,Servlet容器都会调用Servlet的service()方法对请求进行处理
- 服务终止:当需要释放内存或者容器关闭时,容器就会调用Servlet实例的destroy()方法完成资源的释放。在destroy()方法调用之后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收
Servlet体系结构
HTTPServlet中的方法
protected void doGet(HttpServletRequest req, HttpServletResponse resp) ;
protected long getLastModified(HttpServletRequest req) ;
protected void doHead(HttpServletRequest req, HttpServletResponse resp) ;
protected void doPost(HttpServletRequest req, HttpServletResponse resp) ;
protected void doPut(HttpServletRequest req, HttpServletResponse resp) ;
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) ;
protected void doOptions(HttpServletRequest req, HttpServletResponse resp) ;
protected void doTrace(HttpServletRequest req, HttpServletResponse resp) ;
protected void service(HttpServletRequest req, HttpServletResponse resp) ;
public void service(ServletRequest req, ServletResponse res);
HttpServlet对HTTP协议进行了封装,serivce()方法根据HttpServletRequest参数中的信息进行处理,根据不同的请求方法调用对应的处理方法。
Request对象和Response对象
Request对象
- 浏览器按照HTTP协议规范根据不同的请求方式发送请求数据 (请求行+请求头+请求体)到Tomcat服务器
具体的格式如下
<方法><空格><URI><空格><HTTP版本> //第一行为请求行,要明确使用哪个方法
<字段名>:<字段值> //第二行开始为消息头,消息头的规格中定义关于项目的额外信息,长度几行到几十行不等
...
...
<空行>
<消息体> //最后是消息体(GET方法不需要填写数据,而POST方法需要将表单信息填入消息体中)
- Tomcat服务器对HTTP请求中的数据进行解析并将解析结果封装到Request对象中,后端就能使用Request中的数据进行业务处理
Response对象
- 业务处理完以后,后端将处理结果返回给前端,这个结果就封装到Response中
- Tomcat根据HTTP协议规则对Response进行解析,生成对应的http相应消息(响应行+响应头+响应体)
具体的格式如下
<http版本><空格><状态码><空格><响应短语> //第一行是状态码和响应短语,这两者内容一致,状态码第一位数字表示状态类型
<字段名>:<字段值> //如果网页还有图片等资源需要浏览器再次访问Web服务器
...
...
<空行>
<消息体>
Request继承体系
ServletRequest和HttpServletRequest都是java定义的接口,而并非实现类,HttpServlet的各个方法中都需要HttpServlet对象,这个对象实际上就是Tomcat中提供的HttpServletRequest是实现类RequestFacade
常用方法
1.请求行参数获取
- 获取请求方式
String getMethod()
- 获取虚拟目录(项目访问路径)
String getContextPath()
- 获取URL(统一资源定位符)
StringBuffer getRequestURL()
- 获取URI(统一资源标识符)
String getRequestURI()
- 获取请求参数(GET方式)
String getQueryString()
2.请求头参数
String getHeader(String name)
3.请求体参数
- 获取字节输入流,如果前端发送的是字节数据,比如传递的是文件数据,则使用该方法
ServletInputStream getInputStream()
- 获取字符输入流,如果前端发送的是纯文本数据,则使用该方法
BufferedReader getReader()
4.获取请求参数
- get方法
String getQueryString()
- post方法
BufferedReader getReader();
Response继承体系
与RequestFacade类似,是Tomcat中提供的HttpServletResponse的实现类
Response响应字符数据
- 通过Response对象获取字符输出流:
PrintWriter writer = resp.getWriter();
- 通过字符输出流写数据:
writer.write(“aaa”);
Response响应字节数据
- 通过Response对象获取字节输出流:
ServletOutputStream outputStream =resp.getOutputStream();
- 通过字节输出流写数据:
outputStream.write(字节数据);
- 字符流是专门用来处理文字的,而字节流主要是用来处理文字以外的如binary文件。
- Java中的字符在内部都是使用Unicode进行表示的,因此,要正确读取字符数据,需要知道字符的编码字符集,字符流提供编码字符集的指定,如果不指定使用系统默认的方式对字符数据进行编码转换,这个编码字符集不正确,会造成读进来的地字符出现乱码。
- 字节流虽然是读取二进制数据用的,但也可以读取字符文件,按字节进行处理,读进来之后可以根据编码字符集进行转换,也可以变成字符串。