作业要求:
- 编写一个Serlvet以便显示该Servlet被访问的次数。
- 编写一个Servlet程序,在doGet方法中显示一个Form表单,用户可以输入姓名和电子邮件地址,用户提交该表单后,doPost方法动态读出请求参数,并输出这些参数。提示:使用request对象的getParameterNames()方法。
- 描述Serlvet的生命周期。
- 实现Servlet有几种方法,每种方法都有哪些特点。
- 如何配置Serlvet。
开始作业
作业 1:点此查看要求
仅贴出Servlet的主体代码如下:
@WebServlet("/Servlet_1") public class Servlet_1 extends HttpServlet { private static final long serialVersionUID = 1L;
public Servlet_1() { super(); } int num=1; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setHeader("Content-type", "text/html;charset=UTF-8"); PrintWriter pw = resp.getWriter(); pw.println("Servlet被访问的次数为:"+num++); }
}
|
运行图示如下:
作业 2:点此查看要求
@WebServlet("/Servlet_2") public class Servlet_2 extends HttpServlet { private static final long serialVersionUID = 1L;
public Servlet_2() { super(); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { req.setCharacterEncoding("UTF-8"); resp.setHeader("Content-type", "text/html;charset=UTF-8"); PrintWriter out = resp.getWriter(); out.println("<html>"); out.println("<head><title>表单提交</title></head>"); out.println("<body>"); out.println("<h1>表单提交页面</h1>"); out.println("<form action='Servlet_2' method='post'>"); out.println("姓名:<input type='text' name='name' /><br>"); out.println("邮箱:<input type='mail' name='mail' /><br>"); out.println("<input type='submit' value='提交'>"); out.println("</form>"); out.println("</body>"); out.println("</html>"); } catch (Exception e) { e.printStackTrace(); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); resp.setHeader("Content-type", "text/html;charset=UTF-8"); String name = req.getParameter("name"); String mail = req.getParameter("mail"); PrintWriter out = resp.getWriter(); out.println("提交的姓名为:"+name+"<br />"); out.println("提交的邮箱为:"+mail+"<br />"); } }
|
运行图示如下:
作业 3:点此查看要求
具体答案内容,请查看这里
作业 4:点此查看要求
Servlet有三种实现方式:
- 继承原生Servlet接口
- 继承GenericServlet类
- 继承HttpServlet类
Servlet的这三种实现方式的具体讲解如下:
1.继承原生Servlet接口:
@WebServlet("/Servlet_1_1") public class Servlet_1_1 implements Servlet { public void destroy() { System.out.println("destroy...."); } public ServletConfig getServletConfig() { return null; } public String getServletInfo() { return null; } public void init(ServletConfig arg0) throws ServletException { System.out.println("init...."); } public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { System.out.println("service...."); } }
|
注解:
这种实现方法是新建一个类,该类继承了Servlet接口,因为新建类的缘故,我们需要手动添加@WebServlet("/Servlet_1_1")
代码,然后重写Servlet接口的五个方法。
题外话:Servlet接口的五个方法
- init()
- service()
- destroy()
- getServletConfig()
- getServletInfo()
init()方法:
在Servlet实例化后,Servlet容器会调用init()方法来初始化该对象,主要是为了让Servlet对象在处理客户请求前可以完成一些初始化工作,例如:建立数据库的连接,获取配置信息等。对于每一个Servlet实例,init()方法只能被调用一次。init()方法有一个类型为ServletConfig的参数,Servlet容器通过这个参数向Servlet传递配置信息。Servlet使用ServletConfig对象从Web应用程序的配置信息中获取以名-值对形式提供的初始化参数。另外,在Servlet中,还可以通过ServletConfig对象获取描述Servlet运行环境的ServletContext对象,使用该对象,Servlet可以和它的Servlet容器进行通信。
Service()方法:
容器调用service()方法来处理客户端的请求。要注意的是,在service()方法被容器调用之前,必须确保init()方法正确完成。容器会构造一个表示客户端请求信息的请求对象(类型为ServletRequest)和一个用于对客户端进行响应的响应对象(类型为ServletResponse)作为参数传递给service()。在service()方法中,Servlet对象通过ServletRequest对象得到客户端的相关信息和请求信息,在对请求进行处理后,调用ServletResponse对象的方法设置响应信息。
destroy()方法:
当容器检测到一个Servlet对象应该从服务中被移除的时候,容器会调用该对象的destroy()方法,以便让Servlet对象可以释放它所使用的资源,保存数据到持久存储设备中,例如将内存中的数据保存到数据库中,关闭数据库的连接等。当需要释放内存或者容器关闭时,容器就会调用Servlet对象的destroy()方法,在Servlet容器调用destroy()方法前,如果还有其他的线程正在service()方法中执行容器会等待这些线程执行完毕或者等待服务器设定的超时值到达。一旦Servlet对象的destroy()方法被调用,容器不回再把请求发送给该对象。如果需要改Servlet再次为客户端服务,容器将会重新产生一个Servlet对象来处理客户端的请求。在destroy()方法调用之后,容器会释放这个Servlet对象,在随后的时间内,该对象会被java的垃圾收集器所回收。
getServletConfig()方法:
该方法返回容器调用init()方法时传递给Servlet对象的ServletConfig对象,ServletConfig对象包含了Servlet的初始化参数。
getServletInfo()方法:
返回一个String类型的字符串,其中包括了关于Servlet的信息,例如,作者、版本和版权。该方法返回的应该是纯文本字符串,而不是任何类型的标记。
关于Servlet接口的五个方法的精彩文字转载自这里。
2.继承GenericServlet类:
@WebServlet("/Servlet_1_2") public class Servlet_1_2 extends GenericServlet {
@Override public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException { try{ System.out.println("service...."); }catch(Exception e){ e.printStackTrace(); } } }
|
注解:
这里的实现方法也是新建一个类,手动添加@WebServlet("/Servlet_1_2")
这一行代码,然后只重写service()方法即可,如果我们直接通过实现Servlet接口来编写一个Servlet类,就需要实现Servlet接口中定义的5种方法,为了简化Servlet的编写,在javax.servlet包中,给我们提供了一个抽象的类GenericServlet,它提供了除service()方法外的其他4种方法的简单实现。GenericServlet类定义了一个通用的,不依赖具体协议的Servlet。实践出现的一个有意思的事情是,我进入映射的虚拟路径/Servlet_1_2后,发现控制台输出的信息如下,这里我并没有修改init()方法:
2.继承HttpServlet类:
@WebServlet("/Servlet_1") public class Servlet_1 extends HttpServlet { private static final long serialVersionUID = 1L;
@Override protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { System.out.println("service...."); }
@Override public void destroy() { System.out.println("destroy...."); }
@Override public void init() throws ServletException { System.out.println("init....."); } }
|
注解:
新建一个Servlet类时的默认构建方法,也是最常用的构建方法。由于大多数网络应用中,都是浏览器通过HTTP协议去访问服务器资源,而我们编写的Servlet也主要是应用于HTTP协议的请求和响应,为了快速开发应用于HTTP协议的Servlet,在javax.servlet.http包中给我们提供了一个抽象的类HttpServlet,他继承自GenericServlet类,用于创建适合Web站点的HTTP Servlet。
作业 5:点此查看要求
配置Serlvet的过程可分为两种,一种是Servlet3.0版本之前的配置,相对来说比较麻烦,还有一种是Servlet3.0版本之后的配置,相对来说简单很多,具体的配置方法,我在JSP笔记_1_初次使用Servlet中已经详细说明过了,这里就不做具体说明了。