(二十七)Servlet

Servlet


概述

Servlet是用java编写的服务器端程序 ,能够生成动态web内容 ,即Servlet是运行在Web服务器(如Tomcat),使用java编写的小应用程序

广义Servlet:实现了这个Servlet接口的类 (一般指广义)

狭义:java语言实现的一个接口


作用

渲染的是浏览器 ,通过浏览器客户端去访问Servlet .

接收浏览器请求并响应数据给浏览器


Servlet开发步骤

  1. 创建一个类去实现javax.servlet.Servlet接口
  2. 实现接口中的所有方法
  3. 在service方法处理请求和响应数据
  4. 配置Servlet访问地址 (让浏览器去访问) 通过web.xml配置 或者注解

为什么在service方法中处理请求和相应数据 ? 因为每一次请求都经过service方法

为什么要配置Servlet ?因为我们要找到它才能去访问它

public class ServletDemo implements Servlet {
    public ServletDemo(){
        //对象时单例的
        System.out.println("ServletDemo.create");
    }

    //当Servlet被创建后,紧接着调用init方法来进行初始化
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        //init 只被调用一次 使用场景:可以在该方法进行一些初始化并耗时的操作
        System.out.println("ServletDemo.init");
    }

    //每次请求,都会执行Servlet方法
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        //每次请求都调用service方法 使用场景:处理每次的请求和相应
        System.out.println("ServletDemo.service");
    }

    //当servlet退出服务的时候,服务器正常关闭 ,不正常关闭的时候不会调用该方法
    @Override
    public void destroy() {
        System.out.println("ServletDemo.destroy");

    }
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
    @Override
    public String getServletInfo() {
        return null;
    }
}
  • 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">
    <!--1.servlet 和servlet-mapping 是一对 ,必须同时存在
      2. servlet-name 这个标签体中的内容必须保持一致 ,一般使用Servlet类的名称
      3.servlet-class这个标签体的内容必须使用Servlet这个类的全限定名
      4.url-pattern这个标签体的内容,必须以 / 开头-->
    <servlet>
        <servlet-name>ServletDemo</servlet-name>
        <servlet-class>cn.k.servlet.ServletDemo</servlet-class>     
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletDemo</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>


Servlet的生命周期

类的生命周期: 创建对象 --> 运作–>销毁

了解Servlet的生命周期构成
  • Servlet对象是谁创建的 ,怎么创建的?
1.Servlet对象 是由Tomcat(服务器)创建的 
2.创建Servlet对象,我们并没有去自己new一个对象 ,所以它是通过反射来创建的.
  在web.xml中,我们配置了 类的全限定名 ,所以可以通过字节码来通过反射 创建真实对象        Class.forName("类的全限定名").newInstance(); 需要有公共无参构造
  • Servlet对象是什么时候创建的?
默认情况下,通过浏览器 第一次访问服务器的时候,servlet被创建
  • Servlet对象是什么时候销毁的?
服务器正常关闭或者重启时销毁

Servlet接口中生命周期方法
  • 构造方法 : 对象实例化时执行,必须要有公共无参构造方法
  • void init(ServletConfig servletConfig) :只被调用一次,可以在该方法进行一些初始化并耗时的操作
  • void service(ServletRequest servletRequest, ServletResponse servletResponse) :每次请求都会被执行
  • void destroy():当servlet退出服务的时候,服务器正常关闭 ,不正常关闭的时候不会调用该方法


请求流程

http://localhost:8080/one/hello

访问项目路径 :/one

资源路径: /hello

浏览器发送请求,Tomcat接收到请求,解析请求地址并获取到要访问的项目和资源路径

以web.xml为例

  • 启动Tomcat服务器会先扫描项目 ,解析web.xml文件加载进缓存,获取每一个Servlet的servlet-class访问地址(全限定类名)和url-pattern装进Map集合url-pattern作为key,servlet-class作为value ,从而获取到了一个map集合Map(String,String),

  • 当服务器开始访问类的全限定名时,又会临时加载一个缓存,将servlet-class 作为key和 真实对象 作为value放进另一个map集合中Map(String,Object),

  • 当访问类的全限定名时,会先判断map集合中value(真实对象)是否存在,如果没有存在,则通过反射 class.forName(“全限定类名”).newInstance来创建Servlet真实对象 ,servlet对象被创建后 Tomcat创建servletConfig调用init()来进行初始化 ,再创建servletRequst对象和servletResponse对象,如果本来存在了servlet对象 就不会调用init()了 ,所以Servlet是单例的

  • 调用service方法,将servletRequst对象和servletResponse对象传递进来,通过response对象返回输出到浏览器,在浏览器中显示出来


Servlet的继承体系

继承GenericServlet
@WebServlet(value = "/hello1")
public class ServletDemo02 extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        
    }
}
继承HttpServlet

如果Servlet使用的是Http协议,选择继承HttpServlet类

@WebServlet(value = "/hello1" )
public class HelloServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

继承HttpServlet 必须要重写 protect void service方法 ,不然报错405,不能调用父类super的service方法


ServletConfig对象

作用:用来封装Servlet初始化的时候的一些配置信息

为什么要配置初始化参数:能够解决硬编码的缺点,可以写在web.xml中,后期方便修改与维护

例如  :      
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>

通过 getInitParameter(“参数名”) ,得到value


loadOnStartup属性

让web容器启动的时候创建并初始化Servlet ,loadOnStartup =-1是默认值

@WebServlet(value = "/hello1" ,loadOnStartup = 1)
取值范围110 ,值越小越先加载


通配符

通配符格式说明
/*匹配所有的访问地址,必须一/开头
/目录名/*匹配目录下的所有地址
*.扩展名匹配某个扩展名结尾的访问地址 *.html等


映射细节

servlet-name 不能用default 和jsp

优先级

**/**开头的优先级大于扩展名结尾 ,匹配原则:精准匹配


请求对象

HttpServletRequest

HttpServletRequest接口的实现类称为请求对象,请求对象封装了所有的请求信息(请求行,请求头,请求体)

常用方法

  • String getMethod() :获得请求方式GET和POST

  • String getRequestURI() :统一资源标识符,代表一个资源名字

  • StringBuffer getRequestURL() :统一资源定位符,代表一个可以访问地址

  • String getContextPath() :获得上下文路径(项目名path)

  • String getProtocol() :获得协议和版本

  • String getParameter(String name) :通过参数名得到参数值

注意:

URI ():统一资源标识符 : /request

UPL():统一资源定位符 : http://localhost:8080/request

//@WebServlet("/request")
public class HttpServletRequestDemo extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //必须放在service方法的第一行 处理的是post请求的乱码
        req.setCharacterEncoding("utf-8");


        //获取请求行的信息
        //请求方式
        System.out.println("req.getMethod() = " + req.getMethod());
        //项目的映射路径
        System.out.println("req.getContextPath() = " + req.getContextPath());
        //协议
        System.out.println("req.getProtocol() = " + req.getProtocol());
        //获取请求头的信息 根据名字获取

        System.out.println("req.getDateHeader(\"User-Agent\") = " + req.getDateHeader("User-Agent"));

        //表单里接收的数据,都是以字符串的形式
        //获取请求体中的数据 getParameter()只能获取一个value
        String name = req.getParameter("name");
        //获取多个value 可以使用 getParameterValues()

        //使用getParameterMap()
        Map<String, String[]> parameterMap = req.getParameterMap();
        parameterMap.entrySet().forEach(x->System.out.println(x.getKey()+":"+ Arrays.toString(x.getValue())));


    }
}


请求参数乱码问题

req.setCharacterEncoding(“utf-8”) 代码位置放在第一行


响应对象

​ 什么是响应对象HttpServletResponse对象?
​ 服务器响应数据给浏览器,响应数据中有(响应行,响应头,响应体),HttpServletRespouse对象封装了操作这些数据的方法.

方法

PrintWriter getWriter() :如果服务器端返回的是字符的文本数据,使用这个方法

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值