前面是通过实现 Servlet接口来完成servlet程序的编写,但是开发中一般不这么用
HttpServlet
类关系图
httpServlet 相当于在servelt基础上进行了扩写,提供了一系列的方法。
继承HttpServlet来编写Servlet�
继承HttpServlet 并根据业务重写doGet,doPost方法 ```java package com.addicated.servlet_02;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;
public class servlet02 extends HttpServlet {
/*
* @Author shihu
* @Description //TODO doGet 在get请求的时候调用
* @Date 10:52 下午 2021/9/9
* @Param [req, resp]
* @return void
**/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servlet 02 中的 get请求被调用");
}
/*
* @Author shihu
* @Description //TODO 同理 post请求的时候进行调用
* @Date 10:52 下午 2021/9/9
* @Param [req, resp]
* @return void
**/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servlet 02 中的 post 请求被调用");
}
}
<a name="MQQnJ"></a>
## 为什么有doGet,doPost
- 来看一段代码
```java
public class servlet_01 implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
// 获取servletname
System.out.println(servletConfig.getServletName()); // 用来获取该servlet程序在web.xml 中配置的别名
// 获取web.xml 中对一个servlet程序配置的初始化变量
System.out.println(servletConfig.getInitParameter("url"));
// 获取servletcontext对象
ServletContext servletContext = servletConfig.getServletContext();
}
@Override
public ServletConfig getServletConfig() {
return null;
}
/*
* @Author shihu
* @Description //TODO 专门用来处理请求和响应
* @Date 10:01 下午 2021/9/9
* @Param [servletRequest, servletResponse]
* @return void
**/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
// 当前存在问题,就是所有请求都会走service
// servletRequest 的父类中有getMethod方法 用来得到前端页面传来请求的类型
// 但是其本身并没有getMethod方法,这时候使用多太特性,向下转型,父类转子类
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
// 调用父类中的getMethod方法拿到请求类型和
String method = httpServletRequest.getMethod();
// 之后通过对method判断进行分别调用
if ("GET".equals(method)){
//get 代码
doGet();
}else if ("POST".equals(method)){
// post 代码
doPost();
}
// 但是上面这样写代码 如果请求中的逻辑很多的话,不方便维护。所以封装出来doGet doPost
System.out.println("hello addicated this is a servlet");
}
- 一开始我们进行实现servlet接口的时候,有一个service方法,service方法是用来处理各种请求的,但是在servlet中并没有对服务进行分发,换句话说,也就是不管get 或者是post patch delete请求,都会发到service。
- 然后只能是通过方法名来进行判断进行请求分发,因此httpservlet中,专门为此进行了请求分发的方法支持。见下图
IDEA 创建servlet
- idea对servlet有特化支持
- annotedClass 最好不要勾选,勾选之后会自动添加注解,在web.xml中会看不到servlet程序的相关注册
此方法创建的servlet程序在web.xml中会自动完成注册,但是mapping并不会自动完成,仍然需要手动,
<servlet-mapping> <servlet-name>ContextServlet</servlet-name> <url-pattern>/ContextServlet</url-pattern> </servlet-mapping>
ServletConfig 对象
从类名可得知,这是一个servlet程序的配置信息类
- servlet程序哈servletconfig对象都是tomcat负责创建,我们负责使用
servlet程序默认是第一次访问的时候创建,servletConfig 是每个servlet程序创建时,就创建一个对应的servletConfig对象 ,这句话的隐含意义其实是
一个servletconfig对象,对应的是一个servlet类, - a serveltConfig类的三大作用
1 ,可以获取servlet程序的别名 servlet-name的值
servletConfig.getServletName()
2 ,获取初始化参数 init-param
servletCongfig.getInitParam()
3 ,获取 servletcontext 对象 ```java public class servlet_01 implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
// 获取servletname
System.out.println(servletConfig.getServletName()); // 用来获取该servlet程序在web.xml 中配置的别名
// 获取web.xml 中对一个servlet程序配置的初始化变量
System.out.println(servletConfig.getInitParameter("url"));
// 获取servletcontext对象
ServletContext servletContext = servletConfig.getServletContext();
}
<a name="qmyw0"></a>
## 继承HttpServlet类创建的类获取Config对象则更为简便
```java
public ServletConfig getServletConfig() {
return this.config;
}
# 上面这个方法实际上是 GenericServlet 类下方法 ,因httpServlet继承了该类,所以可以直接调用
另外 ,如果在继承httpservlet之后,重写掉了 init方法,则一定要调用父类的init方法,
否则则获取不到servletConfig对象,
原理为
子类重写父类方法会完全代替掉父类的方法,导致没有对serveltConfig进行初始化,引起npe
genericServlet 下的init方法
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
ServletContext对象
- 1 是一个接口,表示servlet上下文对象
2 一个工程 只有一个servletContext对象实例
3 servletContext 对象是一个域对象
4 servletContext 是在 web工程部署启动的时候创建,在web工程停止的时候销毁 什么是域对象?
可以像map一样存储数据的对象<br /> 这里的域 指的是存储数据的操作范围<br /> 存数据 | 取数据 | 删除数据<br />map put | get | remove<br />域对象 setAttribute | getAttribute |removeAttribute
context对象的作用
1 获取web.xml 中配置的上下文参数 context-param
2 获取当前工程路径 格式:/工程路径
3 获取工程部署后在服务器硬盘上的绝对路径
4 像map一样存取数据 ```java protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {ServletConfig servletConfig = getServletConfig(); ServletContext servletContext = servletConfig.getServletContext(); // 1 获取web.xml 中配置的上下文参数 context-param Object username = servletContext.getInitParameter("username"); System.out.println(username); // 2 获取当前工程路径 格式:/工程路径 String contextPath = servletContext.getContextPath(); System.out.println(contextPath); // 3 获取工程部署后在服务器硬盘上的绝对路径 String realPath = servletContext.getRealPath("/"); System.out.println(realPath);
} — web.xml
<context-param>
<param-name>username</param-name>
<param-value>context</param-value>
</context-param>
```