Java Web -----------第六章Java Servlet

目录

6.1servlet的部署、创建与运行

6.1.1源文件及字节码文件

6.1.2、编写部署文件web.xml

6.1.3、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


6.1servlet的部署、创建与运行


Java Servlet 的核心思想是在 Tomceat 服务器端创建啊应用户请求的 servlet 对象,简称servlet。因此 ,学习 Java Servlet 的首要任务是掌握怎样编写创建 servlet 的类 ,怎样在 Tomcat 服务器上保存这个类所得到的字节码文件,怎样编写 web. xml 部署文件,怎样请求 Tomcat 服务需创建一个 servlet。

6.1.1源文件及字节码文件


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

下面的例6_1 中的Example6_ 1. java 的Example6_1 类是一个简单的 Servlet 类。会在浏览器看到 hello 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{
       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)字节码的保存

为了能让 Tomcat 服务器使用Example6_ 1 类创建一个 servlet ,需要将例6_1 中的 Java源文件产生的Example6 1. class 字节码文件按照类的包名对应的目录路径保存到 Web 服务目录中特定子目录中。包名 moon. sun 对应的目录路径是 moonNXsun,因此,需要把 Example6 _1. class 保存到\ch6\WEB-INF\classes\moon\sun 中 。
注意保存类型选择为"所有文件“,将“编码”选择为"ANSI”。

然后用命令行进入 moonNsun 的父目录 classes (不要进入 moon或sun 目录)编译Example6 1. java:

classes > javac - cp servlet - api. jar moonNsunNExample6 1. java

注意,编译时不要忘记使用-cp 参数,该参数指定使用非核心类库中的类,例如 servlet-api. jar 文档中给出的类 ,-cp 参数只要 的出 jar 文档的位置即可(如果 jar 文档在当前目录,就直接输入 jar 文档的名字即可)。本章使用的 javax. servlet 和 javax. servlet. http 包中的类不在 JDK 提供的核心类库中,均在 servlet-api. jar 文档中,因此可以将 Tomcat 安装目录 lib 子目录中的 servlet-api. jar 文件复制(不要剪贴)到\ch6\WEB-INF\classes\中。否则,-cp 参数必须显式给出 servlet-api. jar 的位置 ,例如 :

classes > javac - cp D:\tomcat\lib\servlet - api. jar moon\sun\Example6_ 1. java

6.1.2、编写部署文件web.xml


Servlet 类的字节码文件保存到指定的目录后,必须为 Tomcat 服务器编写一个部署文件,只有这样 Tomcat 服务需才会用 Servlet 类创建 servlet 对象。该部署文件是一个XML 文件,名字必须是 web. xml。

可以在 Tomcat 服务需的 webapps 目录中的root 目录找到一个 web. xml 文件 ,参照它编写自己的 web. xml 文件。

编写的 web. xml 文件必须保存到 Web 服务目录的 WEB-INF 子目录中

根据例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>


一个XML 文件应当以 XML 声明作为文件的第一行,在其前面不能有空白、其他的处理指令或注释。XML 声明以“<? xml”标识开始、 以”? >“标识结束。注意“<?”和”xml”之间 ,以及”?”和”>”之间不要有空格。如果在 XML 声明中没有显式地指定encoding 属性的值,那么该属性的默认值为 UTF-8 编码。

servlet标记与子标记
servlet 标记需要有两个子标记: servlet-name 和 servlet-class,其中 servlet-name 标记的内容是 Tomcat 服务器创建的 servlet 的名字 ,servlet-class 标记的内容告知 Tomcat 服务器用哪个Servlet 类来创建 servlet。

servlet-mapping标记与子标记
子标记: servlet-name 和 url-pattern ,其中,servlet-name 标记的内容是 Tomcat 服务需创建的 servlet 的名字(该名字必须和对应的 servlet 标记的子标记 servlet-name 的内容相同 ) 。url-pattern 标记用来指定用户用怎样的 URL 格式来请求 servlet ,例如,url-pattern 标记的内容是/lookHello ,那么用户必须在浏览锅的地址栏中输入:

http://127.0.0.1:8080/ch6/lookHello

来请求名字是 hello 的 servlet。

6.1.3、servlet创建于运行


现在 ,用户就可以请求例61 给出的 Servlet 类创建的名字是 hello 的 servlet 了,根据 6. 1. 2节中的 web. xml 文件,用户在浏览右输入 :

http://127.0.0.1:8080/ch6/lookHello

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

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

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

request. getParameter(参数 n)

例 6 .2 中,用户请求 servlet 绘制一个椭圆,请求时将椭圆的宽(横轴长)和高(纵轴长 )通过参数 width 和 height 传递给 servlet。

Example6_2.java

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;
    }
}


用命令行进入 moon\sun 的父目录 classes,编译 Example6 2. java(有关约定见 6.1.1节):

classes > javac - cp servlet - api. jar moon\sun\Example6 2. java
web.xml

<?xml version="1.0" encoding="utf-8"  ?>
<web-app>
   <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>
</web-app>


在浏览器输入:

http://127.0.0.1:8080/ch6/lookPic?width = 500&height = 200

6.2、servlet的工作原理


6.2.1、servlet对象的生命周期


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

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

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

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

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

6.2.2、init方法


该方法是 HttpServlet 类中的方法,可以在子类中重与这个方法。init 方法的声明格式是:

public void init(ServletConfig config) throws ServletException

servlet 第一次被请求加载时,服务器创建一个 servlet, 这个对象调用 init 方法完成必要的初始化工作。该方法在执行时,服务需会把一个 SevletConfig 类型的对象传递给 init 方法,这个对象就被保存在 servlet 中 ,直到 servlet 被销毁。这个 ServletConfig 对象负责回 servlet传递服务设置信息 ,如果传递失败就会发生 ServeletException ,servlet 就不能正常工作。

6.2.3、service方法


该方法是 HttpServlet 类中的方法,可以在子类中直接继承该方法或重写这个方法。service 方法的声明格式是:

publlc vold service(HttpServletRequest 
request HttpServletResponse response)throw ServletException,IOExcept1ion)

当 servlet 成功创建和初始化之后,调用 service 方法来处理用户的请求并返回响应。Tomcat 服务器将两个参数传递给该方法。一个是 HttpServletRequest 类型的对象 ,该对象封装了用户的请求信息 ,另外一个参数对象是 HttpServletResponse 类型的对象 ,该对象用来响应用户的请求。和 init 方法不同的是,init 方法只被调用一次,而 service 方法可能被多次的调用。

6.2.4、destroy方法


该方法是 HttpServlet 类中的方法,子类可直接继承这个方法,一般不需要重写。destroy方法的声明格式是:

public destroy( )

当 Tomcat 服务器终止服务时,例如关闭 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 ,和否则将变成请求root 服务目录下的某个 servlet。

通过表单向 servlet 提交数据

Web 服务目录下的JSP 页面都可以通过 form 表单请求该 Web 服务目录下的某个servlet。如果 web. xml 文件中给出的 servlet 的 url-pattern 是/computeBill ,那么 form 表单中 action 给出的值就是 computeBill ,如下所示 ;

< form action = "computeBill /">

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

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

例如 :

< form action = "computeBill?sideA= 10.66&sideB = 23.9&sideC = 897 /">

通过JSP 页面访问 servlet 的好处是,JSP 页面可以负责页面的信息显示,信息的有关处理交给 servlet 去完成。

6.4、共享变量


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

6.5、doGet和doPost方法


doGet 和 doPost ,用来处理用户的请求并作出响应。当 Tomcat 服务咒创建servlet 后 ,该 servlet 会调用 init 方法初始化目己,以后每当 Tomcat 服务需再接一个对该 servlet 请求时 ,就会产生一个新线程 ,并在这个线程中让该 servlet 调用 servVice 方法。实际上 HttpServlet 类所给出的 service 方法的功能是检查HTTP 请求类型(get\post 等) ,并在 service 方法中根据用户的请求方式,在 service 方法中对应地再调用 doGet 或 doPost 方法。因此,在编写的 Servlet 类(HttpServlet 类的一个子类)时 ,也可以不重与 service 方法来响应用户 ,直接继承 service 方法即可。

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

6.6、重定向与转发


重定向的功能是将用户从当前页面或 servlet 定癌到另一个JSP 页面或servlet。转发的功能是将用户对当前JSP 页面或 servlet 的请求转发给另一个JSP 页面或 servlet。

(1)sendRedirect方法
重定回方法 void sendRedirect(CString location)是 HttpServletResponse 类中的方法。当用户请求一个 servlet 时 ,该 servlet 在处理数据后,可以使用重定癌方法将用户重新定回到另一个JSP 页面或 servlet。重是同方法仅仅是将用户从当前页面或 servlet 定回到另一个 JSP页面或 servlet ,但不能将用户对当前页面或 servlet 的请求(HttpServletRequest 对象)转发给所定向的资源。即重定回的目标页面或 servlet 无法使用 request 获取用户提交的数据。

(2)forward方法
当前页面所转发到的 JSP 页面或 servlet 可以使用 request 获取用户提交的数据。下面介绍实现转发的步骤。

得到 RequestDispatcher 对象。用户所请求的当前 JSP 或 servlet 可 以让HttpServletRequest 对象 request 调用

public RequestDispatcher getRequestDispatcher(String path)

方法返回一个 RequestDispatcher 对象 ,其中参数 path 是准备要转发到的JSP 页面的URL 或
servlet 的 url-pattern。例如 :

RequestDispatcher dispatcher = request. getRequestDispatcher(“target. jsp””)
RequestDispatcher dispatcher = request. getRequestDispatcher(“targetServlet””) ;

转发。在上一步中获取的 RequestDispatcher 对象调用

Vold forward( ServletRequest request, ServletResponse response)
throws SerVvJletException, ava. 10. IOExcept1lon

方法可以将用户对当前 JSP 页面或 servlet 的请求转发给 RequestDispatcher 对象所指定的
JSP 页面或 servlet ,例如 :

dispatcher. forward(Trequest, response) ;

把用户对当前 JSP 页面或 servlet 的请求转变为对转发到的 JSP 页面或 servlet 的请求。

(3)二者的区别

转发(forward) 和重定向方法(sendRedirect)不同的是,用户可以看到转发到的JSP 页面或 servlet 的运行效果,但是,在浏览需的地址栏中不能看到 forward 方法转发到的JSP 页面的地址或 servlet 的地址,用户在浏览需的地址栏中所看到的仍然是当前JSP 页面的 URL 或servlet 的 url-pattern。如果此时刷新浏览句,那么请求将是当前的 JSP 页面或 servlet。

(4)使用转发的好处
使用转发技术可以让 JSP 页面和处理数据的 servlet 解耦,JSP 页面只需和处理转发的servlet 打交道。例如 ,在实际问题中,对数据的处理可能有多种需求,那么可以把这些需求分别指派给几个 servlet 来完成,然后编写一个 servlet 负责接收用户的请求,并根据用户的请求信息将用户的请求转发给这些 servlet 中的某个 servlet。当更新某个需求时,只需重新编译相应的 Servlet 类,这有利于 Web 应用程序的维护。

例6 7 中有3个servlet,其中名字是 sort 的 servlet 负责排序数字 ,名字是 sum 的 servlet负责计算数字的代数和,名字是 handleForward 的servlet负责转发。

example6_7.jsp

<%@ 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>


 

Example6_7_Servlet.java

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);
   }
}
Example6_7_Servlet_Sum.java

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_7_Servlet_Sum 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();
      String digitData = request.getParameter("digitData");
      double sum = getPriceSum(digitData);
      out.println("<html><body bgcolor=cyan>");
      out.println("<h1>数字的代数和:"+sum);
      out.println("</h1></body></html>);

}
web.xml

<?xml version="1.0" encoding="utf-8"  ?>
<web-app>
<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>
    </web-app>


6.7、使用session


用户在访问一个 Web 服务目录期间,Tomcat 服务需为该用户分配一个 session 对象(称为用户的会话) ,Tomcat 服务需可以在各个页面以及 servlet 中使用这个 session 记录用户的有关人信息,而且 Tomcat 服务需保证不同用户的 session 对象互不相同。有关 session 对象的原理.和常用方法可参见 4. 3 节。
HttpServletRequest 对象 request 调用 getSession 方法获取用户的 session 对象 :

HttpSession sesslion = request. getSesslion(true) ;

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

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值