好了,既然开发环境已经配置好了。那么我们首先要搞定得便是servlet了,至于为什么不先去研究jsp,这是因为jsp与servlet本就是一体两面,jsp其本身经过编译、载入、转化等步骤最终会成为servlet(之后会专门来介绍这两个得关系)。所以我们首先学习servlet,如果servlet学习好了得话,那么在jsp中遇见得许多错误也会迎刃而解。那么,一起来研究下servlet把。
一、CGI
CGI即公共网关接口,它提供一个计算机程序同HTTP协议或者WWW服务的接口,也就是人机交互接口,其功能主要是处理来自表单得信息,然后在服务器再进行处理,最后反馈给浏览器。(只做简单了解)
二、Servlet
servlet又叫做服务端小程序,是在服务器上运行得小程序,它的主要功能是能够动态获得和修改数据,从而生成动态得web内容。其运行速度要比上述得CGI程序要快,主要原因是因为各个用户对servlet得请求会被创建为程序中得一个线程,从而降低了系统得开销。
1.servlet程序
先来写第一个servlet程序把,根据程序我们来探索其内部原理:
①首先选择File—new—web project—输入我们网站项目得名称—finish即可创建一个web项目。
②创建包:右键src—new—Package—输入包名(如cc.study)
③创建Servlet:右键包—new—Servlet—输入servlet程序名称
④创建成功显示
⑤创建html 表单并对servlet进行访问获取结果
修改web.xml中MainServlet得访问路径
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.5" 3 xmlns="http://java.sun.com/xml/ns/javaee" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 6 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" metadata-complete="true"> 7 <display-name></display-name> 8 <servlet> 9 <description>This is the description of my J2EE component</description> 10 <display-name>This is the display name of my J2EE component</display-name> 11 <servlet-name>MainServlet</servlet-name> 12 <servlet-class>cc.study.MainServlet</servlet-class> 13 </servlet> 14 15 <servlet-mapping> 16 <servlet-name>MainServlet</servlet-name> 17 <url-pattern>/main.do</url-pattern> 18 </servlet-mapping> 19 <welcome-file-list> 20 <welcome-file>index.jsp</welcome-file> 21 </welcome-file-list> 22 </web-app>
index.html代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>index.html</title> 5 6 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 7 <meta http-equiv="description" content="this is my page"> 8 <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 9 10 <!--<link rel="stylesheet" type="text/css" href="./styles.css">--> 11 12 </head> 13 14 <body> 15 <form action="main.do" method="get"> 16 姓名:<input type="text" name="name"> 17 <button>确认</button> 18 </form> 19 </body> 20 </html>
Servlet对doGet进行重写
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 package cc.study; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 6 import javax.servlet.ServletException; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 /** 12 * 13 * 项目名称:Boke 14 * 类名称:MainServlet 15 * 类描述: 对form表单提交姓名进行动态响应 16 * 创建人:墨染、 17 * 创建时间:2017-11-27 下午3:57:26 18 * 修改人:墨染、 19 * 修改时间:2017-11-27 下午3:57:26 20 * 修改备注: 21 * @version 22 * 23 */ 24 public class MainServlet extends HttpServlet { 25 @Override 26 protected void doGet(HttpServletRequest req, HttpServletResponse resp) 27 throws ServletException, IOException { 28 resp.setCharacterEncoding("utf-8"); 29 String name = req.getParameter("name"); 30 PrintWriter out = resp.getWriter(); 31 if (name != "") { 32 if (name.equals("zhangsan")) { 33 out.write("18"); 34 } else { 35 out.write("false"); 36 } 37 } else { 38 out.write("name is null"); 39 } 40 out.flush(); 41 out.close(); 42 } 43 }
获得结果如下显示:
输入zhangsan结果:
输入a结果:
不进行输入结果:
2.servlet实现过程
①浏览器向服务器发送请求
②服务器接收到请求并将改请求发送到服务端程序并判断由哪一个servlet进行处理
③servlet根据请求内容进行处理,(可能会操作数据库,也可能只返回某些数据)
④将数据返回给服务器,服务器再反馈给浏览器进行动态显示。
3.Servlet生命周期
一个Servlet程序得整个生命周期是由创建——销毁得。其主要得体现方法为:创建init(),处理请求Service(),销毁destroy()。
①init方法和destroy方法在整个生命周期中只运行一次
当只用init方法时:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 public class MainServlet extends HttpServlet { 2 private String flag=""; 3 @Override 4 public void init(ServletConfig config) throws ServletException { 5 flag="init start"; 6 } 7 // @Override 8 // public void destroy() { 9 // flag="destory stop"; 10 // } 11 @Override 12 protected void doGet(HttpServletRequest req, HttpServletResponse resp) 13 throws ServletException, IOException { 14 resp.setCharacterEncoding("utf-8"); 15 String name = req.getParameter("name"); 16 PrintWriter out = resp.getWriter(); 17 out.println(flag); 18 out.flush(); 19 out.close(); 20 } 21 }
获得结果为init start,即说明init方法在servlet进程创建得时候运行了,给flag赋值为init start。
当用init和destroy时,可以看到init方法是在开始不用调用执行,而destroy方法则是需要在doget方法内对其进行调用来处理,一般是用来结束数据库连接,或者保存文件使用。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 public class MainServlet extends HttpServlet { 2 private String flag=""; 3 @Override 4 public void init(ServletConfig config) throws ServletException { 5 flag="init start"; 6 } 7 @Override 8 public void destroy() { 9 System.out.println("destory被调用了"); 10 } 11 12 @Override 13 protected void doGet(HttpServletRequest req, HttpServletResponse resp) 14 throws ServletException, IOException { 15 resp.setCharacterEncoding("utf-8"); 16 String name = req.getParameter("name"); 17 PrintWriter out = resp.getWriter(); 18 out.println(flag); 19 out.flush(); 20 out.close(); 21 destroy(); 22 } 23 }
②service方法是整个servlet中最主要得执行方法,下面是父类中httpServlet得service代码,根据重写方法来启动线程对程序进行处理。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 protected void service(HttpServletRequest req, HttpServletResponse resp) 2 throws ServletException, IOException 3 { 4 String method = req.getMethod(); 5 6 if (method.equals("GET")) { 7 long lastModified = getLastModified(req); 8 if (lastModified == -1L) 9 { 10 doGet(req, resp); 11 } else { 12 long ifModifiedSince; 13 try { 14 ifModifiedSince = req.getDateHeader("If-Modified-Since"); 15 } 16 catch (IllegalArgumentException iae) { 17 ifModifiedSince = -1L; 18 } 19 if (ifModifiedSince < lastModified / 1000L * 1000L) 20 { 21 maybeSetLastModified(resp, lastModified); 22 doGet(req, resp); 23 } else { 24 resp.setStatus(304); 25 } 26 } 27 } 28 else if (method.equals("HEAD")) { 29 long lastModified = getLastModified(req); 30 maybeSetLastModified(resp, lastModified); 31 doHead(req, resp); 32 } 33 else if (method.equals("POST")) { 34 doPost(req, resp); 35 } 36 else if (method.equals("PUT")) { 37 doPut(req, resp); 38 } 39 else if (method.equals("DELETE")) { 40 doDelete(req, resp); 41 } 42 else if (method.equals("OPTIONS")) { 43 doOptions(req, resp); 44 } 45 else if (method.equals("TRACE")) { 46 doTrace(req, resp); 47 } 48 else 49 { 50 String errMsg = lStrings.getString("http.method_not_implemented"); 51 Object[] errArgs = new Object[1]; 52 errArgs[0] = method; 53 errMsg = MessageFormat.format(errMsg, errArgs); 54 55 resp.sendError(501, errMsg); 56 } 57 }
本文旨在帮助大家理解什么servlet以及servlet在生产流程中担任得角色,希望大家能够通过此文对此有一个直观得认识,当然,文中可能有些地方也可能会有措辞不当或者理解不充分得地方,如果大家有所发现,希望在评论处给于指正。:-D