前言
如果区分不开JSP和Servlet的小伙伴们,可以看这篇博客,里面有描述JSP的本质和脚本,内置对象所在Servlet对应的对象及方法!!!!!!
一、什么是Servlet?
servlet是一个符合特定规范的java程序,是一个基于java技术的Web组件,主要用于生成动态页面内容,Servlet在服务器端运行,由Servlet容器管理。
二、Servlet工作原理
浏览器发送第一次请求时,会判断该请求的url是静态资源还是动态资源,如果是静态资源直接交给web服务器去处理,并且响应给浏览器,否,是动态资源web服务器处理不了会把请求的request和reponse对象交给Web容器去处理,Web容器将Servlet进行实例化和初始化(仅限于第一次请求),将这两个对象交给servlet去处理逻辑,并且生成页面,响应给Web服务器,Web服务器响应给浏览器。
静态资源: html、css、视频等等
动态资源: jsp,servlet等.
Web容器: 用来处理动态资源,可以被称为Servlet容器或JSP容器(因为JSP本质上就是一个Servlet)。
Web服务器: 只能处理静态资源,处理不了动态资源。
TomCat服务器:包含Web服务器和Web容器,所以可以称为Web服务器又称为Web容器。
图下的servlet可以看作是一个个java程序,实现不同的功能!。
三、Servlet&JSP
Servlet和JSP都可以动态生成页面内容,但是在使用它们两个开发Web程序时,就导致了各种问题:
JSP: Html+java, java代码是使用脚本写在Html中的,这就导致处理逻辑很不方便简洁(如: 拼接脚本) 。
问题示例:
servlet: java+Html ,servlet也可以生成动态内容,但是它必须把整个HTML打印到一个输出流,再serlvet的out.println()格式化很糟糕。
问题示例:
Servlet和JSP的互补!
如上图所示: servlet处理html页面很繁琐,JSP处理java逻辑代码也很繁琐,那么,他们的问题是不是正好互补呢?我们正可以使用他们各自的优点进行一个互补,如: 使用servlet去处理程序逻辑并获取动态内容,而JSP负责拿到值去渲染页面。所以这就是为什么他们明明都可以处理动态内容,却各司其职了。
四、Servlet的体系结构
4.1Servlet API 两个重要的包
1 .java.servlet
包中的类和接口是通用的不依赖Http协议的Servlet ApI。
包中的接口
Servlet 接口体系
## 1.Servlet初始化
void init(ServletConfig var1) throws ServletException;
## 2.获取ServletConfig 配置
ServletConfig getServletConfig();
## 3.Servlet服务
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
## 4.获取Servlet信息
String getServletInfo();
## 5.销毁Servlet
void destroy();ServletConfig 用于Servlet的一系列配置
## 1.获取Servlet名称 String getServletName(); ## 2.获取Servlet上下文对象(作用于整个Web应用) ServletContext getServletContext(); ## 3.获取Servlet初始化参数 String getInitParameter(String var1); ## 4.获取所有初始化参数的名称 Enumeration<String> getInitParameterNames();
Serializable 可序列化接口
ServletRequest 接口
## 常用应用方法 ## 1.获取请求属性 Object getAttribute(String var1); ## 2.设置请求编码格式 void setCharacterEncoding(String var1) throws UnsupportedEncodingException; ## 3.获取请求参数 String getParameter(String var1); ## 总结 剩下的方法此处省略不写,如想深入研究,可以查看源码。
ServletResponse 接口
## 常用应用方法 ## 1.获取输入流 PrintWriter getWriter() throws IOException; ## 2.设置响应编码格式 void setCharacterEncoding(String var1); ## 3.设置响应页面格式 void setContentType(String var1); ## 总结 剩下的方法此处省略不写,如想深入研究,可以查看源码。
可能还有一些,就不做了解了(目前只知道这些)
包中的接口实现类
GenericServlet 实现了以上三个接口,是一个抽象类
## 主要应用方法 ## 1.实例化Servlet 构造方法 public GenericServlet() {} ## 2.实现销毁方法 public void destroy() {} ## 3.service抽象服务方法 public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; ## 总结 剩下的方法大部分都是实现于该包中接口的方法,此处省略不写,如想深入研究,可以查看源码。
1 .java.servlet.http
该包中的类都是有http协议的,使用http协议来写Web应用程序,都用该包中的类。
包中的类
HttpServlet 继承于GenericServlet抽象类,并且实现了部分方法。
## 该类将GenericServlet里的服务抽象方法做了一个重写,并且根据不同的请求方法进行了判断。 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getMethod(); long lastModified; if (method.equals("GET")) { ............ } } else if (method.equals("HEAD")) { .... } 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 { ....... resp.sendError(501, errMsg); } }
Http ServletRequest(继承于ServletRequest,并且实现了部分方法)。
Http ServletResponse (继承于ServletResponse,并且实现了部分方法)。
五、创建Servlet
5.1 注解
## 继承HttpServlet HelloServlet extends HttpServlet ## @WebServlet(name="hello",urlPatterns = "/hello") name代表Servlet的名字 urlPatterns 代表该请求由当前Servlet来处理
5.2 Web.xml
<servlet> <servlet-name>hello</servlet-name> <servlet-class>servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> ## 总结 servlet标签: 配置一个Servlet servlet-name:servlet的名字 servlet-class:servlet的路径 servlet-mapping标签: 映射配置的servlet servlet-name: 映射servlet名字 url-pattern:配置servlet处理的请求地址 ------- / 拦截所有的请求,除了.jsp请求 ------- /* 拦截所有的请求
六、Servlet的生命周期
概述:
Servlet的生死是由Web容器决定的,Web容器负责拿到Web服务器转交的请求资源(对象),然后去实例化一个Servlet,随后再初始化,让它成为一个真正的Servlet,再将资源对(request,response)转交给servlet实例去进行逻辑操作,(如果服务器关闭,那么Web容器会自动调用销毁对象)。
6.1 实例化
## Servlet容器(又称Web容器)创建Servlet的实例。 public GenericServlet(){} 或 public HttpServlet(){}
Web容器自动调用无参构造方法
6.2 初始化
## 对Servlet进行一系列配置,成为一个真正的Servlet void init(ServletConfig var1){};
6.3 服务
## 如果请求Servlet,则容器调用service()方法,进行判断请求方式 public void service(ServletRequest var1, ServletResponse var2){...}
6.4 销毁
## 销毁实例之前Web容器调用destory()方法 public void destroy() {}
Web容器将Servlet实例化的注意点
如果浏览器第一次请求时,Web容器已经实例化了一个Servlet,那么等该Servlet再一次请求时,Web容器不会再次实例化和初始化,直接调用服务操作,(因为第一次请求时容器就保存了Servlet的实例)