黑马程序员——Servlet生命周期和Servlet之间的跳转

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

Servlet生命周期

1.1在CGI编程中,用户每次请求CGI程序,服务器就会开辟一个单独的进程来处理请求,处理完请求后再将这个进程销毁。这样反反复复的开辟与销毁不仅效率低下,而且占用很多资源。如果并发请求数(同一时刻请求数目很多),CGI程序往往显得力不从心。

而Servlet解决了这个问题。服务器会在启动时(如果load-on-startup=1)或第一次请求Servlet时(如果load-on-startup=0)初始化一个Servlet对象,然后这个Servlet对象去处理所有的客户端的请求。服务器关闭时才销毁这个Servlet对象。这样省去了开辟和销毁Servlet的开销。当然这也增加了服务器维护Servlet的工作。

Servlet会在服务器启动或第一次请求该Servlet的时候开始生命周期,在服务器结束的时候结束生命周期。无论请求多少次Servlet,最多只有一个Servlet实例。多个客户端并发请求Servlet时,服务器会启动多个线程分别执行该Servlet的Service方法。

个人所得税计算器实例

把读取的初始化参数放在init方法中,即保证了读取一次,又保证不耽误doGet和doPost的使用。代码如下:

 

package com.helloweenvsfei.servlet;

import java.io.IOException;
import java.io.PrintWriter;

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 LifeCycleServlet extends HttpServlet {

 private static final long serialVersionUID = -7197419401412129310L;
 
 private static double startPoint = 0;

 @Override
 public void init() throws ServletException {
  this.log("执行 init() 方法 ... ");
  ServletConfig conf = this.getServletConfig();
  startPoint = Double.parseDouble(conf.getInitParameter("startPoint"));
 }
 

 @Override
 protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
  this.log("执行 service() 方法 ... ");
  super.service(arg0, arg1);
 }

 @Override
 public void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  this.log("执行 doPost() 方法 ... ");
  response.setCharacterEncoding("UTF-8");
  response.setContentType("text/html");
  PrintWriter out = response.getWriter();
  out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
  out.println("<HTML><HEAD><TITLE>个人所得税计算</TITLE></HEAD>");
  out.println("<link rel='stylesheet' type='text/css' href='../css/style.css'>");
  out.println("<BODY>");
  
  out.println("<div align='center'><br/><fieldset style=width:90%><legend>个税计算器</legend><br/>");
  
  try{
   // 从参数中获取的工资数目
   double income = new Double(request.getParameter("income"));
   // 应纳税部分
   double charge = income - startPoint;
   // 缴税
   double tax = 0;

   if (charge<=0) {tax=0;}
   if (charge>0&&charge<=500) {tax=charge*0.05;}
   if (charge>500&&charge<=2000) {tax=charge*0.1-25;}
   if (charge>2000&&charge<=5000) {tax=charge*0.15-125;}
   if (charge>5000&&charge<=20000) {tax=charge*0.2-375;}
   if (charge>20000&&charge<=40000) {tax=charge*0.25-1375;}
   if (charge>40000&&charge<=60000) {tax=charge*0.30-3375;}
   if (charge>60000&&charge<=80000) {tax=charge*0.35-6375;}
   if (charge>80000&&charge<=100000) {tax=charge*0.4-10375;}
   if (charge>100000) {tax=charge*0.45-15375;}

   out.println("<div style='line'>");
   out.println(" <div class='leftDiv'>您的工资为</div><div class='rightDiv'>" + income + " 元</div>");
   out.println("</div>");
   
   out.println("<div style='line'>");
   out.println(" <div class='leftDiv'>您应纳税</div><div class='rightDiv'>" + tax + " 元</div>");
   out.println("</div><br/>");

   out.println("<input type='button' οnclick='history.go(-1);' value='纳税光荣 逃税可耻 返回'  class=button>");
   
  }catch(Exception e){
   out.println("请输入数值类型数据。<input type='button' οnclick='history.go(-1);' value='返回'  class=button>");
  }
  out.println("</BODY>");
  out.println("</HTML>");
  out.flush();
  out.close();
 }

 @Override
 public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  this.log("执行 doGet() 方法 ... ");
  response.setCharacterEncoding("UTF-8");
  response.setContentType("text/html");
  PrintWriter out = response.getWriter();
  out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
  out.println("<link rel='stylesheet' type='text/css' href='../css/style.css'>");
  out.println("<HTML><HEAD><TITLE>个人所得税计算</TITLE></HEAD>");

  out.println("<div align='center'><br/><fieldset style=width:90%><legend>个税计算器</legend><br/>");
  out.println("<form method='post' action='LifeCycleServlet'>");
  
  out.println("<div style='line'>");
  out.println(" <div class='leftDiv'>您的工资为</div><div align='left' class='rightDiv'><input type='text' name='income'> 单位:元</div>");
  out.println("</div><br/>");
  
  out.println("<div style='line'>");
  out.println(" <div class='leftDiv'></div><div align='left' class='rightDiv'><input type='submit' value='  计算个税  ' class=button></div>");
  out.println("</div>");
  
  out.println("</form>");
  
  out.println("<BODY>");
  out.println("</BODY>");
  out.println("</HTML>");
  out.flush();
  out.close();
 }

 @Override
 public void destroy() {
  this.log("执行 destroy() 方法 ... ");
  startPoint = 0;
 }
 
}

LifeCycleServlet在初始化时需要读取配置在web.xml中的个人所得税起征点。web.xml配置如下

 <servlet>
  <servlet-name>LifeCycleServlet</servlet-name>
  <servlet-class>
   com.helloweenvsfei.servlet.LifeCycleServlet
  </servlet-class>
  <init-param>
   <param-name>startPoint</param-name>
   <param-value>2000</param-value>
  </init-param>
 </servlet>

<servlet-mapping>
  <servlet-name>LifeCycleServlet</servlet-name>
  <url-pattern>/servlet/LifeCycleServlet</url-pattern>
 </servlet-mapping>

 注解@PostConstruct与注解@PreDestroy

从Java EE 5开始,Servlet增加了两个影响Servlet生命周期的注解(Annonation):@PostConstruct和@PreDestroy。这两个注解用来修饰一个非静态的void()方法,而且这个方法不能抛出异常声明。注释可以写在方法的前面,也可以写在返回类型void前面。例如

@PostConstruct

public void someMethod{

}

public @PreDestroy void anotherMethhod(){

}

被@PostConstruct修饰的方法会在构造函数之后,init()方法之前运行。并且只运行一次。

被@PreDestroy修饰的方法会在destroy()方法之后,Servlet被彻底卸载之前执行。

服务器在启动时,会遍历Web应用的WEB-INFO/class所有的class文件和WEB-INFO/lib所有的jar文件,以检查哪些类使用了注解。

支持@Predestroy和@PostConstruct注解的服务器需要支持到Servlet2.5及以上的规范。Tomcat5.X仅支持到Servlet 2.4的规范。

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值