Java Web之路(一)Servlet
序言
执行过程
Servlet 生命周期、工作原理:http://www.cnblogs.com/xuekyo/archive/2013/02/24/2924072.html
Servlet的生命周期
Servlet的生命周期是由Servlet的容器来控制的,它可以分为3个阶段;初始化,运行,销毁。
初始化阶段:
1).Servlet容器加载servlet类,把servlet类的.class文件中的数据读到内存中。
2).然后Servlet容器创建一个ServletConfig对象。ServletConfig对象包含了Servlet的初始化配置信息。
3).Servlet容器创建一个servlet对象。
4).Servlet容器调用servlet对象的init方法进行初始化。
运行阶段:
当servlet容器接收到一个请求时,servlet容器会针对这个请求创建servletRequest和servletResponse对象。
然后调用service方法。并把这两个参数传递给service方法。Service方法通过servletRequest对象获得请求的信息。并处理该请求。再通过servletResponse对象生成这个请求的响应结果。然后销毁servletRequest和servletResponse对象。我们不管这个请求是post提交的还是get提交的,最终这个请求都会由service方法来处理。
销毁阶段:
当Web应用被终止时,servlet容器会先调用servlet对象的destrory方法,然后再销毁servlet对象,同时也会销毁与servlet对象相关联的servletConfig对象。我们可以在destroy方法的实现中,释放servlet所占用的资源,如关闭数据库连接,关闭文件输入输出流等。
在这里该注意的地方:
在servlet生命周期中,servlet的初始化和和销毁阶段只会发生一次,而service方法执行的次数则取决于servlet被客户端访问的次数。
3.Servlet的三种创建方式
1)实现javax.servlet.Servlet接口
package com.mf.servlet; 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 ServletDemo1 implements Servlet{ //Servlet生命周期的方法 //在servlet第一次被访问时调用 //实例化 public ServletDemo1(){ System.out.println("***********ServletDemo1执行了*********"); } //Servlet生命周期的方法 //在servlet第一次被访问时调用 //初始化 public void init(ServletConfig arg0) throws ServletException { System.out.println("***********init执行了*********"); } //Servlet生命周期的方法 //服务 //每次访问时都会被调用 public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException { //System.out.println("hello servlet"); System.out.println("***********service执行了*********"); } //Servlet生命周期的方法 //销毁 public void destroy() { System.out.println("***********destroy执行了*********"); } public ServletConfig getServletConfig() { // TODO Auto-generated method stub return null; } public String getServletInfo() { // TODO Auto-generated method stub return null; } }
2)继承javax.servet.GenericServlet类(适配器模式)
package com.mf.servlet; import java.io.IOException; import javax.servlet.GenericServlet; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class ServletDemo2 extends GenericServlet { @Override public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException { System.out.println("ok"); } }
3)继承javax.servlet.http.HttpServlet类(模板方法设计模式)
package com.mf.servlet; 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{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("*******doGet *******"); System.out.println(req.getRemoteAddr()); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("**********doPost**********"); } }
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <!-- 创建一个Servlet实例 --> <servlet> <servlet-name>servletDemo1</servlet-name> <servlet-class>com.mf.servlet.ServletDemo1</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <!-- 给Servlet提供(映射)一个可供客户端访问的URI --> <servlet-mapping> <servlet-name>servletDemo1</servlet-name> <url-pattern>/demo1</url-pattern> </servlet-mapping> <servlet> <servlet-name>servletDemo2</servlet-name> <servlet-class>com.mf.servlet.ServletDemo2</servlet-class> </servlet> <servlet-mapping> <servlet-name>servletDemo2</servlet-name> <url-pattern>/demo2</url-pattern> </servlet-mapping> <servlet> <servlet-name>servletDemo3</servlet-name> <servlet-class>com.mf.servlet.ServletDemo3</servlet-class> </servlet> <servlet-mapping> <servlet-name>servletDemo3</servlet-name> <url-pattern>/demo3</url-pattern> </servlet-mapping> </web-app>
servet映射细节
url-pattern: *.do 以*.字符串的请求都可以访问 注:不要加/
url-pattern: /* 任意字符串都可以访问
url-pattern: /action/* 以/action开头的请求都可以访问
匹配规则:
优先级:从高到低
绝对匹配--> /开头匹配 --> 扩展名方式匹配
如果url-pattern的值是/,表示执行默认映射。所有资源都是servlet
Servlet的线程安全
解决线程安全问题的最佳办法,不要写全局变量,而写局部变量。
Servlet获取配置信息
package com.mf.servlet; import java.io.IOException; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletConfigDemo1 extends HttpServlet { /*private ServletConfig config; public void init(ServletConfig config) throws ServletException { this.config = config; } */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /*String encoding = config.getInitParameter("encoding");//获得配置文件中的信息的 System.out.println(encoding);*/ //第二种方式 记得屏蔽最上面代码 /*System.out.println("--------"); String encoding = this.getServletConfig().getInitParameter("encoding"); System.out.println(encoding);*/ //第三种方式 记得屏蔽最上面的代码 /*String encoding = super.getInitParameter("encoding"); System.out.println(encoding);*/ } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
ServletContext
ServletContext: 代表的是整个应用。一个应用只有一个ServletContext对象。单实例。
作用:
域对象:在一定范围内(当前应用),使多个Servlet共享数据。
常用方法:
void setAttribute(String name,object value);//向ServletContext对象的map中添加数据
Object getAttribute(String name);//从ServletContext对象的map中取数据
void rmoveAttribute(String name);//根据name去移除数据
//通过调用GenericServlet的getServletContext方法得到ServletContext对象 ServletContext application = this.getServletContext(); //向ServletContext添加一个键值对 application.setAttribute("name", "tom"); System.out.println(application.getClass().getName());
String name = (String) this.getServletContext().getAttribute("name"); if(name==null){ System.out.println("你不能直接访问这个类"); } System.out.println(name);
获取全局配置信息
<!-- 配置当前应用的全局信息 --> <context-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </context-param>
String encoding = this.getServletContext().getInitParameter("encoding"); System.out.println(encoding);
获取资源路径
package com.mf.ServletContext; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Properties; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletDemo4 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //test1(); //test2(); test3(); } //获取/WEB-INF/classes/b.properties文件 private void test3() throws IOException, FileNotFoundException { String path = this.getServletContext().getRealPath("/WEB-INF/classes/com/mf/servlet/c.properties"); Properties pro = new Properties(); pro.load(new FileInputStream(path)); System.out.println(pro.get("key")); } //获取/WEB-INF/classes/b.properties文件 private void test2() throws IOException, FileNotFoundException { String path = this.getServletContext().getRealPath("/WEB-INF/classes/b.properties"); Properties pro = new Properties(); pro.load(new FileInputStream(path)); System.out.println(pro.get("key")); } //获取WEB-INF下的a.properties文件 private void test1() throws IOException, FileNotFoundException { String path = this.getServletContext().getRealPath("/WEB-INF/a.properties");//参数一定要以/开头 //创建一个Properties Properties pro = new Properties(); pro.load(new FileInputStream(path)); System.out.println(pro.getProperty("key")); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
实现Servlet的转发
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("我要办事"); System.out.println("你的事我办不了,我可以帮你找人办"); ServletContext application = this.getServletContext(); /*RequestDispatcher rd = application.getRequestDispatcher("/servlet/demo6"); rd.forward(request, response);*/ //将请求向下传递 application.getRequestDispatcher("/servlet/demo6").forward(request, response); System.out.println("事办完了"); }
Servlet相关对象