java web开发——第六章java Servlet基础

目录

前言

6.1 servlet的部署、创建与运行

6.1.1源文件及字节码文件

6.1.2  编写部署文件web.xml

6.1.3  servlet的创建与运行

6.1.4  向servlet传递参数的值

6.2 servlet的工作原理

6.2.1  servlet 对象的生命周期

6.2.2  init方法

6.2.3  service方法

6.2.4  destroy方法

6.3 通过JSP页面访问servlet

6.4 共享变量

6.5 doGet和doPost方法

6.6 重定向与转发

6.7 使用session

总结


前言

本章主要内容是servlet的部署、创建与运行、servlet的工作原理、通过JSP的页面访问servlet、共享变量、doPost和doGot方法、重定向与转发和使用session。难点是servlet的工作原理和重定向与转发。


6.1 servlet的部署、创建与运行

6.1.1源文件及字节码文件

1.Servlet类

写一个创建servlet的类就是编写一个特殊类的子类,这个特殊的类就是javax.servlet.http包中的HttpServlet类。HttpServlet实现了Servlet接口,实现了响应用户的方法(这些方法将在后续内容中讲述)。HttpServlet的子类被习惯地称作一个Servlet类,这样的类创建的对象习惯地被称作一个servlet。

package moon.sun;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class Example6_1 extends HttpServlet{
    public void init(ServletConfig config) throws ServletException{
       super.init(config);
    }
    public void service(HttpServletRequest request,HttpServletResponse response) throws IOException{
      //设置响应的MIME类型:
       response.setContentType("text/html;charset=utf-8");
       PrintWriter out = response.getWriter();//获得向用户发送数据的输出流。
       out.println("<html><body bgcolor = #ffccff>");
       out.println("<h1>hello servlet,你好 servlet</h1>");
       out.println("</body></html>");
    } 
}

2.字节码文件的保存
字节码文件按着类的包名对应的目录路径保存到Web服务目录中特定子目录中。

6.1.2  编写部署文件web.xml

Servlet类的字节码文件保存到指定的目录后,必须为Tomcat服务器编写一个部署文件,只有这样,Tomcat服务器才会用Servlet类创建servlet对象。
部署文件是一个XML文件,名字必须是web.xml。
web.xml由Tomcat服务器负责管理,xml文件是由标记(元素)组成的文本文件,Tomcat服务器配有内置的解析器,可以解析XML文件的标记中的数据。
编写的web.xml文件必须保存到Web服务目录的WEB-INF子目录中,比如ch6\WEB-INF中(不要保存在ch6中)。根据例子6_1给出的Servlet类,web.xml文件的内容如下(需要用纯文本编辑器编辑web.xml)

<?xml version="1.0" encoding="utf-8"  ?>
<web-app>
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>moon.sun.Example6_1</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/lookHello</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>lookPic</servlet-name>
        <servlet-class>moon.sun.Example6_2</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>lookPic</servlet-name>
        <url-pattern>/lookPic</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>computeBill</servlet-name>
        <servlet-class>moon.sun.Example6_3_Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>computeBill</servlet-name>
        <url-pattern>/computeBill</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>circle</servlet-name>
        <servlet-class>moon.sun.Example6_4_Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>circle</servlet-name>
        <url-pattern>/circle</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>computePI</servlet-name>
        <servlet-class>moon.sun.Example6_5_Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>computePI</servlet-name>
        <url-pattern>/computePI</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>sumORproduct</servlet-name>
        <servlet-class>moon.sun.Example6_6_Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>sumORproduct</servlet-name>
        <url-pattern>/sumORproduct</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>handleForward</servlet-name>
        <servlet-class>moon.sun.Example6_7_Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>handleForward</servlet-name>
        <url-pattern>/handleForward</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>sort</servlet-name>
        <servlet-class>moon.sun.Example6_7_Servlet_Sort</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>sort</servlet-name>
        <url-pattern>/sort</url-pattern>
    </servlet-mapping >
    <servlet>
        <servlet-name>sum</servlet-name>
        <servlet-class>moon.sun.Example6_7_Servlet_Sum</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>sum</servlet-name>
        <url-pattern>/sum</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>guess</servlet-name>
        <servlet-class>moon.sun.Example6_8_Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>guess</servlet-name>
        <url-pattern>/guess</url-pattern>
    </servlet-mapping>
</web-app>

一个XML文件应当以XML声明作为文件的第一行,在其前面不能有空白、其他的处理指令和注释。
XML声明以"<? xml"表示开始、以"?>"标识结束。注意"<?"和xml之间,以及"?"和">"之间不要有空格。

1.根标记
xml文件必须有一个根标记,web.xml文件的根标记是 web-app,根标记 web-app 的开始标签是web-app>,结束标签是</web-app>,开始标签和结束标签之间的内容称作根标记的内容。
2.servlet 标记及子标记
web-app 根标记里可以有若于个 servlet 标记(称作根标记的子标记,该标记的开始标签是servlet >,结束标签是</servlet >,开始标签和结束标签之间是 servlet 标记的内容servlet标记需要有两个子标记:servlet-name 和 servlet-class,其中 servlet-name 标记的内容是Tomcat服务器创建的 servlet 的名字,servlet-class 标记的内容告知 Tomcat 服务器用哪个Servlet类来创建servlet。在我们给出的 web.xml文件中,让 Tomcat 服务器使用例6_1给出的Example6_1类创建的名字是 hello 的 servlet。web.xml文件可以有若干个 servlet 标记(一个servlet 标记部署一个servlet 对象),但要求它们的< servlet-name >子标记的内容互不相同,即服务器可以创建多个 servlet,它们的名字必须互不相同。

6.1.3  servlet的创建与运行

用户就可以根据web.xml部署文件来请求Tomcat服务器创建并运行一个servlet。

如果Tomcat服务器没有名字为hello的servlet,就会根据web.xml文件中servlet标记的子标记servlet-class指定的Servlet类创建一个名字为hello的servlet。因此,如果名字是hello的servlet被创建之后,又修改Java源文件、编译得到新的Servlet类,并希望Tomcat服务器用新的Servlet类创建servlet,那么就要重新启动Tomcat服务器。根据6.1.2中的web.xml文件,用户需在浏览器输入:

http://127.0.0.1:8080/ch6/lookHello

请求Tomcat服务器运行名字是hello的servlet。

6.1.4  向servlet传递参数的值

在请求一个servlet时,可以在请求的url-pattern中额外加入参数及其值,格式是:

url-pattern?参数1=值&参数2=值…参数n=值

那么被请求的servlet就可以使用request对象获取参数的值,例如:

request.getParameter(参数n)
package moon.sun;
import java.awt.image.BufferedImage;
import java.awt.*;
import java.awt.geom.*; 
import javax.imageio.ImageIO;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class Example6_2 extends HttpServlet{
    public void init(ServletConfig config) throws ServletException{
       super.init(config);
    }
    public void service(HttpServletRequest request,HttpServletResponse response) throws IOException{
        request.setCharacterEncoding("utf-8");
        double width  = Double.parseDouble(request.getParameter("width"));
        double height = Double.parseDouble(request.getParameter("height"));
        response.setContentType("image/jpeg");
        Ellipse2D ellipse=new Ellipse2D.Double(400-width/2,300-height/2,width,height);
        BufferedImage image = getImage(ellipse);
        try {
            OutputStream outClient= response.getOutputStream();//指向用户端的输出流。
            boolean boo =ImageIO.write(image,"jpeg",outClient);
        }
        catch(Exception exp){}
    } 
    BufferedImage getImage(Shape shape){ //得到图形的图像
        int width=800, height=600;
        BufferedImage image = 
        new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        Graphics g = image.getGraphics();
        g.fillRect(0, 0, width, height);
        Graphics2D g_2d=(Graphics2D)g; 
        g_2d.setColor(Color.blue);
        g_2d.fill(shape); 
        return image;
    }
}

6.2 servlet的工作原理

servlet由Tomcat服务器负责管理,Tomcat服务器通过读取web.xml,然后创建并运行servlet。

6.2.1  servlet 对象的生命周期

servlet由Tomcat服务器负责创建并完成初始化工作。当多个用户请求一个servlet时,服务器为每个用户启动一个线程。

一个servlet的生命周期主要有下列三个过程组成:

(1) servlet第一次被请求加载时,服务器创建servlet,servlet调用init方法完成必要的初始化工作。

(2) 新诞生的servlet再调用service方法响应用户的请求。

(3) 当服务器关闭时,调用destroy方法销毁servlet。

init方法只被调用一次。当后续的用户请求servlet服务时,Tomcat服务器将启动一个新的线程,在该线程中,servlet调用service方法。也就是说,每个用户的每次请求都导致service方法被调用执行,其执行过程分别运行在不同的线程中。

6.2.2  init方法

public void init(ServletConfig  config) throws ServletException

servlet第一次被请求加载时,服务器创建一个servlet,这个对象调用init方法完成必要的初始化工作。该方法在执行时,服务器会把一个SevletConfig类型的对象传递给init()方法,这个对象就被保存在servlet中,直到servlet被销毁。

6.2.3  service方法

public void service(HttpServletRequest request  HttpServletResponse  response)throw ServletException,IOException

Tomcat服务器将两个参数传递给该方法。和init方法不同的是,init方法只被调用一次,而service方法可能被多次的调用。当后续的用户请求该servlet时,Tomcat服务器将启动一个新的线程,在该线程中servlet调用service方法响应用户的请求,调用过程运行在不同的线程中,互不干扰。因此,不同线程的service方法中的局部变量互不干扰,一个线程改变了自己的service方法中局部变量的值不会影响其他线程的service方法中的局部变量。

6.2.4  destroy方法

public destroy()

当Tomcat服务器终止服务时,destroy()方法会被执行,销毁servlet.子类可直接继承这个方法,一般不需要重写。

6.3 通过JSP页面访问servlet

按着部署文件web.xml给出的servlet的url-pattern,用户除了可以在浏览器输入url-pattern请求运行一个servlet外,也可以通过JSP页面来请求一个servlet。

需要特别注意的是,如果web.xml文件中给出的servlet的url-pattern是/lookHello,那么JSP页面请求servlet时,必须要写成 lookHello,不可以写成/lookHello。

1.通过表单向servlet提交数据

如果web.xml文件中给出的servlet的url-pattern是/computeBill,那么form表单中action给出的值就是computeBill :

<form  action= "computeBill "  >
</form>

当请求一个servlet时,也可以在请求的url-pattern中额外加入参数及其值,格式是:

url-pattern?参数1=值&参数2=值…参数n=值
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<style>
   #textStyle{
      font-family:宋体;font-size:36;color:blue 
   }
</style>
<HTML><body bgcolor=#ffccff>
<form action="computeBill?discount=6" id= textStyle method=post>
  输入账单:<br>
<textArea name='billMess' id =textStyle rows=5 cols=30 >
 剁椒鱼头:62.9元,烤鸭:199元,红焖大虾:289.9元。
</textArea>
<br><input type=submit id=textStyle value="提交">
</form>
</body></HTML>
package moon.sun;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class Example6_3_Servlet extends HttpServlet{
   public void init(ServletConfig config) throws ServletException{
      super.init(config);
   }
   public void service(HttpServletRequest request,HttpServletResponse response)
                       throws IOException{
      request.setCharacterEncoding("utf-8");
      response.setContentType("text/html;charset=utf-8");
      PrintWriter out=response.getWriter();
      out.println("<html><body bgcolor=yellow>");
      String discountMess=request.getParameter("discount");
      double discount = Double.parseDouble(discountMess);
      String billMess=request.getParameter("billMess");
      if(billMess == null) {
         out.print("没有账单");  
         return;
      }
      double bill = getPriceSum(billMess); //账单金额。
      double billDiscount = bill*(discount/10); //优惠后的金额。
      out.print("<h2>"+billMess+"<br>消费:"+bill+"圆"); 
      out.print("优惠"+discount+"折<br>后的金额:"+billDiscount+"圆");       
      out.print("</h2></body></html>");
   } 
   public double getPriceSum(String input){  // 定义方法
      Pattern pattern;          //模式对象
      Matcher matcher;          //匹配对象
      String regex="-?[0-9][0-9]*[.]?[0-9]*" ;//匹配数字的正则表达式
      pattern = Pattern.compile(regex);  //初试化模式对象
      matcher = pattern.matcher(input);  //初始化匹配对象,用于检索input
      double sum = 0;
      while(matcher.find()) {
         String str = matcher.group(); 
         sum += Double.parseDouble(str);
      } 
      return sum;
   }
}

2.通过超链接访问servlet

JSP页面可以使用超链接去请求某个servlet。如果web.xml文件中给出的请求servlet的url-pattern是/circle,那么超链接标记中href的值是circle(不要写成/circle):

<a href="circle"></a>
package moon.sun;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.awt.image.BufferedImage;
import java.awt.*;
import java.awt.geom.*; 
import javax.imageio.ImageIO;
public class Example6_4_Servlet extends HttpServlet{
   HttpServletRequest request;
   HttpServletResponse response;
   public void init(ServletConfig config) throws ServletException{
      super.init(config);
   }
   public void service(HttpServletRequest request,HttpServletResponse response)
                       throws IOException{
      this.request = request;
      this.response = response;
      request.setCharacterEncoding("utf-8");
      String mess = request.getParameter("mess");
      String radius = request.getParameter("radius");
      if(mess.equals("area")) {
          getArea(Double.parseDouble(radius));
      }
      else if(mess.equals("geometry")){
          getGeometry(Double.parseDouble(radius));
      }
   }
   void getArea(double r) throws IOException{
      response.setContentType("text/html;charset=utf-8");
      PrintWriter out=response.getWriter();
      double area = Math.PI*r*r;
      String result = String.format("%.2f",area);
      out.print("<h2>半径"+r+"圆的面积(保留2位小数):<br>"); 
      out.print(result);       
      out.print("</h2></body></html>");
   } 
   void getGeometry(double r) throws IOException{ 
      response.setContentType("image/jpeg");
      Ellipse2D ellipse= new Ellipse2D.Double(30,30,2*r,2*r);
      BufferedImage image = getImage(ellipse);
      OutputStream outClient= response.getOutputStream();
      boolean boo =ImageIO.write(image,"jpeg",outClient);
   } 
   BufferedImage getImage(Shape shape){ //得到图形的图像
        int width=800, height=600;
        BufferedImage image = 
        new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        Graphics g = image.getGraphics();
        g.fillRect(0, 0, width, height);
        Graphics2D g_2d=(Graphics2D)g; 
        g_2d.setColor(Color.blue);
        g_2d.fill(shape); 
        return image;
    }
}
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<style>
   #textStyle{
      font-family:宋体;font-size:36;color:blue 
   }
</style>
<HTML><body bgcolor=#ffccff>
<% double r = 100.8;
%>
<p id=textStyle>
<a href ="circle?mess=area&radius=<%= r %>">看半径<%=r%>圆的面积。</a><br>
<a href ="circle?mess=geometry&radius=<%=r%>">看半径<%=r%>圆的图形。</a>
</p></body></HTML>

6.4 共享变量

Servlet类是HttpServlet的一个子类,在编写子类时就可以声明某些成员变量,那么,请求servlet的用户将共享该servlet的成员变量。

<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<HTML><body bgcolor=#ffccff>
<p style="font-family:宋体;font-size:36;color:blue">
<a href="computePI" >参与计算PI的值</a>
</p></body></HTML>
package moon.sun;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class Example6_5_Servlet extends HttpServlet{
    double sum=0,i=1,j=1; //被所有用户共享
    int number=0;         //被所有用户共享
    public void init(ServletConfig config) throws ServletException{
        super.init(config);
    }
    public synchronized void service(HttpServletRequest request,
              HttpServletResponse response) throws IOException { 
       response.setContentType("text/html;charset=utf-8");
       PrintWriter out=response.getWriter();
       out.println("<html><body bgcolor=cyan>");
       number++;
       sum=sum+i/j;
       j=j+2;
       i = -i;  
       out.println("<h1>servlet:"+getServletName()+
                    "已经被请求了"+number+"次");
       out.println("<br>现在PI的值是:");
       out.println(4*sum);
       out.println("</h1></body></html>");
  } 
}

6.5 doGet和doPost方法

HttpServlet类除了init、service、destroy方法外,该类还有两个很重要的方法:doGet和doPost,用来处理用户的请求并作出响应。

实际上HttpServlet类所给出的service方法的功能是检查HTTP请求类型(get、post),并在service方法中根据用户的请求方式,在service方法中对应地再调用doGet或doPost方法。

因此,在编写的Servlet类(HttpServlet类的一个子类)时,也可以不重写service方法来响应用户,直接继承service方法即可。

如果不重写service方法,就需要在Servlet类中重写doPost或doGet方法来响应用户的请求。如果不论用户请求类型是post还是get,Tomcat服务器的处理过程完全相同,那么可以只在doPost方法中编写处理过程,而在doGet方法中再调用doPost方法即可,或只在doGet方法中编写处理过程,而在doPost方法中再调用doGet方法。如果根据请求的类型进行不同的处理,就要在两个方法中编写不同的处理过程(这一点比service方法更为灵活)

<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<style>
   #textStyle{
      font-family:宋体;font-size:36;color:blue 
   }
</style>
<HTML><body bgcolor=#ffccff>
<form action="sumORproduct" id =textStyle method=post>
  输入数字,用逗号分隔提交给servlet(post方式):
  <br><input type=text id =textStyle name="number"/>
  <input type=submit id =textStyle value="提交">
</form>
<form action="sumORproduct" id =textStyle method=get>
   输入数字,用逗号分隔提交给servlet(get方式):
  <br><input type=text id =textStyle name="number"/>
  <input type=submit id =textStyle value="提交"/>
</form>
</body></HTML>
package moon.sun;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class Example6_6_Servlet extends HttpServlet{
   public void init(ServletConfig config) throws ServletException{
      super.init(config);
   }
   public void  doPost(HttpServletRequest request,HttpServletResponse response)
                throws ServletException,IOException{
      request.setCharacterEncoding("utf-8");
      response.setContentType("text/html;charset=utf-8");
      PrintWriter out=response.getWriter();
      out.println("<html><body bgcolor=cyan>");
      String s=request.getParameter("number");
      String []a=s.split("[,,]+");
      double sum = 0;
      for(String item:a) {
         if(item.length()>=1)
          sum+=Double.parseDouble(item);
      } 
      out.print("<h2>用户的请求方式是"+request.getMethod()+"<br>") ;
      for(String item:a) {
         if(item.length()>=1)
          out.print(item+" ");
      }  
      out.print("<br>的和是"+sum);
      out.println("</h2></body></html>");
   } 
   public  void  doGet(HttpServletRequest request,HttpServletResponse response) 
                        throws ServletException,IOException{

      request.setCharacterEncoding("utf-8");
      response.setContentType("text/html;charset=utf-8");
      PrintWriter out=response.getWriter();
      out.println("<html><body bgcolor=yellow>");
      String s=request.getParameter("number");
      String []a=s.split("[,,]+");
      double product = 1;
      for(String item:a) {
         if(item.length()>=1)
          product*=Double.parseDouble(item);
      }
      out.print("<h2>用户的请求方式是"+request.getMethod()+"<br>") ; 
      for(String item:a) {
         if(item.length()>=1)
          out.print(item+" ");
      }   
      out.print("<br>的乘积是"+product);
      out.println("<h2></body></html>");
   }
}

6.6 重定向与转发

重定向的功能是将用户从当前页面或servlet定向到另一个JSP页面或servlet。转发的功能是将用户对当前JSP页面或servlet的请求转发给另一个JSP页面或servlet。本节学习在Servlet类中使用HttpServletResponse类的sendRedirect重定向方法,以及RequestDispatcher类的forward转发方法,并指出二者的区别。

1.sendRedirect方法

重定向方法void sendRedirect(String location)

将用户重新定向到另一个JSP页面或servlet。重定向方法仅仅是将用户从当前页面或servlet定向到另一个JSP页面或servlet,但不能将用户对当前页面或servlet的请求(HttpServletRequest对象)转发给所定向的资源。即重定向的目标页面或servlet无法使用request获取用户提交的数据。

执行sendRedirect方法(重定向,也见4.2.3)时,Tomcat服务器还是要把当前的servlet代码执行完毕后才实施重定向(跳转)操作,但Tomcat服务器不再给用户看当前servlet代码的执行效果。如果在执行sendRedirect(URL url)方法后,servlet紧接着执行了return返回语句,那么Tomcat服务器会立刻结束当前servlet的执行。

2.forward方法

  RequestDispatcher dispatcher = 
  request.getRequestDispatcher(JSP页面的URL或servlet的url-pattern);
转发。在步骤(1)中获取的RequestDispatcher对象调用

void forward(ServletRequest request,ServletResponse response)             throws ServletException,ava.io.IOException
方法可以将用户对当前JSP页面或servlet的请求转发给RequestDispatcher对象所指定的JSP页面或servlet

dispatcher.forward (request,response);
把用户对当前JSP页面或servlet的请求转变为对转发到的JSP页面或servlet的请求。

RequestDispatcher对象可以把用户对当前JSP页面或servlet的请求转发给另一个JSP页面或servlet,而且将用户对当前JSP页面或servlet的请求传递给转发到的JSP页面或servlet。也就是说,当前页面所转发到的标页面或servlet可以使用request获取用户提交的数据。

3.二者的区别

转发(forwar)和重定向方法(sendRedirect)不同的是,用户可以看到转发到的JSP页面或servlet的运行效果,但是,在浏览器的地址栏中不能看到forward方法转发到的JSP页面的地址或servlet的地址,用户在浏览器的地址栏中所看到的仍然是当前JSP页面的URL或servlet的url-pattern。如果此时刷新浏览器,那么请求将是当前的JSP页面或servlet。所转发到的标页面或servlet可以使用request获取用户提交的数据。而重定向的目标页面或servlet无法使用request获取用户提交的数据。

另外,当servlet中执行forward方法实施转发操作时,Tomcat会立刻结速当前servlet的执行。而servlet中执行sendRedirect方法(重定向,也见4.2.3)时,Tomcat服务器还是要把当前的servlet代码执行完毕后才实施重定向(跳转)操作,但Tomcat服务器不再给用户看当前servlet代码的执行效果。如果在执行sendRedirect(URL url)方法后,servlet紧接着执行了return返回语句,那么Tomcat服务器会立刻结束当前servlet的执行。

<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<style>
   #textStyle{
      font-family:宋体;font-size:36;color:blue 
   }
</style>
<HTML><body bgcolor=#ffccff>
<p id=textStyle>
<form action="handleForward" id= textStyle method=post>
  输入数字(用逗号空格或其他非数字字符分隔):<br>
<textArea name='digitData' id =textStyle rows=5 cols=30 >
</textArea>
<br><input type=submit id=textStyle name = submit value="提交(排序数字sort)"/>
<br><input type=submit id=textStyle name = submit value="提交(求数字代数和sum)"/>
</form>
</p></body></HTML>
package moon.sun;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class Example6_7_Servlet extends HttpServlet{
   public void init(ServletConfig config) throws ServletException{
      super.init(config);
   }
   public void  doPost(HttpServletRequest request,HttpServletResponse response)
                throws ServletException,IOException{
      RequestDispatcher dispatcher = null; //负责转发的对象。
      request.setCharacterEncoding("utf-8");
      response.setContentType("text/html;charset=utf-8");
      String mess = request.getParameter("submit");
      String digitData = request.getParameter("digitData");
      if(digitData == null ||digitData.length()==0) {
          response.sendRedirect("example6_7.jsp");//重定向到输入数据页面。
          return;
      }
      if(mess.contains("sort")) {
         dispatcher = request.getRequestDispatcher("sort");//转发给负责排序的servlet
         dispatcher.forward(request,response);
      }
      else if(mess.contains("sum")){
         dispatcher = request.getRequestDispatcher("sum");//转发给负责排序的servlet
         dispatcher.forward(request,response);
      }
   } 
   public  void  doGet(HttpServletRequest request,HttpServletResponse response) 
                        throws ServletException,IOException{
       doPost(request,response);
   }
}

6.7 使用session

HTTP通信协议是用户与服务器之间一种请求与响应(request/response)的通信协议,属于无状态协议。所谓无状态是指,当用户(浏览器)发送请求给服务器,Tomcat服务器作出响应后,如果同一个用户再发送请求给Tomcat服务器时,Tomcat服务器并不知道就是刚才的那个用户。简单地说,Tomcat服务器不会记录用户的信息。用户在访问一个Web服务目录期间,Tomcat服务器为该用户分配一个session对象(称为用户的会话),Tomcat服务器可以在各个页面以及servlet中使用这个session记录用户的有关信息,而且Tomcat服务器保证不同用户的session对象互不相同。

HttpServletRequest对象request调用getSession方法获取用户的session对象:

HttpSession session=request.getSession(true);

访问某个Web服务目录的用户,在不同的servlet中获取的session对象是完全相同的,不同的用户的session对象互不相同。

实验代码:

<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<style>
   #tom{
      font-family:宋体;font-size:26;color:blue 
   }
</style>
<%
String s ="(20,220)(220,20)(420,220)(220,420)";
%>
<HTML><body bgcolor=#ffccff>
<p id=tom>
<form action="drawPolygon" id= tom method=post>
输入多边形的顶点,格式是(m,n)<br>m,n为整数 0<=m<=800,0<=n<=600<br>
<textArea name="polygonVertex" id =tom rows=5 cols=30 >
<%= s %>
</textArea>
<br><input type=submit id=tom value="提交"/>
</form>
</p></body></HTML>
package moon.sun;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.awt.image.BufferedImage;
import java.awt.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.awt.geom.*; 
import javax.imageio.ImageIO;
public class DrawPolygon_Servlet extends HttpServlet{
   HttpServletRequest request;
   HttpServletResponse response;
   public void init(ServletConfig config) throws ServletException{
      super.init(config);
   }
   public void service(HttpServletRequest request,HttpServletResponse response)
                       throws IOException{
      request.setCharacterEncoding("utf-8");
      String polygonVertex = request.getParameter("polygonVertex");
      if(polygonVertex == null||polygonVertex.length()==0){
          response.sendRedirect("inputVertex.jsp");//重定向到输入数据页面。
          return;
      }
      response.setContentType("image/jpeg");
      Polygon  polygon = getPolygon(polygonVertex);
      BufferedImage image = getImage(polygon);
      OutputStream outClient= response.getOutputStream();
      boolean boo =ImageIO.write(image,"jpeg",outClient);
   }
   Polygon getPolygon(String polygonVertex){ //得到多边形。
      Polygon polygon = new Polygon();
      Pattern pattern;             //模式对象。
      Matcher matcher;            //匹配对象。
      String regex="(\\d+[,, ]+\\d+)" ;//匹配顶点的正则表达式。
      pattern = Pattern.compile(regex);  //初试化模式对象。
      matcher = pattern.matcher(polygonVertex);  //用于检索polygonVertex。
      while(matcher.find()) {
         String str = matcher.group(); 
         String []vertex = str.split("[( ),, ]+");
         polygon.addPoint(Integer.parseInt(vertex[0]),Integer.parseInt(vertex[1]));
      } 
      return polygon;
   }
   BufferedImage getImage(Shape shape){ //得到图形的图像。
        int width=1000, height=800;
        BufferedImage image = 
        new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        Graphics g = image.getGraphics();
        g.fillRect(0, 0, width, height);
        Graphics2D g_2d=(Graphics2D)g; 
        g_2d.setColor(Color.blue);
        g_2d.draw(shape); 
        return image;
   }
}

总结

  Java Servlet 的核心是在服务器端创建响应用户请求的对象,即创建 servlet 对象。servlet对象第一次被请求加载时,服务器创建一个 servlet 对象,这个对象调用 init 方法完成必要的初始化工作。init 方法只被 servlet 对象调用一次,当后续的客户请求该servlet 对象服务时,服务器将启动一个新的线程,在该线程中,servlet 对象调用 service方法响应客户的请求。每个客户的每次请求都导致 service 方法被调用执行,调用过程运行在不同的线程中,互不干扰。
  Servlet 类继承的 service 方法检查 HTTP 的请求类型(get 、post 等),并在 service 方法中根据用户的请求方式,对应地调用 doGet 或 doPost 方法。因此,Servlet 类不必重写service 方法,直接继承该方法即可。可以在 Servlet 类中重写 doPost 或 doGet 方法来响应用户的请求。
  RequestDispatcher 对象可以把用户对当前JSP 页面或 servlet 的请求转发给另一个JSP页面或 servlet,而且将用户对当前JSP 页面或 servlet 的请求和响应传递给转发到的JSP页面或 servlet。也就是说,当前页面所要转发到的目标页面或 servlet 对象可以使用request 获取用户提交的数据以上就是本章内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值