Java Web 5.Servlet

五 Servlet

5.1 Servlet介绍

Servlet是运算在服务器上的一个java程序,简单说,它就是一个java类。我们要使用servlet,需要导入servlet的api.

------------------------------

5.2 服务器编译环境设置

1
2
3
result

------------------------------

5.3 Servlet的入门
5.3.1 入门案例

package servlet;

//1,自定义类继承HttpServlet
public class Demo01Servlet extends HttpServlet {

    //2,重写doGet和doPost方法
        //doGet:处理get请求
        //doPost:处理post请求
        //在doGet方法中调用doPost方法,不管是 get请求 or post请求,都交给doGet方法处理
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理get请求
        System.out.println("Demo01Servlet doGet");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理post请求
        doGet(req, resp);
    }
}

web/WEB-INF/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">

    <!--3,配置Servlet-->
    <!--3.1,声明Servlet-->
    <servlet>
        <!--servlet的名称-->
        <servlet-name>Demo01Servlet</servlet-name>
        <!--servlet的全类名-->
        <servlet-class>com.qfedu.servlet.Demo01Servlet</servlet-class>
    </servlet>
    <!--
        3.2,给Servlet设置访问名称
           Servlet should have a mapping
    -->
    <servlet-mapping>
        <!--servlet的名称-->
        <servlet-name>Demo01Servlet</servlet-name>
        <!--servlet的访问名称-->
        <url-pattern>/demo01</url-pattern>
    </servlet-mapping>
</web-app>
5.3.2 执行流程
浏览器发起请求: http://localhost:8080/day50/demo01
​	就会在服务器中找访问名称为demo01的Servlet -> Demo01Servlet
​	请求的处理就交给了Demo01Servlet的实例,根据请求方式get/post,决定是给doGet还是doPost方法处理
5.3.3 注意事项
不管是get请求还是post请求,对于服务器来说,没差别

​get请求将请求参数放到请求网址

​post请求将请求参数放到请求正文

​服务器最终无非就要获取请求参数。getParameter()方法

------------------------------

5.4 Servlet详解

HttpServlet继承于GenericServlet、GenericServlet实现于Servlet,也就是说Servlet是顶层接口

5.4.1 Servlet处理请求
  • Servlet接口下有一个实现类叫GenericServlet,GenericServlet有一个子类HttpServlet.
  • 在Servlet接口中定义了一个方法service,它的主要作用是处理来自浏览器的请求操作。在service方法的重载的方法中,对请求方式进行判断,如果是GET就会调用doGet方法,如果是POST就会调用doPost方法。
5.4.2 创建Servlet的三种方式
  • 方式一:实现Servlet接口
在servlet接口中,没有doGet和doPost方法,处理请求是service方法(抽象的)
  • 方式二:继承GenericServlet类
在GenericServlet类中,没有doGet和doPost方法,处理请求是service方法(抽象的)
  • 方式三:继承HttpServlet类
HttpServlet类中重写service方法。

​根据源码,发现重写service方法中,
	有将ServletRequest强转为HttpServletRequest, 
​	将ServletResponse强转为HttpServletResponse
​	以上强转是因为,ServletRequest和ServletResponse并没有针对Http协议做优化!!!无法专门针对http协议调用方法!!

​	HttpServletRequest和HttpServletResponse有针对http协议做优化!!!

在开发中,一般应用比较多的是使用extends HttpServlet,优点是它是与http协议相关
的,封装了http协议相关的操作。

------------------------------

5.5 Servlet生命周期

在javax.servlet.Servlet接口中定义了三个方法init service destroy它们就是servlet的生命周期
方法

public interface Servlet {
	//监听Servlet的初始化
    void init(ServletConfig var1) throws ServletException;

    ServletConfig getServletConfig();
    
	//处理请求
    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    String getServletInfo();

	//监听Servlet的销毁
    void destroy();
}
  • 调用构造方法创建Sevlet对象(Servlet是单例的,构造方法只执行一次)
  • 调用init方法,进行初始化操作(只执行一次)
  • 当有请求访问Servlet时,会执行service方法(每次请求都执行),在父类HttpServlet中,重写service方法,会把请求分发给doPost()和doGet()方法
  • 当容器关闭时,会执行destroy方法,销毁对象,释放资源

------------------------------

5.6 load-on-startup配置
根据Servlet生命周期,可知,servlet默认不会随着服务器的启动而初始化

load on startup可以让servlet随着服务器的启动而初始化

对于load-on-startup它的可以配置的值有10个,1代表优先级最高,数值越大,优先级越低

------------------------------

5.7 Servlet配置
5.7.1 自定义Servlet

对于servlet,我们需要在web.xml文件中对其进行配置

  • 在web.xml中声明Servlet
<servlet>
        <servlet-name>Demo01Servlet</servlet-name>
        <servlet-class>servlet.Demo01Servlet</servlet-class>
    </servlet>

---------------

  • 在web.xml中给Servlet映射访问路径
<servlet-mapping>
        <servlet-name>Demo01Servlet</servlet-name>
        <url-pattern>/demo01</url-pattern>
    </servlet-mapping>
一个<servlet>可有多个<servlet-mapping>与其对应
5.7.2 < url-parttern >书写规则
  • 完全匹配
要求网址上的访问名称完全和<url-parttern>一致

​必须以"/"开头,否则会报错:IllegalArgumentException : Invalid <url-pattern>

---------------

  • 目录匹配
要求网址上的访问名称中的目录和<url-parttern>一致

​必须以"/"开头,以"*"结尾

​比如:/a/b/* , 目录必须是/a/b,后面随便写

---------------

  • 后缀名匹配
要求网址上的访问名称中的后缀和<url-parttern>一致

​不能以"/"开头,以"*"开头,后缀名根据业务写

​比如:*.xyz。后缀名必须是xyz,其他随意写!!!

------------------------------

5.8 缺省Servlet

创建一个servlet时,如果它的url-pattern的配置值为”/”这时这个servlet就是一个缺省的
servlet,tomcat服务器中默认就有缺省Servlet

  • 缺省Servlet的作用
凡是在web.xml文件总找不到匹配的<servlet-mapping>元素的URL,它们的请求都将交给
缺省Servlet处理。也就是说,缺省的servlet用于处理其他Servlet处理不了的请求

当访问tomcat服务中的静态资源(html、图片等等)时,实际上是在访问这个缺省的servlet
  • 自定义缺省Servlet
在当前工程中自定义Servlet,将url-parttern设置为"/",就覆盖了tomcat容器中的缺省Servlet
  • 应用
 SpringMVC框架中,用于放行静态资源

------------------------------

5.9 服务器中路径
  • 带协议的绝对路径
http://localhost:8080/day51/img/girl.jpg
  • 不带协议的绝对路径
/day51/img/girl.jpg
  • 相对路径
当前目录:./ ,可以省略

上一级目录:../

------------------------------

5.10 ServletConfig对象

ServletConfig是javax.servlet.包下的一个接口。ServletConfig它是Servlet的一个配置对象

ServletConfig对象是由服务器创建的,它是通过Servlet的init方法传递到Servlet中

  • 作用
获取Servlet名称 getServletName

获取Servlet初始化参数 getInitParameter getInitParameterNames

获取ServletContext对象

getInitParameter(String parameterName):根据参数名称获取指定的参数值

getInitParameterNames():获取所有的参数名称

获取域对象:ServletContext
public class Demo11Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletConfig servletConfig = getServletConfig();
        String servletName = servletConfig.getServletName();
        System.out.println(servletName+"正在运行...");
        System.out.println("--------------------");
        String username = servletConfig.getInitParameter("username");
        System.out.println(username);
        String password = servletConfig.getInitParameter("password");
        System.out.println("--------------------");
        Enumeration<String> parameterNames = servletConfig.getInitParameterNames();
        while (parameterNames.hasMoreElements()){
            String parameterName = parameterNames.nextElement();
            String parameterValue = servletConfig.getInitParameter(parameterName);
            System.out.println("name"+parameterName+"password"+parameterValue);
        }

        ServletContext servletContext = getServletContext();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
<servlet>
        <servlet-name>Demo11Servlet</servlet-name>
        <servlet-class>servlet.Demo11Servlet</servlet-class>
        <init-param>
            <param-name>username</param-name>
            <param-value>root</param-value>
        </init-param>
        <init-param>
            <param-name>password</param-name>
            <param-value>root123</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>Demo11Servlet</servlet-name>
        <url-pattern>/demo11</url-pattern>
    </servlet-mapping>

------------------------------

5.11 ServletContext对象

相当于是整个应用程序对象

5.11.1 介绍
  • ServletContext它是javax.servlet包下的一个接口
  • 当服务器启动时,会为服务器中的每一个web应用程序创建一个ServletContext对象,一个ServletContext对象对应的就是一个web应用程序
  • 对于ServletContext,我们叫它上下文对象,ServletConfig对象中维护了ServletContext对象,也就是说,我们可以通过ServletConfig对象来获取ServletContext对象
  • 在web应用中的servlet要想实现资源的共享,可以通过ServletContext来完成,
    ServletContext也叫做域对象
5.11.2 ServletContext对象作用
  • 实现Servlet资源共享

ServletContext是一个域对象,可以用来存储数据.可以将它想像成一个Map<String,Object>,可以通过它实现Servlet资源共享

在应用程序中的任何位置都能够访问
    * getAttribute(String parameterName) : 获取ServletContext域中指定名称的参数值
    * setAttribute(String paramterName,Object parameterValue):存储参数到ServletContext域中
    * removeAttribute(String parameterNam):将ServletContext域中指定名称的参数移除

---------------

  • 获取全局初始化参数

在web.xml中配置的全局初始化参数,可以通过ServletContext对象获取

public class Demo15Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = getServletContext();
        Enumeration<String> parameterNames = servletContext.getInitParameterNames();
        while (parameterNames.hasMoreElements()){
            String parameterName = parameterNames.nextElement();
            String parameterValue = servletContext.getInitParameter(parameterName);
            System.out.println("name:"+parameterName+"value:"+parameterValue);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
<context-param>
        <param-name>username</param-name>
        <param-value>root</param-value>
    </context-param>
    <servlet>
        <servlet-name>Demo15Servlet</servlet-name>
        <servlet-class>servlet.Demo15Servlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>Demo15Servlet</servlet-name>
        <url-pattern>/demo15</url-pattern>
    </servlet-mapping>

---------------

  • 获取资源在服务器上的真实磁盘路径

getRealPath:依据当前项目去生成真实磁盘路径

servletContext.getRealPath("upload"):当前项目的服务器磁盘路径/upload

servletContext.getRealPath("upload/img"):当前项目的服务器磁盘路径/upload/img
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = getServletContext();
        String upload = servletContext.getRealPath("upload");
        System.out.println(upload);
    }

------------------------------

5.12 ServletContext综合案例
  • 需求:统计站点访问次数
public class Demo17Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1 获取ServletContext对象
        ServletContext servletContext = getServletContext();
        //2 判断是否第一次
        Integer count = (Integer) servletContext.getAttribute("count");
        if (count == null) {
            //2.1 第一次访问
            count = 1;
            System.out.println(count);
            servletContext.setAttribute("count", count);
        } else {
            //2.2 非第一次访问
            count++;
            System.out.println(count);
            servletContext.setAttribute("count", count);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

------------------------------

5.13 Servlet3.0

支持注解开发,由注解配置来代替web.xml配置

  • 在Servlet类上直接使用@WebServlet注解
@WebServlet(name = "Demo01Servlet", urlPatterns = {"/demo01", "/mydemo01"},
        initParams = {@WebInitParam(name = "username", value = "root"),
                @WebInitParam(name = "password", value = "123456")})

---------------

  • 常用属性
name:String:设置Servlet名称

urlPatterns:String[]:设置Servlet的访问路径

loadOnStartup:int:设置Servlet的load-on-startup属性

initParams:WebInitParam[]:设置Servlet的初始化参数

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值