06 Servlet

Servlet与jsp是等价的。

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

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

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

Servlet可以连接java代码与前端代码Html之间,架成桥梁传输数据。jsp就是HTML与java代码的整合,既可以写后端代码也可以写前端代码所以并没有实现前后端分离,但是前后端分离的基础。

后面通过规定消息转发,就是json数据传输格式实现前后端分离。

在这里插入图片描述

等价于jsp作用类似。

获取协议信息 修改协议信息

获取标签信息 修改标签信息

遵循HTTP协议,继承HttpServlet类

在这个继承类中写http页面信息。会初始化一些协议信息,并构建http页面内容。

提供将要被子类化以创建适用于 Web 站点的 HTTP servlet 的抽象类。HttpServlet 的子类至少必须重写一个方法,该方法通常是以下这些方法之一:

  • doGet,如果 servlet 支持 HTTP GET 请求
  • doPost,用于 HTTP POST 请求
  • doPut,用于 HTTP PUT 请求
  • doDelete,用于 HTTP DELETE 请求
  • initdestroy,用于管理 servlet 的生命周期内保存的资源
  • getServletInfo,servlet 使用它提供有关其自身的信息
  1. 简述HTTP协议的概念及特点
    1. 支持客户/服务器模式。

    2. 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有 GET、POST。每种方法规定了客户与服务器联系的类型不同。由于 HTTP 协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。

    3. 灵活:HTTP 允许传输任意类型的数据对象。传输的类型由Content-Type加以标记。

    4. 无连接:无连接是表示每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

      ​ HTTP1.1 版本后支持可持续连接。通过这种连接,就有可能在建立一个 TCP 连接后,发送请求并得到回应,然后发送更多的请求并得到更多的回应.通过把建立和释放 TCP 连接的开销分摊到多个请求上,则对于每个请求而言,由于 TCP 而造成的相对开销被大大地降低了。而且,还可以发送流水线请求,也就是说在发送请求 1 之后的回应到来之前就可以发送请求 2.也可以认为,一次连接发送多个请求,由客户机确认是否关闭连接,而服务器会认为这些请求分别来自不同的客户端。

    5. 无状态:HTTP 协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快

  2. 简述实现Servlet的步骤

    创建Servlet

    1. 创建普通 java类
    2. 遵循servlet标准(继承 HttpServlet)
    3. 重写service方法(当前Servlet 类被访问时自动调用service方法)
    4. 设置对外访问的路径 (设置@WebServlet("/路径"))
  3. 简述Servlet的生命周期
    1. init()初始化在被调用的时候创建。
    2. serivce()处理客服的请求方法。
    3. destroy()服务关闭时调用。
  4. 简述Servlet的请求过程

    转载:https://blog.csdn.net/qq_19782019

    在这里插入图片描述

    第一次请求:

    ①.解析请求信息,解析/one/hello;

    上下文路径(环境):/one.

    资源名称:/hello.

    ②.根据上下文路径/one去Tomcat根/conf下找到server.xml文件获取所有的元素再判断哪一个元素的path属性值为/one,接着找到的docBase属性值,该属性值就是当前访问项目的根路径.

    ③.再从当前项目的根路径下的WEB-INF目录中识别web.xml文件.

    ④.获取web.xml文件中所有的url-pattern元素,判断是否存在/hello的属性值(找不到则报404错误).

    ⑤.根据/hello资源名称最终获取对应的Servlet类的全限定名(类的包名.类名).

    ⑥.根据Servlet的全限定名,使用反射调用构造器创建对象Servlet obj = Class.forName(Servlet全限定名).

    (把创建的Servlet对象存储到Servlet缓存池中,供下一次请求使用)

    ⑦.容器创建ServletConfig对象再使用Servlet对象调用init方法进行初始化 obj.init(config).

    ⑧.容器创建ServletRequest,ServletResponse对象再使用Servlet对象调用service方法进行服务obj.service(req, resp).

    ⑨.在service方法中对客户端做响应操作.

    非第一次请求

    前五步与上述前五步相同.

    ⑥.从Tomcat中的Servlet实例缓存池中取出HelloServlet对象

    ⑦.创建HttpRequest,HttpResponse对象调用Service方法进行服务 obj.service(req, resp).

    ⑧.在service方法中对客户端做响应.

    上述流程均有Tomcat容器完成,Servlet,ServletConfig,HttpRequest,HttpResp对象均由容器创建.

    Servlet中方法调用先后顺序:init---->service---->destroy运行时如下图所示:

  5. 简述GET请求和POST请求的区别?
    1. get请求提交的数据会在地址栏显示出来,而post请求不会在地址栏显示。
      get请求,请求的数据会附在url之后(就是把数据放置在http协议头中),以?分割url协议和传输数据,多个参数用&连接
      post请求,把请求的数据放在http包的包体中。
      因此,get请求的数据会在地址栏中显示出来,而post请求地址栏不会改变。

    2. 传输数据的大小
      get请求由于浏览器对地址url长度的限制而导致传输数据有限制
      post请求不会因为地址长度限制而导致传输数据限制

    3. 安全性,post的安全性比get的安全性要高

  6. 如何获取请求的数据?如何响应数据给客户端?

    获取请求数据request:

    HttpServletRequest 对象用于获取客户端发送给服务器的请求数据;
    核心 API:
    获取请求行数据:
    request.getMethod():获取请求方式;
    request.getRequestURI():获取请求资源;
    request.getProtocal():获取请求的 http 协议版本;
    获取请求头数据:
    request.getHeader(“名称”):根据请求头名称获取对应的值;
    request.getHeaderNames():获取所有的请求头名称;
    获取实体内容:
    request.getInputStream():获取实体内容数据;
    获取请求参数:
    request.getParameter(“参数名”):根据参数名获取参数值(注意,只能获取一个参数的值)
    request.getParameterValue(“参数名”):根据参数名获取参数值(可以获取多个值的参数)
    request.getParameterNames():获取所有参数名称列表

    响应数据给客服端response:
    • 设置响应头信息; addHeader(ket,value) setHeader(key,value) set键名(value)
      • response.addHeader(“a”,“A”);response.addHeader(“Content-type”,“text/html;charset=utf-8”);
      • response.setHeader(“Refresh”,“5;URL=www.baidu.com”);5秒后自动跳转到百度主页
    • 发送状态码;
      • response.setStatus(int code);
      • response.sendError(int code , String msg);
    • 设置响应正文;
      • PrintWriter out = response.getWriter();//获取字符流
      • ServletOutputStream out = response.getOutputStream();//获取字节流
    • 重定向;
      • response.setHeader(“Location”, “/day05/index.jsp”);
      • response.sendRedirect("/day05/index.jsp");

    在这里插入图片描述

  7. 如何处理乱码问题(请求与响应)

    编码与解码统一 所以在写入与显示设置编码格式

    请求乱码

    在请求头中有页面显示的编码格式:

    下图是百度搜索,所以他接受的信息是文本与图片text/plain

    在这里插入图片描述
    在这里插入图片描述

    设置请求头中Content-Type的键值为:charset=UTF-8

    request.setHeader(“Content-Type”,“text/html;charset=utf-8”);

    request.setCharacterEncoding(“UTF-8”);

    响应乱码

    response.setCharacterEncoding(“UTF-8”);

    response.setHeader(“content-type”,“text/html;charset=utf-8”);

    写入也需要注意,若idea默认是"UTF-8"则无需修改,否则需要在写入字符串后面填写写入的编码格式。

    ServletOutputStream outputStream = response.getOutputStream();
    outputStream.write("你好".getBytes());
    outputStream.write("<h2>hello<h2>".getBytes("UTF-8"));
    outputStream.flush();
    
  8. request.getAttribute()和request.getParameter()的区别?
    1. getAttribute表示从request范围取得设置的属性,必须要先setAttribute设置属性,才能通过getAttribute来取得,设置与取得的为Object对象类型
    2. getParameter表示接收参数,参数为页面提交的参数,包括:表单提交的参数、URL重写(就是xxx?id=1中的id)传的参数等,因此这个并没有设置参数的方法(没有setParameter),而且接收参数返回的不是Object,而是String类型
  9. 请求转发forward和重定向redirect的区别?

    forward(转发):

    是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,因为这个跳转过程实在服务器实现的,并不是在客户端实现的所以客户端并不知道这个跳转动作,所以它的地址栏还是原来的地址.

    redirect(重定向):

    是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.

    转发是服务器行为,重定向是客户端行为。

    区别:

    1. 从地址栏显示来说
      forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.

    redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.

    1. 从数据共享来说
      forward:转发页面和转发到的页面可以共享request里面的数据.
      redirect:不能共享数据.

    2. 从运用地方来说
      forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
      redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等

    3. 从效率来说
      forward:高.
      redirect:低.

    本质区别:

    重定向,其实是两次request,请求转发是一次request。

    转发是服务器行为,重定向是客户端行为。

Filter过滤器

​ 在服务器一启动就创建,并每个接口都要先经过filter过滤器,判断是否要过滤,从而在执行。过滤器执行的先后顺序是根据过滤器的名字排序的。一层一层判断。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hBWVIUSa-1605619461625)(javaweb.assets/image-20201117210523710.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W1mwFwib-1605619461626)(javaweb.assets/image-20201117210823920.png)]

@WebFilter("/*")
public class Filter01 implements Filter {

    //初始拦截器 项目启动时
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    //拦截后的处理
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //1. 可设置请求与及相应的编码格式
        HttpServletRequest request= (HttpServletRequest) servletRequest;
        HttpServletResponse response= (HttpServletResponse) servletResponse;
        request.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Type", "text/html; charset=UTF-8");

        //2.连接资源文件的请求 或所需拦截的要求 登录以及必须填写某项记录
        if(true){
            //拦截前操作
            System.out.println("拦截前操作");
            //放行
            filterChain.doFilter(request, servletResponse);
            
            //放行后操作
            System.out.println("放行后操作");
        }else {
            System.out.println("拦截");
        }


    }

    //拦截器销毁  项目关闭时
    @Override
    public void destroy() {

    }
}
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐