1 Servlet介绍
全称server applet,是sun公司提供开发动态资源的技术。Servlet类技术,与普通java类是有区别的,servlet具有处理请求与响应的能力,
1.2. servlet类与普通java类的区别
普通java类必须有程序的入口main方法才可以运行
servlet类是web服务器调用运行的,用户访问的服务器,请求交给服务器,服务器调用servlet程序处理,servlet处理响应完成交给服务器,服务器交给浏览器。
Servlet的体系结构为如下:
2. 创建Servlet的2种方式
1. 继承GenericServlet创建Servlet类,只需要重写一个service方法
public class Demo1Servlet extends GenericServlet {
/** * 处理请求的方法 */ @Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
response.getOutputStream().write("hello world".getBytes());
}
} |
继承HttpServlet创建Servlet类(推荐使用),可以实现分别处理get请求与post请求了
public class Demo2Servlet extends HttpServlet {
/** * Constructor of the object. */ public Demo2Servlet() { super(); }
/** * 处理get提交请求的 */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getOutputStream().write("处理了get请求".getBytes()); }
/** * 处理post提交请求的 */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getOutputStream().write("处理了post请求".getBytes()); }
} |
HttpServletRequest和HttpServletResponse是两个接口,而且是ServletRequest和ServletResponse的子接口。实现类由Tomcat实现
注意:创建了servlet,并修改了servlet代码,必须重启服务器。
2.1. 修改Servlet默认生成代码模板
大家创建HttpServlet的时候,发现会自动生成类有很多多余代码,而老师生成的Servlet类自动生成的代码效果如下:
public class Demo3Servlet extends HttpServlet {
/** * doget */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); }
/** * dopost */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
} |
3. Servlet运行原理
3.1. 疑问
疑问:java是面向对象的,思考一下面向对象方法的调用,对象需要先实例化,之后采用对象点方法进行调用,但是现在很奇怪Servlet对象的service方法怎么就调用了呢,是谁实例化了Servlet对象呢?
服务器实例化了Servlet和调用service方法
3.2. servlet运行原理
3.3. 运行原理总结
1. 服务器创建了Servlet对象
2. 客户端所有请求数据都在request对象里面
3. 所有响应给浏览器的数据都在response对象里面
4.servlet运行原理
4.1. 运行原理总结
1. 服务器创建了Servlet对象
2. 客户端所有请求数据都在request对象里面
3. 所有响应给浏览器的数据都在response对象里面
4.2. 思考问题
运行原理是由服务器实例了servlet对象,并且调用service方法处理请求。但是继承httpServlet处理请求的方法是doGet和doPost,并不是service方法,为什么呢?
答:因为httpServlet重写了service方法,判断请求方法是get还是post,get请求走子类doGet处理请求,post请求走子类doPost处理请求。所以继承HttpServlet处理请求的方法是doGet方法和doPost方法。
5. servlet生命周期
servlet是在第一次访问服务器的时候创建,因为init方法只执行一次,所以servlet对象只创建一次。无论用户多次访问服务器的时候都会调用service方法,当服务器关不的时候servlet才会被销毁。
5.1. 学习生命周期的作用
1.为什么修改了servlet代码需要重启服务器才能应用到?
答:servllet默认在用户第一次访问时服务器创建servlet对象,并且这个对象是全局唯一对象,如果此时修改了servlet代码,服务器不会重新创建servlet对象,所以需要重启服务器,目的让服务器重新创建servlet对象
2.面试:请写出servlet生命周期相关方法,并写出调用顺序?
相关方法,init,service,destroy,调用顺序如下
用户第一次访问,调用init方法和service方法
用户以后每次访问,都调用service方法
当前服务器关闭的时候,调用destroy方法
6. ServletConfig
6.1 介绍
它是servlet的一个配置文件对象
6.2 作用
可以读取web.xml中对当前servlet配置的参数数据
方法名 | 作用 |
String getInitParamter(String name) | 得到web.xml中有关Servlet的配置参数,通过参数名得到参数值 |
Enumeration<String> getInitParameterNames() | 得到web.xml中有关这个Servlet的所有的配置参数的名字,Enumeration是一个枚举类,类似于迭代器。
|
6.3 实现读取当前servlet配置参数的步骤
1. 在web.xml中配置当前servlet的参数
<servlet> <servlet-name>ServletConfigServlet</servlet-name> <servlet-class>com.itheima.servlet.ServletConfigServlet</servlet-class> <!--配置当前servlet的参数数据 --> <init-param> <param-name>param1</param-name> <param-value>123456</param-value> </init-param> <init-param> <param-name>param2</param-name> <param-value>abcd</param-value> </init-param> </servlet> |
2. 在servlet里面读取参数数据
public class ServletConfigServlet extends HttpServlet {
@Override public void init(ServletConfig config) throws ServletException { super.init(config); //ServletConfig config 用于读取当前web.xml中当前ServletConfigServlet的配置参数 //读取参数数据了,核心的方法 //config.getInitParameter(name); 获取指定名称的参数值 //config.getInitParameterNames() 获取所有参数名称列表
//需求:打印所有参数名称与值 //读取所有参数名称列表,Enumeration是一个古老的迭代器 Enumeration<String> enumeration = config.getInitParameterNames(); //遍历迭代,移动指针 while(enumeration.hasMoreElements()){ //获取当前指针数据 String paramName = enumeration.nextElement(); //根据参数名获取参数值 String paramValue = config.getInitParameter(paramName); //打印 System.out.println(paramName+"="+paramValue); }
}
/** * doGet method */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //在处理请求方法里面获取servletConfig对象 //getServletConfig(); } } |
7. servlet映射路径配置
就是在web.xml中配置访问servlet动态资源的url,位置如下:
<servlet-mapping> <servlet-name>LifeCycleServlet</servlet-name> <url-pattern>/lifeCycle</url-pattern> </servlet-mapping> |
7.1.1. 可以配置多个url-pattern
代码
<servlet-mapping> <servlet-name>Demo1Servlet</servlet-name> <url-pattern>/demo1</url-pattern> <!-- 可以配置多个url-pattern --> <url-pattern>/hello</url-pattern> <url-pattern>/hello.html</url-pattern> </servlet-mapping> |
7.1.2. 可以配置多个servlet-mapping
介绍
同一个servlet可以配置多个访问映射servlet-mapping标签配置
代码
<servlet-mapping> <servlet-name>Demo1Servlet</servlet-name> <url-pattern>/demo1</url-pattern> <!-- 可以配置多个url-pattern --> <url-pattern>/hello</url-pattern> <url-pattern>/hello.html</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Demo1Servlet</servlet-name> <url-pattern>/hello2</url-pattern> </servlet-mapping> |
7.1.3. servlet映射路径匹配方式
7.1.3.1. 精确匹配
上面讲的都是属于精确匹配,配置的url与用户访问的url要一模一样才可以访问到对应的servlet.
7.1.3.2. 模糊匹配(通配符匹配)
模糊匹配使用一个通配符“*”号,只有这一个通配符。
通配符匹配使用只有2种方式:
1. 前缀匹配,必须以“/”开头,以“*”结尾(*前面必须有/)
例子,/abc/*,只要用户访问时/abc/开头都可以匹配到
2. 后缀匹配,必须以“*”开头,以“.”扩展名方式结束使用
例子*.do,只要用户访问时以.do结尾都可以匹配到
/abc/*/abc,既不属于前缀也不属于后缀,属于精确匹配