JSP_Java Servlet基础

目录

前言

6.1servlet的部署、创建与运行

6.1.1  Servlet类及字节码文件的保存

6.1.2  编写部署文件web.xml

6.1.3  servlet的创建与运行

6.1.4  向servlet传递参数的值

6.2servlet的工作原理

6.2.1  servlet 对象的生命周期

6.2.2  init方法

6.2.3  service方法

6.2.4  destroy方法

6.3通过JSP页面访问servlet

6.4共享变量

6.5doPost和doGet方法

6.7重定向与转发

6.8使用session


前言

     有些Web应用可能只需要JSP+Javabean就能设计得很好,但是有些Web应用,就可能需要JSP+Javabean+servlet来完成,即需要服务器再创建一些servlet,配合JSP页面来完成整个Web应用程序的工作。关于这一点将在第7章的MVC模式中讲述。   

6.1servlet的部署、创建与运行

   本章在webapps目录下新建一个Web服务目录ch6,因此,除非特别约定,本章例子中涉及的JSP页面均保存在ch6中。创建servlet的类的字节码文件需要按要求存放,因此需要在ch6下建立如下的目录结构(目录名字WEB-INF中的字母大写): \ch6\WEB-INF\classes ▲本章使用的javax.servlet 和javax.servlet.http包中的类不在JDK提供的核心类库中,为了方便编译Java源文件,请事先将Tomcat安装目录lib子目录中的servlet-api.jar文件复制(不要剪贴)到 \ch6\WEB-INF\classes 中。

6.1.1  Servlet类及字节码文件的保存

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

这就是一个简单的Servlet类

2.字节码文件的保存

字节码文件按着类的包名对应的目录路径保存到Web服务目录中特定子目录中。包名moon.sun对应的目录路径是moon\sun,因此,保存到:

\ch6\WEB-INF\classes\moon\sun

可以事先将Java源文件,按照其包名,比如,包名为moon.sun,保存到

\ch6\WEB-INF\classes\moon\sun

然后用命令行进入moon\sun的父目录classes(不要进入moon或sun目录)编译:

classes> javac -cp servlet-api.jar moon\sun\Example6_1.java

6.1.2  编写部署文件web.xml

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

1、编写的web.xml文件必须保存到Web服务目录的WEB-INF子目录中,比如ch6\WEB-INF中(不要保存在ch6中)。根据例子6_1给出的Servlet类,web.xml文件的内容如下(需要用纯文本编辑器编辑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>

</web-app>

2、web.xml由Tomcat服务器负责管理,Tomcat服务器配有内置的解析器,可以解析XML文件的标记中的数据。

 3、Web服务目录的WEB-INF子目录下的web.xml文件负责管理当前Web服务目录下的全部servlet,当该Web服务目录需要提供更多的servlet时,只要在web.xml文件中增加servlet和servlet-mapping子标记即可。 

4、对于webapps下的Web服务目录,如果修改并重新保存web.xml文件,Tomcat服务器就会立刻重新读取web.xml文件,因此,修改web.xml文件不必重新启动Tomcat服务器。但是,如果修改导致web.xml文件出现错误,Tomcat服务器就会关闭当前Web服务目录下的所有servlet的使用权限。所以必须保证web.xml文件正确无误,才能成功启动Tomcat服务器。但是,对于不是webapps下的Web服务目录,如果新建或修改了相应的web.xml文件,需要重新启动Tomcat服务器。      

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)                                                                          

6.2servlet的工作原理

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=值 例如:

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

2、通过超链接访问servlet

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

<a href="circle"></a>

6.4共享变量

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

service方法可能被多次的调用。也就是说,当后续的用户请求该servlet时,Tomcat服务器将启动一个新的线程,在该线程中servlet调用service方法响应用户的请求,即每个用户的请求都导致service方法被调用执行,调用过程运行在不同的线程中,互不干扰。因此,不同线程的service方法中的局部变量互不干扰,一个线程改变了自己的service方法中局部变量的值不会影响其他线程的service方法中的局部变量。

例:

数学上有一个计算PI 的公式,利用servlet的成员变量被所有用户共享这一特性实现多用户计算 的值,即任何用户请求访问servlet时都参与了一次 的计算。

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>

example6_5.jsp

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

Example6_5_Servlet.java

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.5doPost和doGet方法

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

doGet和doPost方法是Java Servlet API中的两个HTTP请求处理方法。

doGet方法处理HTTP GET请求,它通常用于从服务器获取数据或执行只读操作。当浏览器通过URL发出GET请求时,服务器会调用doGet方法来响应请求。例如,当用户在浏览器中输入http://example.com/servlet/MyServlet,服务器会调用MyServlet的doGet方法。

doPost方法处理HTTP POST请求,它通常用于向服务器提交数据或执行写操作。当浏览器通过表单提交POST请求时,服务器会调用doPost方法来处理请求。例如,当用户在浏览器中提交表单时,服务器会调用MyServlet的doPost方法来处理表单数据。

在Servlet中,开发人员可以根据需要实现doGet或doPost方法来处理HTTP请求。通常,doGet方法和doPost方法都会从ServletRequest对象中获取请求参数,然后通过ServletResponse对象将响应发送回浏览器。

6.7重定向与转发

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

1.sendRedirect方法

sendRedirect方法是Java Servlet API中的一个重定向方法,它可以将请求重定向到另一个URL或Servlet。

使用sendRedirect方法可以在服务器端将请求重定向到另一个URL或Servlet,这样浏览器会收到一个新的URL,并向该URL发出新的请求。这种方式可以用于实现页面跳转、登录验证、错误处理等功能。

sendRedirect方法的语法如下:

response.sendRedirect("url");

其中,url是要重定向到的URL或Servlet的路径。如果url是相对路径,则相对于当前请求的URL。

例如,如果当前请求的URL是http://example.com/servlet/MyServlet,而调用sendRedirect方法时指定的url是"index.jsp",则浏览器会重定向到http://example.com/servlet/index.jsp。

需要注意的是,调用sendRedirect方法后,当前请求的处理会立即结束,并且浏览器会收到一个新的URL。因此,在调用sendRedirect方法后,不应该再向浏览器发送任何响应。

2.forward方法

forward方法是Java Servlet API中的一个转发方法,它可以将请求转发到另一个Servlet或JSP页面。

使用forward方法可以在服务器端将请求转发到另一个Servlet或JSP页面,这样可以将请求的处理过程分解为多个Servlet或JSP页面来处理,从而实现更加灵活的应用程序设计。

forward方法的语法如下:

request.getRequestDispatcher("url").forward(request, response);

其中,url是要转发到的Servlet或JSP页面的路径。如果url是相对路径,则相对于当前请求的URL。

在调用forward方法时,需要传递当前的ServletRequest对象和ServletResponse对象作为参数。这样,被转发的Servlet或JSP页面就可以使用这些对象来处理请求和发送响应。

需要注意的是,调用forward方法后,当前请求的处理不会立即结束,而是将请求转发到另一个Servlet或JSP页面进行处理。因此,在调用forward方法后,仍然可以向浏览器发送响应,但是这些响应只会被浏览器忽略。

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的执行。

6.8使用session

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

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

HttpSession session=request.getSession(true);

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值