servlet
什么是Servlet
1、Servlet程序是一个接口 2、Servlet是JavaWeb三大组件之一。三大组件分别是:Filter过滤器、Servlet程序、Listener监听器。 3、Servlet程序是运行在web服务器上的java小程序(Tomcat)。它可以用来接收客户端的请求,以及响应客户端(浏览器)。
Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。
下图显示了 Servlet 在 Web 应用程序中的位置。
servlet简单理解就是你再前端输入的内容我怎么让后端接受到呢?怎么让后端去根据你前端输入的url去执行对应的后端代码呢?使用servlet就可以实现前后端的对应
Servlet 执行以下主要任务
- 读取客户端(浏览器)发送的显式的数据。这包括网页上的 HTML 表单,或者也可以是来自 applet 或自定义的 HTTP 客户端程序的表单。
- 读取客户端(浏览器)发送的隐式的 HTTP 请求数据。这包括 cookies、媒体类型和浏览器能理解的压缩格式等等。
- 处理数据并生成结果。这个过程可能需要访问数据库,执行 RMI 或 CORBA 调用,调用 Web 服务,或者直接计算得出对应的响应。
- 发送显式的数据(即文档)到客户端(浏览器)。该文档的格式可以是多种多样的,包括文本文件(HTML 或 XML)、二进制文件(GIF 图像)、Excel 等。
- 发送隐式的 HTTP 响应到客户端(浏览器)。这包括告诉浏览器或其他客户端被返回的文档类型(例如 HTML),设置 cookies 和缓存参数,以及其他类似的任务
Servlet的创建
Servlet 创有三种方式。
1、实现 Servlet 接口
因为是实现 Servlet 接口,所以我们需要实现接口里的方法。
下面我们也说明了 Servlet 的执行过程,也就是 Servlet 的生命周期。
//Servlet的生命周期:从Servlet被创建到Servlet被销毁的过程 //一次创建,到处服务 //一个Servlet只会有一个对象,服务所有的请求 /* * 1.实例化(使用构造方法创建对象) * 2.初始化 执行init方法 * 3.服务 执行service方法 * 4.销毁 执行destroy方法 */ public class ServletDemo1 implements Servlet { //public ServletDemo1(){} //生命周期方法:当Servlet第一次被创建对象时执行该方法,该方法在整个生命周期中只执行一次 public void init(ServletConfig arg0) throws ServletException { System.out.println("=======init========="); } //生命周期方法:对客户端响应的方法,该方法会被执行多次,每次请求该servlet都会执行该方法 public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException { System.out.println("hehe"); } //生命周期方法:当Servlet被销毁时执行该方法 public void destroy() { System.out.println("******destroy**********"); } //当停止tomcat时也就销毁的servlet。 public ServletConfig getServletConfig() { return null; } public String getServletInfo() { return null; } }
实现servlet接口的步骤
1、需要编写一个类去实现Servlet接口 2、重点实现service方法 3、需要到web.xml中去配置一个Servlet程序的访问地址。
编写类去实现Servlet接口
package AugustNine; import javax.servlet.*; import java.io.IOException; public class AugustTwentyOne implements Servlet { public AugustTwentyOne(){ System.out.println("1: 执行当前类的构造器进行"); } @Override public void init(ServletConfig servletConfig) throws ServletException { System.out.println("2 :初始化" ); } @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("3: 执行服务 所有的流程操作都是在这里进行执行"); } @Override public String getServletInfo() { return null; } @Override public void destroy() { System.out.println("4: 当前web工程关闭时 执行"); } }
在tomcat生成的web下的web.xml中配置要接受的前端路径和后端分配的类
<servlet> <servlet-name>AugustTwentyOne</servlet-name> <!-- 起一个别名--> <servlet-class>AugustNine.AugustTwentyOne</servlet-class><!-- 对要执行的后端的类 --> </servlet> <servlet-mapping> <servlet-name>AugustTwentyOne</servlet-name><!-- 别名和前端上面的servlet中的那么必须相同 --> <url-pattern>/twentyOne</url-pattern><!-- 前端输入的url请求 --> </servlet-mapping>
web.xml详解中servlet的详解
<!-- servlet标签 表示在web服务器上配置了一个Servlet程序 --> <servlet> <!-- 给配置的Servlet程序起一个唯一的名称 --> <servlet-name>HelloServlet</servlet-name> <!-- servlet-class标签配置全类名 --> <servlet-class>com.atguigu.servlet.HelloServlet</servlet-class> </servlet> <!-- servlet-mapping标签配置一个请求地址 --> <servlet-mapping> <!-- 当前要配置的地址给哪个Servlet程序使用 --> <servlet-name>HelloServlet</servlet-name> <!-- url-pattern 标签,表示配置一个请求地址。<br/> / ==>>> 表示 http://ip:port/工程名/ <br/> /hello ===>>> 表示 http://ip:port/工程名/hello <br/> --> <url-pattern>/hello</url-pattern> </servlet-mapping>
解析url到servlet的详解
浏览器输入的url解析到对应的servlet-mapping中对应的 url-pattern然后再依次流转
Servlet的生命周期
1、调用Servlet程序的构造器方法 2、调用servlet程序的init初始化方法 第一、二步,是在我们第一次访问Servlet程序的时候才会调用。 3、调用Servlet程序的service方法 ===>>>> 每次访问都会调用 4、调用Servlet程序的destroy方法 ====>>>> 在web工程停止的时候调用
模拟GET请求和POST请求的分发
html界面
<form action="http://localhost:8080/day06/hello2" method="get"> <input type="submit" /> </form>
public class HelloServlet implements Servlet { /** * service方法会在每次请求的时候调用<br/> */ @Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { System.out.println("3.Hello Servlet 程序 被访问了!"); // 就需要想办法知道,现在是GET请求,还是POST请求。 // getMethod() 可以得到请求的方式 GET或POST HttpServletRequest httpRequest = (HttpServletRequest) request; String method = httpRequest.getMethod(); System.out.println( "当前请求方式是:" + method ); if ("GET".equals(method)) { // 做GET请求的操作 doGet(); } else if ("POST".equals(method)) { doPost(); } } public void doGet() { System.out.println("这是GET请求的业务功能代码 doGet()方法"); } public void doPost() { System.out.println("这是POST请求的业务功能代码 doPost()方法"); } }
通过继承HttpServlet实现Servlet程序
在实际开发中,我们很少会通过实现Servlet接口去实现Servlet程序。 而是通过继承HttpServlet类去实现Servlet程序。 1、编写一个类去实现HttpServlet抽象类。 2、重写doGet或doPost方法。 3、到web.xml中去配置访问地址。
Servlet类代码
public class HelloServlet2 extends HttpServlet { /** * 在类代码中,需要根据你的具体业务需要。去重写doGet或doPost方法<br/> * doGet方法在GET请求的时候调用<br/> * doPost方法会在Post请求的时候调用。<br/> */ /** * GET请求的时候调用 */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("这是HelloServlet2 doGet方法"); } /** * POST请求的时候调用 */ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("这是HelloServlet2 doPost方法"); } }
web.xml中的配置
<servlet> <servlet-name>HelloServlet2</servlet-name> <servlet-class>com.atguigu.servlet.HelloServlet2</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet2</servlet-name> <!-- /hello2 它的访问地址是:http://ip:port/工程名/hello2 --> <url-pattern>/hello2</url-pattern> </servlet-mapping>
ServletConfig类
ServletConfig类从类名中就可以体系中它本身的作用。就是Servlet程序的配置信息类。
每次Tomcat服务器创建Servlet程序的时候,都会创建一个ServletConfig对象,传递给init初始化方法。
做初始化操作使用。
Servlet程序由Tomcat服务器创建。
ServletConfig类也是由Tomcat服务器创建。
ServletConfig类的三大作用
1、可以获取Servlet-name标签给Servlet配置的别名(名称)
2、获取Servlet程序的初始化参数 <init-param>
3、获取ServletContext对象。
@ override public void init(ServletConfig config) throws ServletException { // a)ServletConfig类的三大作用 // 1、可以获取Servlet-name标签给Servlet配置的别名(名称) System.out.println("Servlet程序的名称:" + config.getServletName()); // 2、获取Servlet程序的初始化参数 <init-param> System.out.println( "url参数的值是:" + config.getInitParameter("url") ); System.out.println( "abc参数的值是:" + config.getInitParameter("abc") ); // 3、获取ServletContext对象。 System.out.println( config.getServletContext() ); }
web.xml的配置
<servlet> <servlet-name>ConfigServlet</servlet-name> <servlet-class>com.atguigu.servlet.ConfigServlet</servlet-class> <!-- init-param 是初始化参数 --> <init-param> <!-- param-name 设置你的参数名 --> <param-name>url</param-name> <!-- param-value 设置参数的值 --> <param-value>jdbc://localhost:3306/test</param-value> </init-param> <!-- init-param 是初始化参数 --> <init-param> <!-- param-name 设置你的参数名 --> <param-name>abc</param-name> <!-- param-value 设置参数的值 --> <param-value>abcValue</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>ConfigServlet</servlet-name> <url-pattern>/configServlet</url-pattern> </servlet-mapping>
Servlet编码常见问题:
如果你重写了init初始化方法,一定要记得在里面调用supper.init( config );,否则在其他地方就不能获取
ServletContext类
什么是ServletContext?
1、ServletContext是一个接口 2、ServletContext是一个域对象 3、一个web工程,Tomcat只会创建出一个ServletContext对象。 域对象是可以像Map集合一样存取对象。 Map 域对象 保存数据 put() setAttribute(); 获取数据 get() getAttribute() 域指的是作用域(就是作用范围)
这里的域对象中的域,是指保存在域对象中的数据的有效操作范围。
ServletContext域对象它的数据操作有效范围是整个Web工程
ServletContext在web工程启动的时候创建。在web工程停止的时候销毁。
ServletContext类的四个作用
1、获取在web.xml中配置的上下文参数 <context-param> 2、获取当前工程的工程路径 3、获取工程发布到服务器上之后,资源或目录在服务器磁盘上的绝对路径。 4、可以像map一样存取数据。
protected void doGet(HttpServletRe quest request, HttpServletResponse response) throws ServletException, IOException { // 获取ServletContext域对象 ServletContext ctx = getServletContext(); // System.out.println(ctx); // 1、获取在web.xml中配置的上下文参数 <context-param> System.out.println("上下文参数url的值是:" + ctx.getInitParameter("url")); System.out.println("上下文参数username的值是:" + ctx.getInitParameter("username")); // 2、获取当前工程的工程路径 System.out.println("当前工程路径:" + ctx.getContextPath()); // 3、获取工程发布到服务器上之后,资源或目录在服务器磁盘上的绝对路径。 /** * / 表示http://ip:port/工程名/ <br/> * 映射到代码的WebContent目录 */ System.out.println( "斜杠:" + ctx.getRealPath("/") ); System.out.println( "WebContent/css目录地址是:" + ctx.getRealPath("/css") ); System.out.println( "WebContent/imgs/2.jpg目录地址是:" + ctx.getRealPath("/imgs/2.jpg") ); }
web.xml中的配置
<!-- 配置上下文参数 --> <context-param> <!-- 参数名 --> <param-name>url</param-name> <!-- 参数值 --> <param-value>jdbc:msyql://localhost:3306/test-context</param-value> </context-param> <context-param> <!-- 参数名 --> <param-name>username</param-name> <!-- 参数值 --> <param-value>root</param-value> </context-param>
上面取出的值是null因为没有放进去值
像Map一样存取数据:
context1
public class Context1 extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext ctx = getServletContext(); System.out.println(ctx); System.out.println(ctx); System.out.println(" Context1 从ServletContext域对象中获取数据abc的值:" + ctx.getAttribute("abc")); // 保存数据到ServletContext域对象 ctx.setAttribute("abc", "abcValue"); System.out.println(" Context1 从ServletContext域中获取数据abc的值:" + ctx.getAttribute("abc")); } }
Context2
public class Context2 extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext ctx = getServletContext(); System.out.println(ctx); System.out.println(ctx); System.out.println(" Context2 从ServletContext域中获取数据abc的值:" + ctx.getAttribute("abc")); } }
.