# Servlet
## Servlet 简介
Java Servlet是和平台无关的服务器端组件,**它运行在Servlet容器中。Servlet容器负责Servlet和客户的通信以及调用Servlet的方法,Servlet和客户的通信采用“请求/响应”的模式**。
Servlet可完成如下功能:
创建并返回基于客户请求的动态HTML页面。
创建可嵌入到现有HTML 页面中的部分HTML 页面(HTML 片段)。
与其它服务器资源(如数据库或基于Java的应用程序)进行通信。
![](https://box.kancloud.cn/5ff9c18c15e248758a9bf66a76150dd9_999x332.png)
Servlet本质上就是一个运行在Servlet容器中的Java类,现在充当Servlet容器的就是我们刚刚安装的Tomcat
***
### 第一个Servlet——HelloWorld
1.创建一个Java类实现Servlet接口,并实现其中所有的方法;
~~~
package com.neusoft.javaweb;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class HelloServlet implements Servlet{
// 构造器
public HelloServlet() {
System.out.println("构造器");
}
@Override
public void init(ServletConfig arg0) throws ServletException {
// TODO Auto-generated method stub
System.out.println("init");
}
@Override
public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("service");
}
@Override
public ServletConfig getServletConfig() {
System.out.println("getServletConfig");
return null;
}
@Override
public String getServletInfo() {
System.out.println("getServletInfo");
return null;
}
@Override
public void destroy() {
// TODO Auto-generated method stub
System.out.println("destroy");
}
}
~~~
2.在web.xml配置和映射Servlet;
~~~
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<!-- 配置和映射Servlet -->
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.neusoft.javaweb.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
~~~
其中
~~~
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.neusoft.javaweb.HelloServlet</servlet-class>
</servlet>
~~~
表示的是为com.neusoft.javaweb.HelloServlet代表的类注册一个名字为helloServlet(类似于为游戏角色创建一个角色名),helloServlet是可以自己随意定制的
~~~
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
~~~
表示的是为helloServlet映射一个访问路径/hello(类似于提供一个能够访问到游戏角色的方式,其中/代表我们web应用的根目录,即[http://localhost:8080/ykbbs/](http://localhost:8080/ykbbs/),也就是WebContent目录)。
3.运行Tomcat,在浏览器中输入[http://localhost:8080/ykbbs/hello](http://localhost:8080/ykbbs/hello),可以发现控制台输出了一些内容,首先是构造器,然后是init,再然后是service,然后每次刷新,每次都只出现了service,然后关闭服务,发现出现destory。
***
### Servlet的生命周期
①服务器加载Servlet
②创建Servlet实例
--只有第一次请求Servlet时,创建Servlet实例,调用构造器
③初始化init()
--只被调用一次,在创建好实例后立即被调用,用于初始化当前Servlet
④service()处理用户请求
--可以被多次调用,每次请求都会调用service方法,实际用于响应请求的
⑤destory()销毁
--只被调用一次,在当前Servlet所在的WEB应用被卸载前调用,用于释放当前Servlet所占用的资源
***
### load-on-startup
可以指定Servlet被创建的时机
~~~
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.neusoft.javaweb.HelloServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
~~~
在加载完Servlet后直接就创建了Servlet实例,并进行了初始化,在此期间我们并没有提出请求。
如果配置了多个Servlet, load-on-startup的值越小越先启动(包括0,负数不会被启动,还是需要发出请求才创建实例并初始化);
***
## 注意:服务器不要空跑,保证有WEB应用在运行,否则不会有任何效果。
### Servlet映射细节
在Servlet映射到的URL中也可以使用 * 通配符,但是只能有两种固定的格式:
一种格式是“* .扩展名”
~~~
<servlet-mapping>
<servlet-name>AnyName</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
~~~
另一种格式是以正斜杠(/)开头并以“/ * ”结尾。
~~~
<servlet-mapping>
<servlet-name>AnyName</servlet-name>
<url-pattern>/action/*</url-pattern>
</servlet-mapping>
~~~
#### **注意:既带 / 又带 * 的,又带扩展名的,是不合法的(例如:/*.do)。**
***
### ServletConfig
封装了Servlet配置信息,并可以获取ServletContext对象
它有4个方法:
**getInitParameterNames**获取初始化参数的名字(集合)
**getInitParameter**(获取初始化参数)
**getServletName**
**getServletContext**
①配置Servlet的初始化参数
~~~
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.neusoft.javaweb.HelloServlet</servlet-class>
<init-param>
<!-- 参数名 -->
<param-name>user</param-name>
<!-- 参数值 -->
<param-value>root</param-value>
</init-param>
<init-param>
<!-- 参数名 -->
<param-name>password</param-name>
<!-- 参数值 -->
<param-value>1230</param-value>
</init-param>
<load-on-startup>-1</load-on-startup>
</servlet>
~~~
配置在Servlet当中,且必须在load-on-startup之前
②获取Servlet的初始化参数
~~~
public void init(ServletConfig servletConfig) throws ServletException {
String user = servletConfig.getInitParameter("user");
System.out.println("user:"+user);
Enumeration<String> names = servletConfig.getInitParameterNames();
while(names.hasMoreElements()) {
String name = names.nextElement();
String value = servletConfig.getInitParameter(name);
System.out.println("^^"+name+":"+value);
}
System.out.println("init");
}
~~~
③获取Servlet的配置名称(了解即可,使用较少)
~~~
String servletName = servletConfig.getServletName();
System.out.println(servletName);
~~~
④**getServletContext**获取Servlet上下文 **(重点)**
~~~
// 代表当前web应用,当前web应用的大管家,可以从中获取当前web应用各个方面的信息
ServletContext servletContext = servletConfig.getServletContext();
~~~
ServletContext常用的方法:
①获取当前web应用的初始化参数
配置参数:
~~~
<context-param>
<param-name>driver</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</context-param>
~~~
获取参数:
~~~
// 与获取Servlet初始化参数是一样的
String driver = servletContext.getInitParameter("driver");
System.out.println("driver:"+driver);
~~~
#### 那么Servlet的初始化参数与当前web应用的初始化参数有什么区别?
一个是局部的,一个是全局的,全局的初始化参数,在任何的Servlet当中都可以获取,而局部的只有当前Servlet可以获取。
②获取当前web应用某一个文件在服务器上的绝对路径,而不是部署前的路径(右键属性中的路径)
~~~
ServletContext servletContext = servletConfig.getServletContext();
String realPath = servletContext.getRealPath("index.jsp");
System.out.println(realPath);
~~~
③获取当前WEB应用的名称**getContextPath()**
~~~
String contextPath = servletContext.getContextPath();
System.out.println(contextPath);
~~~
这个名称有时候是动态变换的,很常用的方法。
④获取当前WEB应用的某一个文件对应的输入流
getResourceAsStream(String path):path的 / 为当前web应用的根目录
~~~
try {
ClassLoader classLoader = getClass().getClassLoader();
InputStream is1 = classLoader.getResourceAsStream("jdbc.properties");
System.out.println("1."+is1);
} catch (Exception e) {
e.printStackTrace();
}
try {
InputStream is2 = servletContext.getResourceAsStream("/WEB-INF/classes/jdbc.properties");
System.out.println("2."+is2);
} catch (Exception e) {
e.printStackTrace();
}
~~~
⑤与attribute属性相关的几个方法(非常重要,后续讲)
- 第一章 配置和安装Tomcat
- 第二章 Servlet(一)
- 第三章 Servlet(二)
- 练习 一 . Servlet配置级获取初始化参数
- 第四章 JSP(一)
- 第五章 JSP(二)
- 第六章 MVC设计模式
- 第七章 Cookie
- 第八章 Session
- 练习 二 . 简易版购物车
- 第九章 EL表达式
- 第十章 JSTL
- 第十一章 过滤器
- 第十二章 监听器
- 第十三章 文件的上传与下载
- 复习总结
- 如何手动启动Tomcat
- 如何修改Tomcat端口号
- 如何在web.xml中配置Servlet
- Servlet生命周期
- load-on-startup参数
- Servlet映射路径
- POST和GET的区别
- JSP中9个隐式对象及功能
- 请求转发及请求重定向的区别
- JSP指令有哪些
- 简述对MVC设计模式的理解
- 简述Cookie机制
- 简述Session机制
- HttpSession的生命周期
- Cookie和Session有什么区别
- 简述创建过滤器步骤
- 过滤器经典案例--统一编码字符集
- getParameter与getAttribute的区别
- JSP页面中可以包含哪些元素
- web应用中,是如何跟踪用户的
- InteliJ创建web项目