Servlet
Servlet 介绍及应用
Servlet是运行在Java服务器端的程序,用于接受和响应来自客户端基于HTTP协议的请求
如果想实现Servlet的功能,可以通过实现javax.servlet.Servlet接口或者基层它的实现类
核心方法: service(), 任何客户端的请求都会经过该方法
Servlet 快速入门
- 创建一个WEB项目
- 创建一个类继承GenercServlet,继承servlet接口, 继承HttpServlet
- 重写service方法
- 在web.xml中配置Servlet
- 部署项目
- 测试
java
public class ServletDemo01 extends GenericServlet{
@Override
public void service(ServletRequest req , ServletResponse requ){
System.out.prinltn("这个方法执行了!");
}
}
web.xml
<!--声明-->
<servlet>
<servlet-name>servletDemo01</servlet-name>
<servlet-class>com.learn.servlet.ServletDemo01</servlet-class>
</servlet>
<!--映射-->
<servlet-mapping>
<servlet-name>servletDemo01</servlet-name>
<servlet-pattern>/servletDemo01</servlet-pattern>
</servlet-mapping>
Servlet执行过程
客户端服务器—>发起请求—>解析请求地址(url)—>找到相关应用—>找到web.xml配置文件
—>找到请求的资源地址(在web.xml向上寻找)---->找到应用的资源—>执行service方法,响应给服务器
Servlet 关系视图
Servlet 实现方式
- 实现Servlet接口,实现所有的抽象方法,该方法 支持最大程度的自定义
- 继承GenericServlet 抽象类, 必须重写service方法,其他方法可以选择重写,该方法让我们开发Servlet变得简单, 这种方式和HTTP协议无关
- 继承HttpServlet抽象类, 需要重写doGet和doPost方法,该方法表示请求和响应都需要HTTP协议
HttpServlet 快速入门
- 创建一个类继承HttpServlet
- 重写doGet和doPost方法
- 在web.xml中配置Servlet
- 部署项目并启动
- 测试
public class ServletDemo01 extends HttpServlet{
@Override
public void doGet(HttpServletRequest req , HttpServletResponse requ){
System.out.prinltn("这个方法执行了!");
}
@Override
publci void doPost(HttpServletRequest req , HttpServletResponse requ{
System.out.println("这个方法执行了!");
}
<!--声明-->
<servlet>
<servlet-name>servletDemo02</servlet-name>
<servlet-class>com.learn.servlet.ServletDemo02</servlet-class>
</servlet>
<!--映射-->
<servlet-mapping>
<servlet-name>servletDemo02</servlet-name>
<servlet-pattern>/servletDemo02</servlet-pattern>
</servlet-mapping>
Servlet生命周期
对象的生命周期就是从创建到销毁的过程
- 第一次到达Servlet时创建出来,并初始化成功,只会执行一次,l将对象放到内存中:init()方法
- 服务器提供的整个过程,对象一直存在,每次都会执行service方法
- 当服务器停止时,或者时宕机的时候,对象销毁destroy()方法
Servlet 线程安全问题
由于Servlet采用的时单例模式, 也就是整个应用中只有一个实例对象,所以我们需要分析这个唯一的实例对象中的类成员是否线程安全,通过模拟登录功能来查看。
public class ServletDemo01 extends HttpServlet{
//1. 定义一个用户名的成员变量
private String username;
@Override
public void doGet(HttpServletRequest req , HttpServletResponse resp){
//2. 获取到用户名
username = req.getParameter("username");
//3. 响应给浏览器
PrintWriter pw = resp.getWriter();
pw.print("welcome:"+ username);
pw.close();
Thread.sleep(3000)//try处理
}
@Override
publci void doPost(HttpServletRequest req , HttpServletResponse resp{
System.out.println("这个方法执行了!");
}
解决方案:
- 把成员变量变成局部变量
- 添加同步代码块
Servlet 映射方式
- 具体名称方式, 访问的资源路径必须和映射配置完全相同
- /开头 + 通配符的方式 , 只要符合目录结构即可 , 不用考虑结尾是什么
- 统配符 + . 固定格式结尾的方式, 是要符合固定结尾格式即可
优先级:也是具体的优先级越高
Servlet 多路径映射(上面的练习)
public class ServletDemo01 extends HttpServlet{
@Override
public void doGet(HttpServletRequest req , HttpServletResponse requ){
//1. 定义一个商品金额
int money = 1000;
//2. 获取访问资源路径
String path = req.getRequestURI();
path.substring(path.lastIndexOf("/"))
//3. 条件判断
if("/Vip".efquals(path)){
System.out.println("商品的原价为" + money + "优惠后:" + (money*0.9);
}else if("/Vvip".equals(path)){
System.out.println("商品的原价为" + money + "优惠后:" + (money*0.5);
}else{
System.out.println("商品的原价为" + money );
}
}
@Override
publci void doPost(HttpServletRequest req , HttpServletResponse requ{
System.out.println("这个方法执行了!");
}
Servlet 创建时机
1. 第一次访问的时候创建
- 减少服务器的内存的浪费, 提高了服务器启动的效率
- 如果有一些应用加载时就做的初始化操作,无法完成
- 服务器加载时创建
- 提前创建好对象, 提高了首次执行的效率,可以完成一些应用加载时要做的初始化操作
- 对服务器内存占用较多,影响了服务器的效率
修改方式: 在 servlet 标签中, 添加 load-on-startup 标签
- 正整数代表服务器加载时机,值越小优先级越高,负数或不写代表第一次访问时创建
<!--声明-->
<servlet>
<servlet-name>servletDemo02</servlet-name>
<servlet-class>com.learn.servlet.ServletDemo02</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!--映射-->
<servlet-mapping>
<servlet-name>servletDemo02</servlet-name>
<servlet-pattern>/servletDemo02</servlet-pattern>
</servlet-mapping>
默认 Servlet
- 默认Servlet是由服务器提供的Servlet 它是由Tomcat的conf 目录中的web.xml, 通常报错信息,都是由默认Servlet去查找并响应的