ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# Servlet ## Servlet 简介 Java Servlet是和平台无关的服务器端组件,**它运行在Servlet容器中。Servlet容器负责Servlet和客户的通信以及调用Servlet的方法,Servlet和客户的通信采用“请求/响应”的模式**。 Servlet可完成如下功能: 创建并返回基于客户请求的动态HTML页面。 创建可嵌入到现有HTML 页面中的部分HTML 页面(HTML 片段)。 与其它服务器资源(如数据库或基于Java的应用程序)进行通信。 ![](https://box.kancloud.cn/5ff9c18c15e248758a9bf66a76150dd9_999x332.png) Servlet本质上就是一个运行在Servlet容器中的Java类,现在充当Servlet容器的就是我们刚刚安装的Tomcat *** ### 第一个Servlet——HelloWorld 1.创建一个Java类实现Servlet接口,并实现其中所有的方法; ~~~ package com.neusoft.javaweb; import java.io.IOException; import javax.servlet.Servlet; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class HelloServlet implements Servlet{ // 构造器 public HelloServlet() { System.out.println("构造器"); } @Override public void init(ServletConfig arg0) throws ServletException { // TODO Auto-generated method stub System.out.println("init"); } @Override public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException { // TODO Auto-generated method stub System.out.println("service"); } @Override public ServletConfig getServletConfig() { System.out.println("getServletConfig"); return null; } @Override public String getServletInfo() { System.out.println("getServletInfo"); return null; } @Override public void destroy() { // TODO Auto-generated method stub System.out.println("destroy"); } } ~~~ 2.在web.xml配置和映射Servlet; ~~~ <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <!-- 配置和映射Servlet --> <servlet> <servlet-name>helloServlet</servlet-name> <servlet-class>com.neusoft.javaweb.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>helloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app> ~~~ 其中 ~~~ <servlet> <servlet-name>helloServlet</servlet-name> <servlet-class>com.neusoft.javaweb.HelloServlet</servlet-class> </servlet> ~~~ 表示的是为com.neusoft.javaweb.HelloServlet代表的类注册一个名字为helloServlet(类似于为游戏角色创建一个角色名),helloServlet是可以自己随意定制的 ~~~ <servlet-mapping> <servlet-name>helloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> ~~~ 表示的是为helloServlet映射一个访问路径/hello(类似于提供一个能够访问到游戏角色的方式,其中/代表我们web应用的根目录,即[http://localhost:8080/ykbbs/](http://localhost:8080/ykbbs/),也就是WebContent目录)。 3.运行Tomcat,在浏览器中输入[http://localhost:8080/ykbbs/hello](http://localhost:8080/ykbbs/hello),可以发现控制台输出了一些内容,首先是构造器,然后是init,再然后是service,然后每次刷新,每次都只出现了service,然后关闭服务,发现出现destory。 *** ### Servlet的生命周期 ①服务器加载Servlet ②创建Servlet实例 --只有第一次请求Servlet时,创建Servlet实例,调用构造器 ③初始化init() --只被调用一次,在创建好实例后立即被调用,用于初始化当前Servlet ④service()处理用户请求 --可以被多次调用,每次请求都会调用service方法,实际用于响应请求的 ⑤destory()销毁 --只被调用一次,在当前Servlet所在的WEB应用被卸载前调用,用于释放当前Servlet所占用的资源 *** ### load-on-startup 可以指定Servlet被创建的时机 ~~~ <servlet> <servlet-name>helloServlet</servlet-name> <servlet-class>com.neusoft.javaweb.HelloServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> ~~~ 在加载完Servlet后直接就创建了Servlet实例,并进行了初始化,在此期间我们并没有提出请求。 如果配置了多个Servlet, load-on-startup的值越小越先启动(包括0,负数不会被启动,还是需要发出请求才创建实例并初始化); *** ## 注意:服务器不要空跑,保证有WEB应用在运行,否则不会有任何效果。 ### Servlet映射细节 在Servlet映射到的URL中也可以使用 * 通配符,但是只能有两种固定的格式: 一种格式是“* .扩展名” ~~~ <servlet-mapping> <servlet-name>AnyName</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> ~~~ 另一种格式是以正斜杠(/)开头并以“/ * ”结尾。 ~~~ <servlet-mapping> <servlet-name>AnyName</servlet-name> <url-pattern>/action/*</url-pattern> </servlet-mapping> ~~~ #### **注意:既带 / 又带 * 的,又带扩展名的,是不合法的(例如:/*.do)。** *** ### ServletConfig 封装了Servlet配置信息,并可以获取ServletContext对象 它有4个方法: **getInitParameterNames**获取初始化参数的名字(集合) **getInitParameter**(获取初始化参数) **getServletName** **getServletContext** ①配置Servlet的初始化参数 ~~~ <servlet> <servlet-name>helloServlet</servlet-name> <servlet-class>com.neusoft.javaweb.HelloServlet</servlet-class> <init-param> <!-- 参数名 --> <param-name>user</param-name> <!-- 参数值 --> <param-value>root</param-value> </init-param> <init-param> <!-- 参数名 --> <param-name>password</param-name> <!-- 参数值 --> <param-value>1230</param-value> </init-param> <load-on-startup>-1</load-on-startup> </servlet> ~~~ 配置在Servlet当中,且必须在load-on-startup之前 ②获取Servlet的初始化参数 ~~~ public void init(ServletConfig servletConfig) throws ServletException { String user = servletConfig.getInitParameter("user"); System.out.println("user:"+user); Enumeration<String> names = servletConfig.getInitParameterNames(); while(names.hasMoreElements()) { String name = names.nextElement(); String value = servletConfig.getInitParameter(name); System.out.println("^^"+name+":"+value); } System.out.println("init"); } ~~~ ③获取Servlet的配置名称(了解即可,使用较少) ~~~ String servletName = servletConfig.getServletName(); System.out.println(servletName); ~~~ ④**getServletContext**获取Servlet上下文 **(重点)** ~~~ // 代表当前web应用,当前web应用的大管家,可以从中获取当前web应用各个方面的信息 ServletContext servletContext = servletConfig.getServletContext(); ~~~ ServletContext常用的方法: ①获取当前web应用的初始化参数 配置参数: ~~~ <context-param> <param-name>driver</param-name> <param-value>com.mysql.jdbc.Driver</param-value> </context-param> ~~~ 获取参数: ~~~ // 与获取Servlet初始化参数是一样的 String driver = servletContext.getInitParameter("driver"); System.out.println("driver:"+driver); ~~~ #### 那么Servlet的初始化参数与当前web应用的初始化参数有什么区别? 一个是局部的,一个是全局的,全局的初始化参数,在任何的Servlet当中都可以获取,而局部的只有当前Servlet可以获取。 ②获取当前web应用某一个文件在服务器上的绝对路径,而不是部署前的路径(右键属性中的路径) ~~~ ServletContext servletContext = servletConfig.getServletContext(); String realPath = servletContext.getRealPath("index.jsp"); System.out.println(realPath); ~~~ ③获取当前WEB应用的名称**getContextPath()** ~~~ String contextPath = servletContext.getContextPath(); System.out.println(contextPath); ~~~ 这个名称有时候是动态变换的,很常用的方法。 ④获取当前WEB应用的某一个文件对应的输入流 getResourceAsStream(String path):path的 / 为当前web应用的根目录 ~~~ try { ClassLoader classLoader = getClass().getClassLoader(); InputStream is1 = classLoader.getResourceAsStream("jdbc.properties"); System.out.println("1."+is1); } catch (Exception e) { e.printStackTrace(); } try { InputStream is2 = servletContext.getResourceAsStream("/WEB-INF/classes/jdbc.properties"); System.out.println("2."+is2); } catch (Exception e) { e.printStackTrace(); } ~~~ ⑤与attribute属性相关的几个方法(非常重要,后续讲)