• 1. 第三章 Servlet基础
  • 2. Java技术细分成了三个子平台 Java SE(Java Platform,Standard Edition) Java EE (Java Platform,Enterprise Edition) Java ME(Java Platform,Micro Edition) Servlet的历史 1995年,Java技术正是推出。 1997年,sun公司紧接着又推出servlet。 Java的web编程技术还包括JSP、JavaBean、JSTL、EL等。2.1 Servlet简介2
  • 3. servlet Servlet(服务器端小程序)是使用Java语言编写的服务器端程序,可以生成动态的WEB页,Servlet主要运行在服务器端,并由服务器调用执行,是一种按照Servlet标准开发的Java类。 Servlet程序采用了多线程的处理方式,这样就使得Servlet程序的运行效率更高,而且Servlet还保留有Java的可移植性的特点,这样使得Servlet更易使用,功能也更加强大。2.1 Servlet简介3
  • 4. Servlet按照如下步骤进行处理 客户端(很可能是Web浏览器)通过HTTP提出请求。 WEB服务器接收该请求并将其发送给servlet。如果这个servlet尚未被加载,web服务器将把它加载到Java虚拟机并且执行它。 Servlet程序将接收该HTTP请求并执行某种处理。 Servlet会将处理后的结果向Web服务器返回应答。 WEB服务器将从Servlet收到的应答发回给客户端。Servlet处理的基本流程4
  • 5. Servlet程序类的继承关系 在整个Servlet程序之中最重要的就是Servlet接口,在此接口下定义了一个GenericServlet的子类,但是一般不会直接继承此类,而是根据所使用的协议选择GenericServlet的子类继承,例如:现在是采用HTTP协议处理的,所以一般而言当需要使用HTTP协议操作时用户自定义的Servlet类都要继承HttpServlet类。 Servlet程序实现5
  • 6. 实现要求 如果要开发一个可以处理HTTP请求的Servlet程序,就是: 定义一个遵循Servlet规范的Java类,也即要继承javax.servlet.http.HttpServlet类。 public class FirstServlet extends HttpServlet{} 覆写HttpServlet类中提供的doGet()或doPost()方法。 protected void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException 2.2 编写第一个Servlet6
  • 7. 永远的Hello World 具体步骤: 编写servlet源程序 建立web应用目录结构(手动编写则需要,MyEclipse已自动创建) 编写web.xml文件 部署web应用 启动web服务器、运行servlet 2.2 编写第一个Servlet7
  • 8. 编写servlet源程序 编写java类,例如:HelloServlet.java,该类继承HttpServlet类,并且覆写doGet()或doPost方法 建立web应用目录结构(如手工编写则需要,MyEclipse不需要此步骤,已自动创建好) 建立应用目录,例如:hello 在hello中创建WEB-INF目录,在WEB-INF中创建classes目录(存放单个类文件)和lib目录(存放打包的jar文件),创建web.xml文件 2.2 编写第一个Servlet8
  • 9. 编写web.xml文件 编写 任意名称 servlet的包.类 编写 与上面名称相同 /浏览器访问的名称 部署web应用 将整个应用目录拷贝到tomcat目录下的webapps下 运行servlet 启动tomcat服务器,在浏览器输入地址即可访问,例如: http://localhost:8080/hello/hello2.2 编写第一个Servlet端口号应用名Web.xml中配置的访问名称9
  • 10. 永远的Hello World—第一个servlet程序2.2 编写第一个ServletHelloServlet.javapackage edu.imut.hello; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HelloServlet extends HttpServlet { // 继承HttpServlet public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 覆写doGet()方法 PrintWriter out = resp.getWriter(); // 准备输出 out.println(""); // 输出html元素 out.println("MLDNJAVA");// 输出html元素 out.println(""); // 输出html元素 out.println("

    HELLO WORLD

    "); // 输出html元素 out.println(""); // 输出html元素 out.println(""); // 输出html元素 out.close() ; // 关闭输出 } }10
  • 11. 2.2 编写第一个Servlet---针对手工编写编译时会出现找不到servlet包的错误 如果用户使用手工的方式编译一个Servlet的话,则有可能在编译时会出现以下的错误提示: 软件包 javax.servlet 不存在 软件包 javax.servlet.http 不存在 这两个Servlet的开发包实际上是保存在%TOMCAT_HOME%\lib\servlet-api.jar路径下,但是由于现在使用javac命令编译的时候,是使用的JAVA SE环境编译的,但是Servlet本身已经属于JAVA EE的应用范畴,所以就出现了找不到开发包的情况,此时,有两种方式: 一种是通过classpath指定,在classpath中加入此开发包的路径 另外一种方式是将Servlet的开发包保存在%JAVA_HOME%\jdk1.6.0_02\jre\lib\ext目录之中 11
  • 12. 配置web.xml文件2.2 编写第一个Servlet hello edu.imut.hello.HelloServlet hello /hello 12
  • 13. 可以修改web.xml,增加多个映射路径2.2 编写第一个Servlet hello /helloServlet hello /hello.asp hello /hello.zhangsan hello /xhm/* 13
  • 14. 访问Servlet的方式 直接在浏览器地址栏输入访问路径来访问Servlet。 http://localhost:8080/ch02/hello 通过超链接访问Servlet Run the hello doGet方法 通过表单提交访问Servlet。
    ......
    2.2 编写第一个Servlet14
  • 15. Servlet API Servlet API 由两个java包组成:javax.servlet和javax.servlet.http javax.servlet包中定义的类和接口是独立于协议的 。 javax.servlet.http中包含了具体于HTTP协议的类和接口,该包中的某些类或接口继承了某些javax.servlet包中的类或接口。2.3 Servlet编程15
  • 16. Servlet接口 Javax.servlet.Servlet接口是任何一个Servlet都要直接或间接实现的 2.3 Servlet编程 方 法说 明public void init(ServletConfit config)Servlet实例化后,Servlet容器调用此方法完成初始化工作public ServletConfig getServletConfig()获取Servlet对象的配置信息,返回ServletConfig对象public void service(ServletRequest request, ServletResponse response)处理request对象封装的客户端请求,并使用response对象返回请求结果public String getServletInfo()返回描述Servlet的一个字符串public void destory()当Servlet将要卸载时由servlet引擎调用,以释放资源16
  • 17. ServletConfig接口 当Servlet容器初始化一个Servlet对象时,会为这个Servlet实例对象创建一个ServletConfig对象。包含Servlet的初始化参数信息 2.3 Servlet编程 方 法说 明public String getServletName()该方法返回一个Servlet实例的名称,该名称由服务器管理员提供public ServletContext getServletContext() 返回一个ServletContext对象的引用public String getInitParameter(String name) 返回一个由参数name决定的初始化变量的值,如果该变量不存在,返回nullpublic Enumeration getInitParameterNames() 返回一个存储所有初始化变量的枚举函数。如果servlet没有初始化变量,返回一个空枚举函数17
  • 18. GenericServlet类 GenericServlet类是一种与协议无关的Servlet,它直接实现了Servlet接口,是一个抽象类。 HttpServlet类 HttpServlet类继承了GenericServlet类,也是一个抽象类。HttpServlet类为Servlet接口提供了HTTP协议相关的通用实现。2.3 Servlet编程18
  • 19. ServletRequest接口 请求时,容器创建ServletRequest对象,封装请求信息;创建ServletResponse对象,封装响应信息 2.3 Servlet编程方 法说 明public Object getAttribute(String name)返回请求范围对象内以name为名字的属性的值,如果该属性不存在,这个方法将返回nullpublic void setAttribute(String name,Object o)将对象o保存在请求范围对象内名字为name的属性,如果第二个参数o为null,那么相当于调用removeAttribute(name)public void removeAttribute(String name)移除请求范围中名字为name的属性public String getCharacterEncoding()返回请求正文使用的字符编码的名字。如果请求没有指定字符编码,这个方法将返回nullpublic String getContentType()返回请求正文的MIME类型。如果类型不可知,这个方法将返回nullpublic String getParameter(String name)返回请求范围对象中name属性的值。如果name参数有多个值,那么这个方法将返回值列表中的第一个值。如果在请求中没有找到这个参数,这个方法将返回nullpublic String[] getParameterValues(String name)返回请求范围对象中name参数所有的值。如果这个参数在请求中并不存在,这个方法将返回null。该方法常用来获取客户端复选框的一组值public RequestDispatcher getRequestDispatcher(String path)返回指定资源名的RequestDispatcher对象,作为path所定位的资源的封装19
  • 20. ServletResponse接口 2.3 Servlet编程方 法说 明public String getCharacterEncoding()返回响应使用字符解码的名字。除非显式设置,否则为ISO-8859-1public OutputStream getOutputStream()返回用于将返回的二进制输出写入客户端的流,此方法和getWrite()方法二者只能调用其一public Writer getWriter()返回用于将返回的文本输出写入客户端的一个字符写入器,此方法和getOutputStream()二者只能调用其一public void setContentType(String type)设置字符编码方式和内容类型20
  • 21. HttpServletRequest接口 专用于HTTP的ServletRequest子接口,客户端浏览器发出的请求被封装成一个HttpServletRequest对象2.3 Servlet编程方 法说 明public Cookie[] getCookies()返回一个数组,该数组包含这个请求中当前的所有cookie。如果这个请求中没有cookie,返回一个空数组public String getMethod()返回这个请求使用的HTTP请求方式(例如:GET、POST、PUT)public String getRequestedSessionId()返回这个请求相应的session id。如果由于某种原因客户端提供的session id是无效的,这个session id将与在当前session中的session id不同,与此同时,将建立一个新的sessionpublic HttpSession getSession()返回与这个请求关联的当前的有效的session。在没有session与这个请求关联的情况下,将会新建一个sessionpublic HttpSession getSession(boolean create)返回与这个请求关联的当前的有效的session。在没有session与这个请求关联的情况下,如果参数create为真时将新建一个session;如果参数create为假,这个方法会返回空值。为了确保session能够被完全维持,Servlet开发者必须在响应被提交之前调用该方法21
  • 22. HttpServletResponse接口 专用于HTTP的ServletResponse子接口,服务器返回给客户端的信息被封装成一个HttpServletRequest对象 2.3 Servlet编程方 法说 明public void addCookie(Cookie cookie)将一个Cookie加入到响应中publicvoid sendRedirect(String location)public void sendError(int status) 设置响应状态码为指定值(可选的状态信息)22
  • 23. ServletContext接口 表示一个Web应用的上下文,运行在Java虚拟机的每一个Web应用都有一个与之相关的Servlet上下文2.3 Servlet编程方 法说 明public Object getAttribute(String name)返回Servlet上下文中名字为name的对象。 名字为name的对象是全局对象,因为它 们可以被同一Servlet在另外某一任意时刻 访问,或上下文中任意其它的Servlet访问public void setAttribute(String name,Object obj) 将对象obj保存在Servlet上下文中,名字 为namepublic String getInitParameter(String name)返回指定上下文范围的初始化参数值23
  • 24. HttpSession接口 被Servlet容器用来实现在HTTP客户端和HTTP会话两者的关联 2.3 Servlet编程方 法说 明public long getCreationTime()返回建立Session的时间,这个时间表示为自1970年1月1日0时0分0秒0毫秒(GMT)至Session创建所经历的的毫秒数public String getId()返回分配给这个Session的标识符。一个HTTP Session的标识符是一个由服务器来建立和维持的唯一的字符串public long getLastAccessedTime()返回客户端最后一次发出与这个Session有关的请求的时间,如果这个Session是新建立的,返回-1。这个时间表示为自1970年1月1日0时0分0秒0毫秒(GMT)至最后一次访问所经历的的毫秒数public int getMaxInactiveInterval()从最后一次与客户端发生交互开始计算,返回会话存活的最大秒数public void setMasInactiveInterval(int seconds)从最后一次与客户端发生交互开始计算,设置会话存活的最大秒数public Object getAttribute(String name)返回会话中名字为name的对象,如果不存在返回nullpublic void setAttribute(String name,Object value)将对象value保存在会话中,指定名字为namepublic void removeAttribute(String name)删除会话中此前保存的名称为name的对象24
  • 25. Servlet的生命周期 由Servlet容器(Web服务器)控制,五步: Servlet类加载->初始化->提供服务->销毁Servlet->卸载 2.3 Servlet编程25
  • 26. 2.3 Servlet编程加载Servlet WEB容器负责加载Servlet,当WEB容器启动时或在第一次使用该Servlet时,容器会负责创建Servlet实例,但用户必须通过部署描述符(web.xml)指定Servlet的位置(Servlet所在的包.类名称),成功加载后,WEB容器会通过反射的方式对Servlet进行实例化。 初始化 当一个Servlet被实例化之后,容器将调用init()方法初始化这个对象,初始化的目的是为了让Servlet对象在处理客户端请求前完成一些初始化工作,例如:建立数据库连接、读取资源文件信息等,如果初始化失败,则此Servlet将被直接卸载。 处理服务 当有请求提交时,Servlet将调用service()方法(常用的是doGet()或doPost())进行处理,在service()方法中,Servlet可以通过ServletRequest接收客户的请求,也可以利用ServletResponse设置响应信息。 销毁 当WEB容器关闭或者检测到一个Servlet要从容器中被删除时,会自动调用destroy()方法,以便让该实例释放掉所占用的资源。 卸载 当一个Servlet调用完destroy()方法后,此实例将等待被垃圾收集器所回收,如果需要再次使用此Servlet的时候,会重新调用init()方法初始化。 26
  • 27. Servlet生命周期对象的方法2.3 Servlet编程No.方法类型描述1public void init() throws ServletException普通Servlet初始化时调用2public void init(ServletConfig config) throws ServletException普通Servlet初始化时调用,可以通过ServletConfig读取配置信息3public abstract void service(ServletRequest req,ServletResponse res) throws ServletException,IOException普通Servlet服务,一般不会直接覆写此方法,而是使用doGet()或doPost()方法4public void destroy()普通Servlet销毁时调用27
  • 28. 生命周期 —— LifeCycleServlet.java package edu.imut.life; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LifeCycleServlet extends HttpServlet { // 继承HttpServlet public void init() throws ServletException { // 初始化操作 System.out.println("** 1、Servlet初始化 --> init()"); } public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, java.io.IOException { // 处理服务 System.out.println("** 2、Servlet服务 --> doGet()、doPost()"); } public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, java.io.IOException { // 处理服务 this.doGet(req, resp); // 调用doGet() } public void destroy() { // Servlet销毁 System.out.println("** 3、Servlet销毁 --> destroy()"); } }28
  • 29. 在web.xml中配置Servlet life edu.imut.life.LifeCycleServlet life /LifeServlet 29
  • 30. Servlet获得初始化参数 通过Servlet配置对象—ServletConfig实现 在Servlet初始化时,容器将调用init(ServletConfig)方法,并为其传递一个ServletConfig对象,该对象称为配置对象。 配置对象ServletConfig的作用 获取servlet初始化参数 获取servlet名称 获取ServletContext对象 2.3 Servlet编程30
  • 31. Servlet获得初始化参数 配置对象的获取 直接使用getServletConfig()获得 ServletConfig config=this.getServletConfig(); 重写init方法,并传递ServletConfig参数 public void init (ServletConfig config) { this.config = config; } Web容器为每一个servlet实例创建一个ServletConfig对象,不同的Servlet之间无法共享使用此对象。2.3 Servlet编程31
  • 32. Servlet获得初始化参数 配置初始化参数 在Servlet的配置文件web.xml中,可以使用一个或者多个标签为当前servlet配置一些初始化参数。 web容器创建servlet对象时,自动将初始化参数封装到ServletConfig对象中,在调用servlet的init方法时,将ServletConfig对象传递给servlet。通过ServletConfig对象就可得到当前servlet初始化参数信息。2.3 Servlet编程32
  • 33. Servlet处理表单 在HTML的表单标记
    的action属性中设置表单提交的目标,提交的目标可以是某一个Servlet action属性值设置为一个Servlet的url-pattern,这里的url-pattern是配置文件web.xml中指定值中去除“/”的部分。 的method属性中设置提交方式,如GET或POST,提交后将去执行Servlet中对应的doGet或者doPost方法。表单提交的信息包括HTML中和标记之间的所有输入控件和选择控件。2.3 Servlet编程33
  • 34. Servlet处理表单 取得请求中包含的提交参数的数据 String getParameter(String name) 取得指定名称的参数,name是form表单元素的name属性值,如:2.3 Servlet编程产品名称: 取得如上文本框中输入值参数的代码为: String productName=request.getParameter(“pName”);34
  • 35. Servlet处理表单 取得请求中包含的提交参数的数据 String[] getParameterValues(String name) 取得指定参数名称的数据数组,用于多值参数的情况。如复选框和复选列表等。如下代码取得复选框的选择数据,如:2.3 Servlet编程爱好:旅游 读书 体育 取得如上参数的代码为: String[] behaves=request.getParameterValues(“behave”); for(int i=0;i
  • 36. 实例:取得用户登录的信息 编写login.html,提供登录所需的表单信息 编写LoginServlet.java,接收请求参数并显示 编写web.xml文件2.3 Servlet编程36
  • 37. 实例:取得用户登录的信息 编写login.html,提供登录所需的表单信息2.3 Servlet编程
    用户名:
    密码:
    37
  • 38. 实例:取得用户登录的信息 编写LoginServlet.java,接收请求参数并显示2.3 Servlet编程public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //处理post请求 //1、接收表单参数 String username=request.getParameter(“username”); //接收请求的参数 String userpass=request.getParameter(“userpass”); //接收请求的参数 PrintWriter out = response.getWriter(); //2、输出接收到的参数 out.println("您的用户名是:"+username); out.println("您的密码是:"+userpass); out.println("欢迎您!"); }38
  • 39. 实例:取得用户登录的信息 编写web.xml文件2.3 Servlet编程 //定义注册Servlet LoginServlet //定义Servlet的名称 com.ch02.LoginServlet //Servlet的包、类名 //映射Servlet LoginServlet //Servlet的名称,与上定义处相同 /servlet/loginServlet //定义Servlet的访问路径 39
  • 40. 实例:取得用户登录信息 解决页面显示乱码问题 问题:通过浏览器调用servlet页面,servlet在浏览器中显示的内容出现乱码 解决:在servlet使用response输出内容之前,增加如下编码语句2.3 Servlet编程response.setContentType("text/html;charset=UTF-8"); //设置中文显示40
  • 41. 实例:取得用户登录信息 解决表单中文参数乱码问题 问题:登录表单输入中文参数,而接收到的参数为乱码,如右图: 解决:在接收post提交的表单参数之前,设定接收参数的内容使用UTF-8编码:2.3 Servlet编程request.setCharacterEncoding("UTF-8");41
  • 42. 取得用户注册信息 新建register.html 新建RegisterServlet.java2.3 Servlet编程42
  • 43. 通过地址栏地址(URL)传递参数 编写URLServlet.java 接收参数(地址栏提供的) 显示参数 配置web.xml文件 输入地址+参数 格式:访问Servlet的地址?参数1=参数值1&参数2=参数值2 例如:http://localhost:8080/ch02/URLServlet?name=zs&no=123 其中,name和no是参数,zs和123是参数值2.3 Servlet编程43
  • 44. 通过超链接传递参数 编写link.html 编写LinkServlet.java 接收参数(超链接提供) 显示参数 配置web.xml文件 输入地址,访问link.html,点击超链接访问LinkServlet2.3 Servlet编程44
  • 45. Servlet中的跳转 重定向:服务器对客户端的请求作出响应,响应结果是让客户端浏览器去重新发出对另一个URL的访问请求 通过HttpServletResponse对象的sendRedirect()方法实现 public void sendRedirect(String location) Location:重定向的新资源的URL地址 绝对地址-如:http://localhost/8080/servlet01/loginServlet 相对地址-如:/工程名(应用名)/资源地址2.3 Servlet编程此处的”/”代表站点根目录45
  • 46. Servlet中的跳转 重定向 客户端跳转 浏览器地址发生改变,为跳转以后的地址 请求的数据不可以带到转发后的页面,属于两个请求对象2.3 Servlet编程46
  • 47. Servlet中的跳转 例:实现登录过程,如果用户名是“admin”密码是”admin123”,则登录成功并显示用户名,否则登录失败,重定向到登录页面,供用户重新登录。 编写login.html 编写LoginServlet.java 接收登录的用户名和密码 判断用户名和密码,如果正确则显示用户名,不正确则重定向到登录页面 配置web.xml2.3 Servlet编程47