Servlet技术

a) 什么是Servlet

1、Servlet 是JavaEE 规范之一。规范就是接口

2、Servlet 就JavaWeb 三大组件之一。三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器。

3、Servlet 是运行在服务器上的一个java 小程序,它可以接收客户端发送过来的请求,并响应数据给客户端。

a) 手动实现Servlet 程序

1、编写一个类去实现Servlet 接口

2、实现service 方法,处理请求,并响应数据

package com.softeem.servlet;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

//创建Servlet类时:
//1.我们定义类时都会以xxxServlet方法命名
//2.需要实现一个接口[Servlet]
public class HelloServlet implements Servlet {

    public HelloServlet(){
        System.out.println("我只会执行一次 我是空参构造方法...");
    }

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("我只会执行一次 init()");
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    //service 方法是专门用来处理请求和响应的
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("每次请求我时,都会执行service() Hello Servlet被访问了");
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        String method = request.getMethod();
        if (method.equals("POST")){
            this.doPost();
        }else{
            this.doGet();
        }
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
        System.out.println("我是web服务器停止时执行destroy()");
    }
    public void doGet(){
        System.out.println("get请求");
    }
    public void doPost(){
        System.out.println("post请求");
    }
}

3、到web.xml 中去配置servlet 程序的访问地址

<?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.softeem.servlet.HelloServlet</servlet-class>
    </servlet>
<!--   servlet-mapping 标签给servlet 程序配置访问地址 -->
    <servlet-mapping>
<!--        告诉服务器,我当前配置的地址是给哪个Servlet程序使用-->
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/HelloServlet</url-pattern>
    </servlet-mapping>
</web-app>

Servlet 的生命周期

1、执行Servlet 构造器方法

2、执行init 初始化方法

第一、二步,是在第一次访问,的时候创建Servlet 程序会调用。

3、执行service 方法

第三步,每次访问都会调用。

4、执行destroy 销毁方法

第四步,在web 工程停止的时候调用。

GET 和POST 请求的分发处理

获取请求的方式:

  1. HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
  2. // 获取请求的方式
  3. String method = httpServletRequest.getMethod();

新建一个html文件在web文件夹下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <base href="http://localhost:8080/javaWeb01">
</head>
<body>
<h1>我是一个测试网页</h1>
<form action="HelloServlet" method="post">
    <input type="submit" value="提交">
</form>
</body>
</html>

一个表单提交网页,点击按钮会跳到HelloServlet类中的doPost方法"post"
 

通过继承HttpServlet 实现Servlet 程序

实现Servlet接口,需要实现里面的所有方法。一般在实际项目开发中,都是使用继承HttpServlet实现Servlet程序。

1、编写一个类去继承HttpServlet 类

HttpServlet 类是一个抽象类,但里面没有抽象方法,主要目的只是为了不让实例化

2、根据业务需要重写doGet 或doPost 方法

3、到web.xml 中的配置Servlet 程序的访问地址(现在使用注解的方法配置Servlet程序的访问地址)

package com.softeem.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(name="HelloServlet2", value = {"/HelloServlet2", "/ss"})
public class HelloServlet2 extends HttpServlet {
    //现在是重写了
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("HelloServlet2.doGet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("HelloServlet2.doPost");
    }
}

编写一个网页

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="HelloServlet2" method="post">
    <input type="submit" value="提交">
</form>
<hr>
<a href="HelloServlet2">跳转到HelloServlet2</a>
</body>
</html>

html中的from表单 提交方式有两种:

1、post

2、get

html中的a链接是使用的get方法提交。

除了form表单能够进行post提交...其他的元素都是采用get提交方式。

如果直接通过地址栏输入Servlet,这样也是get的提交

创建Servlet

Servlet 类的继承体系

Servlet接口,只是负责定义Servlet程序的访问规范。

GenericServlet类实现了Servlet接口。做了很多空实现。并持有一个ServletConfig类的引用。并对ServletConfig的使用做一些方法。

HttpServlet抽取类实现了service()方法,并实现了请求的分发处理。

ServletConfig 类

Servlet 程序默认是第一次访问的时候创建,ServletConfig 是每个Servlet 程序创建时,就创建一个对应的ServletConfig 对象。

service方法处理

service方法就是进行请求分发的,它会就我们的请求分发给doPost方法或者是doGet方法,然后我们去这两个方法中处理业务逻辑,但是这样麻烦,所以选择直接重写service方法...不需要它去请求分发了,我直接让service方法处理请求的业务

init()方法与init(ServletConfig config)方法的区别

重写init方法里面一定要调用父类的init(ServletConfig)操作,该类会调用init(),这样在两个方法同时存在的情况下才都会执行。否则只会执行重写后的init(ServletConfig)

public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }

public void init() throws ServletException {
}

super.init(ServletConfig)一定是super,this.init(ServletConfig)会出现空指针异常。

package com.softeem.servlet;

import javax.servlet.ServletConfig;
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 HelloServlet4 extends HttpServlet {

    @Override
    public void init() throws ServletException {
        System.out.println("------------------init()开始---------------------------------");
        //此方法里面没有ServletConfig参数,但是Servlet接口中的init方法将config赋值给了全局变量config
        ServletConfig config = super.getServletConfig();
        System.out.println("HelloServlet 程序的别名是:" + config.getServletName());
        System.out.println("初始化参数 username 的值是;" + config.getInitParameter("username"));
        System.out.println("初始化参数 url 的值是;" + config.getInitParameter("url"));
        System.out.println(config.getServletContext());
        System.out.println("------------------init()结束---------------------------------");
    }

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("2 init 初始化方法");
        //可以获取Servlet 程序的别名servlet-name的值 也就是配置文件上的名字
        System.out.println("HelloServlet 程序的别名是:" + servletConfig.getServletName());
        //获取初始化参数init-param
        System.out.println("初始化参数 username 的值是;" + servletConfig.getInitParameter("username")); System.out.println("初始化参数 url 的值是;" + servletConfig.getInitParameter("url"));
        //获取ServletContext 对象
        System.out.println(servletConfig.getServletContext());
        super.init(servletConfig);
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("HelloServlet4.service");
    }
}

带参和不带参实际都是一样的,不带参要多加一行代码获取ServletConfig。ServletConfig config = super.getServletConfig();

获取Servlet 程序的别名servlet-name的值:config.getServletName()

获取初始化参数init-param:config.getInitParameter("")

获取ServletContext 对象:config.getServletContext()

//注解配置
@WebServlet(name = "HelloServlet5", value = "/HelloServlet5", initParams = {
    @WebInitParam(name="username",value = "root"),
    @WebInitParam(name="url", value = "jdbc:mysql://localhost:3306/test"),
    @WebInitParam(name = "password", value = "021211")
})

1. ServletContext

a) 什么是ServletContext?

1、ServletContext 是一个接口,它表示Servlet 上下文对象

2、一个web 工程,只有一个ServletContext 对象实例。

3、ServletContext 对象是一个域对象。

4、ServletContext 是在web 工程部署启动的时候创建。在web 工程停止的时候销毁。

什么是域对象?

域对象,是可以像Map 一样存取数据的对象,叫域对象。这里的域指的是存取数据的操作范围,整个web 工程。

a) ServletContext 类的四个作用

1、获取web.xml 中配置的上下文参数context-param

<!--context-param 是上下文参数(它属于整个web 工程)-->
<context-param>
  <param-name>email</param-name>
  <param-value>2023@qq.com</param-value>
</context-param>
<!--context-param 是上下文参数(它属于整个web 工程)-->
<context-param>
  <param-name>phone</param-name>
  <param-value>15172788750</param-value>
</context-param>
@WebServlet("/ContextServlet")
    public class ContextServlet1 extends HttpServlet {
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ServletConfig config = getServletConfig();
            //获取ServletContext对象
            ServletContext context = getServletContext();
            //可以只用一句代码,如下,是GenericServlet类中自己封装了一个getServletContext()方法,内部就是return this.getServletConfig.getServletContext();
            //ServletContext servletContext = this.getServletContext();

            String email = context.getInitParameter("email");
            System.out.println("context-param 参数 email 的值是:" + email);
            String phone = context.getInitParameter("phone");
            System.out.println("context-param 参数 phone 的值是:" + phone);
        }
    }

2、获取当前的工程路径,格式: /工程路径

.getContextPath()

获取工程下css目录的绝对路径是:.getRealPath("/css")

@Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        System.out.println( "当前工程路径:" + servletContext.getContextPath() );
        /**
* / 斜杠被服务器解析地址为:http://ip:port/工程名/ 映射到IDEA 代码的web 目录<br/>
*/
        System.out.println(" 工 程 部 署 的 路 径 是 :" + servletContext.getRealPath("/")); 
        System.out.println("工程下 css 目录的绝对路径是:" + servletContext.getRealPath("/css"));
        System.out.println("工程下 imgs 目录 1.jpg 的绝对路径是:" + servletContext.getRealPath("/imgs/1.jpg"));
    }

3、获取工程部署后在服务器硬盘上的绝对路径

.getRealPath("/")

4、像Map 一样存取数据

@WebServlet("/ContextServlet1")
public class ContextServlet1 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = getServletContext();
        System.out.println(servletContext);
        System.out.println("保存之前:Context1获取username的值是:"+servletContext.getAttribute("username")); //null
        servletContext.setAttribute("username","ss"); //设置username值等于ss
        System.out.println("Context1中获取数据 username 的值是:"+servletContext.getAttribute("username")); //ss

    }
}
@WebServlet("/ContextServlet1")
public class ContextServlet1 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = getServletContext();
        System.out.println(servletContext);
        System.out.println("保存之前:Context1获取username的值是:"+servletContext.getAttribute("username")); //null
        servletContext.setAttribute("username","ss"); //设置username值等于ss
        System.out.println("Context1中获取数据 username 的值是:"+servletContext.getAttribute("username")); //ss

    }
}

当ServletContext对象中保存了username属性ss后在其它的Servlet类中,在去ServletContext对象中的属性username也能获取值ss

ServletContext类它是一个全局作用域,所以说只要在它里面保存了数据,可以在任何地方去获取它保存的数据,除非你主动除掉保存的数据,否则这些数据一直存在

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值