一、servlet简介
servlet是一种动态web资资源开发技术,用于开发动态web页面;
二、servlet的运行过程
servlet程序是由web服务器调用,web服务器收到客户端的servlet访问请求后;
1、web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第4步,否则执行第2步,
2、装载并创建一个Servlet的一个实例对象。
3、调用servlet实例对象的init()方法。
4、创建一个用于封装http请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet对象service方法并将请求和响应作为参数传递进去。
5、web应用程序被停止或启动之前,servlet引擎将卸载servlet,并在卸载之前调用servlet的destroy()方法。
三、一个完整的servlet组成部分
1、首先我们会定义一个Java类,重写doGet(),doPost()方法;
2、在web.xml文件下配置servlet;
3、一个servlet的组成分为servlet-name和servlet-class都是成对的标签,servlet-name表示servlet的注册码,servlet-class
表示servlet的完整类名(全包名)
4、还需要配置一个servlet-mapping 一个servlet-mapping 包括 servlet-name和url-pattern两对标签,servlet-name表示servlet的注册名,url-pattern表示对外的绝对访问路径。
需要注意的是一个servlet可以对应多个servlet-mapping
<servlet><servlet-name>ServletDemo1</servlet-name><servlet-class>gacl.servlet.study.ServletDemo1</servlet-class></servlet><servlet-mapping><servlet-name>ServletDemo1</servlet-name><url-pattern>/servlet/ServletDemo1</url-pattern></servlet-mapping><servlet-mapping><servlet-name>ServletDemo1</servlet-name><url-pattern>/1.htm</url-pattern></servlet-mapping><servlet-mapping><servlet-name>ServletDemo1</servlet-name><url-pattern>/2.jsp</url-pattern></servlet-mapping><servlet-mapping><servlet-name>ServletDemo1</servlet-name><url-pattern>/3.php</url-pattern></servlet-mapping><servlet-mapping><servlet-name>ServletDemo1</servlet-name><url-pattern>/4.ASPX</url-pattern></servlet-mapping>
四、Servlet访问通配符的一些匹配规则
在Servlet映射到的URL中也可以使用通配符,但是只能有两种固定的格式:一种格式是”.扩展名”,另一种格式是以正斜杠(/)开头并以”/*”结尾。例如:
五、servlet的启动装载
创建一个servlet,使得它只有当web服务器关闭时才销毁。
<servlet><servlet-name>invoker</servlet-name><servlet-class>org.apache.catalina.servlets.InvokerServlet</servlet-class><load-on-startup>1</load-on-startup></servlet>
用途:为web应用写一个InitServlet,这个servlet配置为启动时装载,为整个web应用创建必要的数据库表和数据。
六、servlet线程安全问题
当多个客户端并发访问同一个servlet时,web服务器会为每一个客户端的访问创建一个线程,并在这个线程上调用service方法,因此导致了一些线程安全问题。
不存在线程安全问题的(将i作为成员变量)
package gacl.servlet.study;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class ServletDemo3 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {/*** 当多线程并发访问这个方法里面的代码时,会存在线程安全问题吗* i变量被多个线程并发访问,但是没有线程安全问题,因为i是doGet方法里面的局部变量,* 当有多个线程并发访问doGet方法时,每一个线程里面都有自己的i变量,* 各个线程操作的都是自己的i变量,所以不存在线程安全问题* 多线程并发访问某一个方法的时候,如果在方法内部定义了一些资源(变量,集合等)* 那么每一个线程都有这些东西,所以就不存在线程安全问题了*/int i=1;i++;response.getWriter().write(i);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}
存在线程安全问题的(将i作为成员变量便会存在线程安全问题)
package servlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/*** 测试线程安全问题*/public class ServletThredDemo1 extends HttpServlet {public int i;public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {//将i定义为成员变量 将不存在线程安全问题i++;try {Thread.sleep(1000*4);} catch (InterruptedException e) {e.printStackTrace();}response.getWriter().write(i+"");}public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException{doGet(request,response);}}
七、ServketCnfig讲解
7.1配置servlet初始化参数
在servlet的配置文件web.xml中,可以使用一个或多个
当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,我们通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
<servlet><servlet-name>ServletConfigDemo1</servlet-name><servlet-class>gacl.servlet.study.ServletConfigDemo1</servlet-class><!--配置ServletConfigDemo1的初始化参数 --><init-param><param-name>name</param-name><param-value>gacl</param-value></init-param><init-param><param-name>password</param-name><param-value>123</param-value></init-param><init-param><param-name>charset</param-name><param-value>UTF-8</param-value></init-param></servlet>
7.2获取初始化参数
package servlet;import javax.servlet.ServletConfig;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.util.Enumeration;/***通过ServletConfig 配置一些默认参数*/public class ServletConfigDemo1 extends HttpServlet {private ServletConfig config;@Overridepublic void init(ServletConfig config) throws ServletException {this.config=config;}public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException{//必须设置响应头 不然会将html 解析为字符串response.setContentType("text/html;charset=utf-8");//通过config对象获取初始化servlet初始化参数String name = config.getInitParameter("name");response.getWriter().print(name);response.getWriter().print("<hr/>");//获取全部的初始化参数Enumeration<String> e = config.getInitParameterNames();while (e.hasMoreElements()){String key = e.nextElement();String value = config.getInitParameter(key);response.getWriter().write(key+":"+value+"<br/>");}}public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException{doGet(request,response);}}
八、servletContext对象
8.1ServletContext对象简介
WEB容器在启动时,它会为每个web应用程序都创建一个对应的serlvetContext对象,它代表当前的web应用。
ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过servletConfig.getServletContext方法获得ServletContext对象。
由于一个web应用中的所有Serlvet共享一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。SerlvetContext对象也被称之为域对象。
8.2多个Servlet通过ServletContext对象实现数据共享
通过servletConfig对象获取servletContext对象设置值
package servlet;import javax.servlet.ServletConfig;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/*** ServletContext域对象实现共享*/public class ServletContextDemo1 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response){ServletContext servletContext = getServletConfig().getServletContext();servletContext.setAttribute("name","lisi");}public void doPost(HttpServletRequest request, HttpServletResponse response){doGet(request,response);}}
通过servletContext对象获取值
package servlet;import javax.servlet.ServletConfig;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/*** ServletContext域对象实现共享*/public class ServletContextDemo2 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {ServletContext servletContext =getServletContext();String name = servletContext.getAttribute("name").toString();response.getWriter().write(name);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws IOException{doGet(request,response);}}
注意:需要配置两个servlet,先设置值,再获取值
8.3用servletContext实现转发
访问的是ServletContextDemo3,浏览器显示的却是ServletContextDemo4的内容,这就是使用ServletContext实现了请求转发
package servlet;import javax.servlet.RequestDispatcher;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/*** 通过ServletContext对象实现转发*/public class ServletContextDemo3 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {String data = "<h1><font color='red'>abcdefghjkl</font></h1>";response.getOutputStream().write(data.getBytes());//获取Context对象ServletContext servletContext = getServletContext();//获取转发的对象 RequestDispatcherRequestDispatcher rd = servletContext.getRequestDispatcher("/servlet/ServletContext4");//实现转发rd.forward(request,response);}public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {doGet(request,response);}}
package servlet;import javax.servlet.RequestDispatcher;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/*** 通过ServletContext对象实现转发*/public class ServletContextDemo4 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {response.getOutputStream().write("ServletContext4".getBytes());}public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {doGet(request,response);}}
