Servlet简介
Servlet是运行在Web服务器上的应用程序。Servlet本身是一个Java接口,它定义了浏览器访问服务器程序的规则,我们写服务器程序只需要按照需求复写Servlet方法即可。
Servlet快速入门
1. 编写Servlet实现类
//实现Servlet接口,按 alt+enter-->implement methods实现所有抽象方法。
public class ServletDemo1 implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init...执行了");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("service...执行了");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
System.out.println("destroy...执行了");
}
}
2. 配置Servlet访问路径
每写一个Servlet实现类,需要在web.xml文件中进行配置。
<!--配置ServletDemo1的全类名 -->
<servlet>
<servlet-name>ServletDemo1</servlet-name>
<servlet-class>cn.itheima.servlet.ServletDemo1</servlet-class>
</servlet>
<!--配置浏览器访问ServletDemo1的路径-->
<servlet-mapping>
<servlet-name>ServletDemo1</servlet-name>
<url-pattern>/ServletDemo1</url-pattern>
</servlet-mapping>
3. 访问Servlet
在浏览器地址栏访问 http:\localhost:8080\servlet\ServletDemo1 查看IDEA控制台,会先执行init方法,再执行service方法。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mT5jZtgK-1612715317876)(assets/1585489139740.png)]
当关闭服务器的时候,destroy执行了
4. Servlet的执行流程
从浏览器发送请求给服务器,到服务器处理Servlet作出响应的流程,如图所示
Servlet体系结构
-
HttpServletRequest对象
当浏览器访问服务器时,tomcat会对Http请求的数据进行解析,并封装为HttpServletRequest对象
-
HttpServletReponse对象
当服务器给浏览器返回数据时,需要将数据封装为HttpServletReponse对象,然后用流往浏览器进行输出。
Servlet映射方式
一个Servlet可以对应多个映射路径,也就是说浏览器访问不同的路径可以对应同一个Servlet。
<!--一个servlet映射多个访问路径-->
<servlet>
<servlet-name>ServletDemo4</servlet-name>
<servlet-class>com.itheima.servlet.ServletDemo4</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo4</servlet-name>
<url-pattern>/servletDemo4/*</url-pattern>
</servlet-mapping>
Servlet创建时机
Servlet默认是在第一次访问时被创建,如果想要在服务器启动时被创建,需要在web.xml文件中进行配置。
添加<load-on-startup>1</load-on-startup>
配置即可,值越小优先级越高。
<servlet>
<servlet-name>ServletDemo4</servlet-name>
<servlet-class>com.itheima.servlet.ServletDemo4</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo4</servlet-name>
<url-pattern>/ServletDemo4</url-pattern>
</servlet-mapping>
ServletConfig配置
ServletConfig是Servlet的配置对象,每一个Servlet都有专属的ServletConfig用来存储一些配置信息。当Servlet被创建时就会创建一个ServletConfig,同时Servlet被销毁时ServletConfig也随之销毁。
- 给ServletConfigDemo1配置初始化参数
<servlet>
<servlet-name>servlerConfigDemo1</servlet-name>
<servlet-class>com.itheima.servletconfig.ServletConfigDemo1</servlet-class>
<!--Servlet初始化参数-->
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>desc</param-name>
<param-value>这是一个ServletConfigDemo</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>servlerConfigDemo1</servlet-name>
<url-pattern>/servlerConfigDemo1</url-pattern>
</servlet-mapping>
- 获取ServletConfigDemo1的初始化参数
public class ServletConfigDemo extends HttpServlet {
private ServletConfig servletConfig;
@Override
public void init() throws ServletException {
//获取ServletConfig
this.servletConfig = getServletConfig();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取所有的配置名称
Enumeration<String> keys = servletConfig.getInitParameterNames();
while (keys.hasMoreElements()) {
String key = keys.nextElement();
//根据配置名称获取值
String value = servletConfig.getInitParameter(key);
//打印键和值
System.out.println(key+"..."+value);
}
//获取ServletConfig(下面有讲是什么意思)
ServletContext servletContext = servletConfig.getServletContext();
System.out.println(servletContext);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
ServletContext对象
ServletContext代表整个Web应用,每一个应用只有一个ServletContext对象。常用于配置和获取应用的全局初始化参数,可以实现Servlet之间的数据共享。
配置全局参数
<!--配置全局编码-->
<context-param>
<param-name>globalEncoding</param-name>
<param-value>utf-8</param-value>
</context-param>
<!--配置全局描述信息-->
<context-param>
<param-name>globalDesc</param-name>
<param-value>utf-8</param-value>
</context-param>
获取全局参数
//获取ServletContext
ServletContext servletContext = getServletContext();
//获取全局参数globalEncoding的值
String globalEncofing = servletContext.getInitParameter("globalEncoding");
System.out.println(globalEncofing);
//获取全局参数globalDesc的值
String globalDesc = servletContext.getInitParameter("globalDesc");
System.out.println(globalDesc);
获取真实路径
在本地电脑上写代码一般都是写的相对路径,但是项目最终会发布到服务器上,需要把本地路径转换为服务器路径,才能被访问到。
//获取ServletContext对象
ServletContext servletContext = req.getServletContext();
//虚拟目录
String contextPath = servletContext.getContextPath();
System.out.println(contextPath);
//获取虚拟目录的绝对路径
String servletContextRealPath = servletContext.getRealPath("/");
System.out.println(servletContextRealPath);
//获取web/a.txt的绝对路径
String webPath = servletContext.getRealPath("/a.txt");
System.out.println(webPath);
//获取web/WEB-INF/a.txt的绝对路径
String webInfPath = servletContext.getRealPath("/WEB-INF/a.txt");
System.out.println(webInfPath);
//获取src/a.txt的绝对路径
String srcPath = servletContext.getRealPath("WEB-INF/classes/a.txt");
System.out.println(srcPath);
Servlet间数据共享
- 在Servlet1中设置数据
public class Servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置共享数据
servletContext.setAttribute("username","zhangsan");
servletContext.setAttribute("password","123");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
- 在Servlet2中获取数据
public class Servlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取username的值
Object username = servletContext.getAttribute("username");
System.out.println(username);
//获取password的值
Object password = servletContext.getAttribute("password");
System.out.println(password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
Servlet注解开发
我们发现,每次写一个Servlet都需要在web.xml文件中写大量的配置,非常麻烦。好消息来了,在Servlet3.0以后的版本提供了Servlet注解配置,大大简化了代码编写。
//@WebServlet注解配置Servlet访问路径
@WebServlet("/servletDemo5")
public class ServletDemo5 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servlet执行了");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
浏览器直接访问 http://localhost:8080/day02_servlet/servletDemo5就可以了