1.1、 什么是Servlet
Servlet是JavaEE规范之一。规范就是接口。
Servlet就JavaWeb三大组件之一。三大组件分别是:Servlet程序、Filter过滤器、Listener监听器。
Servlet是运行在web服务器上的一个java小程序,它可以接收客户端发送过来的请求,并响应数据给客户端。
1.2、 手动实现Servlet程序
第一步:编写一个类去实现Servlet接口。
第二步:实现service方法,处理请求,并响应数据。
第三步:到web.xml中去配置servlet程序的访问地址。
(1) Servlet程序的示例代码:
public class HelloServlet implements Servlet {
/**
* service方法是专门用来处理请求和响应的
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Hello Servlet 被访问了");
}
}
(2) web.xml中的配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- servlet标签给Tomcat配置Servlet程序 -->
<servlet>
<!--servlet-name标签 Servlet程序起一个别名(一般是类名) -->
<servlet-name>HelloServlet</servlet-name>
<!--servlet-class是Servlet程序的全类名-->
<servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
</servlet>
<!--servlet-mapping标签给servlet程序配置访问地址-->
<servlet-mapping>
<!--servlet-name标签的作用是告诉服务器,当前配置的地址给哪个Servlet程序使用-->
<servlet-name>HelloServlet</servlet-name>
<!--url-pattern标签配置访问地址 <br/>
//斜杠在服务器解析的时候,表示地址为:http://ip:port/工程路径
/hello 表示地址为:http://ip:port/工程路径/hello <br/>
-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
常见的错误1:url-pattern中配置的路径没有以斜杠打头
常见错误3:servlet-class标签的全类名配置错误:
1.4、 Servlet的生命周期
Servlet程序的生命周期是指,这个Servlet由创建到销毁过程。
Servlet程序是单例的。
Servlet是由Tomcat服务器第一次访问到Servlet程序的时候创建Servlet。
Servlet中的方法都是由Tomcat服务器负责调用。
数字标签作用
默认情况下,Servlet程序是在我们第一次访问的时候,由Tomcat服务器负责创建.
我们也可以通过在web.xml中去配置
让Tomcat服务器在启动web工程的时候,创建好这个Servlet程序.
如果访问失败请确认以下几点:
第一点: 你的类编写有没有IDEA提示报错,必须是public 类。
第二点: 你在web.xml中配置的地址是多少.确保在web.xml中的配置没有错误.
http://ip:port/工程路径/hello
。
第三点: 确认你在启动web工程的时候 没有任何错误信息。
第四点: 确保你在浏览器地址栏中敲的地址一字不差。
http://127.0.0.1:8080/06_servlet/hello
。
1.5、 GET和POST请求的分发处理
public class HelloServlet implements Servlet {
/**
* service方法是专门用来处理请求和响应的
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("3 service === Hello Servlet 被访问了");
/// 可以通过ServletRequest对象的方法.getMethod()得到请求的方式
// 强转为子类型
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
//调用 getMethod()方法获取请求的方式
String method = httpServletRequest.getMethod();
if ("GET".equals(method)) {
doGet();
} else if ("POST".equals(method)) {
doPost();
}
}
/**
* 用来处理get请求的操作
*/
public void doGet(){
System.out.println("get请求");
System.out.println("get请求");
}
/**
* 用来处理post请求的操作
*/
public void doPost(){
System.out.println("post请求");
System.out.println("post请求");
}
}
1.6、 通过继承HttpServlet实现Servlet程序
一般在实际项目开发中,都是使用继承HttpServlet类的方式去实现Servlet程序。
1)编写一个类去继承 HttpServlet 类。
2)根据业务需要重写doGet或doPost方法。
3)到web.xml中的配置Servlet程序的访问地址
(1)Servlet类的代码:
public class HelloServlet2 extends HttpServlet {
/**
* doGet()在get请求的时候调用
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HelloServlet2 的doGet方法");
}
/**
* doPost()在post请求的时候调用
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HelloServlet2 的doPost方法");
}
}
(2)web.xml中的配置:
<servlet>
<servlet-name>HelloServlet2</servlet-name>
<servlet-class>com.atguigu.servlet.HelloServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet2</servlet-name>
<!-- / 表示地址为: http://ip:port/工程路径/
/hello2 表示:http://ip:port/工程路径/hello2
-->
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
1.7、 使用IDEA创建Servlet程序
1.8、 JavaEE3.0规范:注解配置Servlet程序
web.xml配置Servlet是2.5的规范.现在使用还是很普遍
servlet3.0规范,只需要使用注解即可,不需要配置.web.xml
package com.atguigu.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
@WebServlet 注解表示当前类是一个Servlet程序
value = "/hello4" 表示配置访问地址.
loadOnStartup = 2表示web工程启动就自动创建Servlet实例.
*/
@WebServlet(value = "/hello4")
public class HelloServlet4 extends HttpServlet {
public HelloServlet4() {
System.out.println(" HelloServlet4 构造 器 ");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HelloServlet4 doGet 方法");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HelloServlet4 doPost 方法");
}
}
ServletConfig类从类名上来看,就知道是Servlet程序的配置信息类。
Servlet程序和ServletConfig对象都是由Tomcat负责创建,我们负责使用。
Servlet程序默认是第一次访问的时候创建,ServletConfig是每个Servlet程序创建时,就创建一个对应的ServletConfig对象。
2.1、 ServletConfig类的三大作用
1)可以获取Servlet程序的别名servlet-name的值。
2)获取初始化参数init-param。
3)获取ServletContext对象。
(1) web.xml中的配置:
<!-- servlet标签给Tomcat配置Servlet程序 -->
<servlet>
<!--servlet-name标签 Servlet程序起一个别名(一般是类名) -->
<servlet-name>HelloServlet</servlet-name>
<!--servlet-class是Servlet程序的全类名-->
<servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
<!--init-param是初始化参数-->
<init-param>
<!--是参数名-->
<param-name>username</param-name>
<!--是参数值-->
<param-value>root</param-value>
</init-param>
<!--init-param是初始化参数-->
<init-param>
<!--是参数名-->
<param-name>url</param-name>
<!--是参数值-->
<param-value>jdbc:mysql://localhost:3306/test</param-value>
</init-param>
</servlet>
<!--servlet-mapping标签给servlet程序配置访问地址-->
<servlet-mapping>
<!--servlet-name标签的作用是告诉服务器,我当前配置的地址给哪个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>
(2) Servlet中的代码:
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("2 init初始化方法");
// 1、可以获取Servlet程序的别名servlet-name的值
System.out.println("HelloServlet程序的别名是:" + servletConfig.getServletName());
// 2、获取初始化参数init-param
System.out.println("初始化参数username的值是;" + servletConfig.getInitParameter("username"));
System.out.println("初始化参数url的值是;" + servletConfig.getInitParameter("url"));
// 3、获取ServletContext对象
System.out.println(servletConfig.getServletContext());
}
3.1、 什么是ServletContext?
1)ServletContext是一个接口,它表示Servlet上下文对象
2)一个web工程,只有一个ServletContext对象实例。
3)ServletContext对象是一个域对象。
4)ServletContext是在web工程部署启动的时候创建。在web工程停止的时候销毁。
什么是域对象?
域对象,是可以像Map一样存取数据的对象,叫域对象。
这里的域指的是存取数据的操作范围,整个web工程。
(1)ServletContext演示代码:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1、获取web.xml中配置的上下文参数context-param
ServletContext context = getServletConfig().getServletContext();
String username = context.getInitParameter("username");
System.out.println("context-param参数username的值是:" + username);
System.out.println("context-param参数password的值是:" + context.getInitParameter("password"));
// 2、获取当前的工程路径,格式: /工程路径
System.out.println( "当前工程路径:" + context.getContextPath() );
// 3、获取工程部署后在服务器硬盘上的绝对路径
/**
* / 斜杠被服务器解析地址为:http://ip:port/工程名/ 映射到IDEA代码的web目录
*/
System.out.println("工程部署的路径是:" + context.getRealPath("/"));
System.out.println("工程下css目录的绝对路径是:" + context.getRealPath("/css"));
System.out.println("工程下imgs目录1.jpg的绝对路径是:" + context.getRealPath("/imgs/1.jpg"));
}
(2)web.xml中的配置:
<!--context-param是上下文参数(它属于整个web工程)-->
<context-param>
<param-name>username</param-name>
<param-value>context</param-value>
</context-param>
<!--context-param是上下文参数(它属于整个web工程)-->
<context-param>
<param-name>password</param-name>
<param-value>root</param-value>
</context-param>
(3)ServletContext像Map一样存取数据:
1) ContextServlet1 代码:
public class ContextServlet1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取ServletContext对象
ServletContext context = getServletContext();
System.out.println(context);
System.out.println("保存之前: Context1 获取 key1的值是:"+ context.getAttribute("key1"));
context.setAttribute("key1", "value1");
System.out.println("Context1 中获取域数据key1的值是:"+ context.getAttribute("key1"));
}
}
2) ContextServlet2代码:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = getServletContext();
System.out.println(context);
System.out.println("Context2 中获取域数据key1的值是:"+ context.getAttribute("key1"));
}