day06_Servlet

1. Servlet简介

1.1 为什么学Servlet

案例:以注册为例,如需实现注册功能

  1. regist.html中的数据,提交到java

    • 【xxx.java文件默认不能直接以url方式访问,所以需要Servlet解决当前问题】
  2. 在java使用jdbc技术,将数据提交到database

1.2 Servlet概述(Server Applet)

  • Servlet:相当于具有【url特性】的java代码
  • 如果把Web应用比作一个餐厅,Servlet就是餐厅中的服务员——负责接待顾客、上菜、结账。
  • Servlet指的是javax.servlet.Servlet接口及其子接口,也可以指实现了Servlet接口的实现类。

1.3 Servlet特性

  • Servlet的实例对象由Servlet容器负责创建;
  • Servlet的方法由容器在特定情况下调用;
  • Servlet容器会在Web应用卸载时销毁Servlet对象的实例。

web.xml:web应用部署描述符,主要用于各种web组件的注册。

1.4 创建Servlet步骤

  1. 搭建web工程环境

  2. 创建class MyFirstServlet实现javax.servlet.Servlet接口

  3. service():处理请求,做出响应

  4. 在web.xml中,注册MyFirstServlet

    1. <servlet>
    2. <servlet-name>MyFirstServlet</servlet-name>
    3. <!--标识类全类名,目的让服务器创建当前Servlet-->
    4. <servlet-class>com.atguigu.servlet.MyFirstServlet</servlet-class>
    5. </servlet>
    6. <servlet-mapping>
    7. <servlet-name>MyFirstServlet</servlet-name>
    8. <!--为servlet设置虚拟URL-->
    9. <url-pattern>/MyFirstServlet</url-pattern>
    10. </servlet-mapping>

2. Servlet工作原理

  • 请求MyFirstServlet
  • 在web.xml中【中】查找指定url
  • 通过映射到【全类名】
  • 执行MyFirstServlet中的相应方法

3. Servlet生命周期【面试题】

  • 构造器

    • 执行时机:第一次接收请求时,执行。
    • 执行次数:在整个生命周期中,只执行一次。【Servlet单例】
  • init()

    • 执行时机:第一次接收请求时,执行构造器之后,执行。
    • 执行次数:在整个生命周期中,只执行一次。
  • service()

    • 执行时机:每次接收请求,都会执行。
    • 执行次数:在整个生命周期中,只执行多次。
  • destroy()

    • 执行时机:在关闭服务器或重启服务器时,执行。
    • 执行次数:在整个生命周期中,只执行一次。

当Servlet第一次接收请求时,Servlet容器【web容器|web服务器】创建Servlet【执行构造器】,之后执行init()方法,进行初始化操作。最后执行service()方法,处理请求,做出响应。【以后再次接收请求,只执行service()方法】。当关闭或重启服务器时,执行destroy()方法,销毁Servlet。

  • Servlet生命周期_扩展

    • 如在web.xml中做如下配置 ```xml <!—设置Servlet创建时机:启动服务器时创建Servlet index:设置Servlet被创建优先级【int类型且正整数,最小值1】
      1. 数值越小,优先级越高

—>

1

  1. -
  2. 此时,Servlet生命周期,如下调整
  3. - 构造执行时机为:启动服务后,执行
  4. - init()执行时机为:启动服务器,执行构造器后,执行。
  5. - 其他方法,无变化。
  6. <a name="8db05e23"></a>
  7. ### 4. ServletConfig与ServletContext对象
  8. <a name="0cdd34bf"></a>
  9. #### 4.1 ServletConfig
  10. -
  11. 概述:该对象相当于封装了Servlet配置信息,每个Servlet都有唯一对应的ServletConfig对象
  12. -
  13. 作用:
  14. -
  15. 获取当前Servlet名称:servletConfig.getServletName()
  16. -
  17. 获取ServletContext对象:servletConfig.getServletContext()
  18. -
  19. 获取当前Servlet初始化参数:servletConfig.getInitParameter()
  20. -
  21. web.xml中配置初始化参数

url jdbc:mysql://localhost:3306/dbname

  1. <a name="cba74a6c"></a>
  2. #### 4.2 ServletContext对象【Servlet上下文对象】
  3. -
  4. 概述:该对象代表当前web应用,每个web应用程序都有唯一对象的ServletContext对象。【该对象在启动服务时,被web服务器创建。】
  5. -
  6. 作用:
  7. 1.
  8. 获取上下文路径【带/项目名,eg:/day05_tomcat_http_servlet】
  9. ```java
  10. String contextPath = servletContext.getContextPath();
  1. 获取真实路径【d:/xxx(文件上传&文件下载)】
    1. String realPath = servletContext.getRealPath("/index.html");
  1. 获取上下文初始化参数
    1. <context-param>
    2. <param-name>stuName</param-name>
    3. <param-value>caixukun</param-value>
    4. </context-param>
  1. String stuName = servletContext.getInitParameter("stuName");
  1. 域对象【web域,共4个域对象】

5. 最终创建Servlet方式

之前创建Servlet方式不足

  1. 实现Servlet接口的实现类中,方法比较冗余【只需要service()】
  2. 没有提示注册Servlet
  • EndServlet : HttpServlet : GenericServlet : Servlet

  • GenericServlet作用

    1. 提供获取ServletConfig和ServletContext对象方法

      • getServletConfig()
      • getServletContext()
    2. 将service()方法,抽象化
      1. @Override
      2. public abstract void service(ServletRequest req, ServletResponse res)
      3. throws ServletException, IOException;
  • HttpServlet作用

    1. override service()【重写service()】

      1. @Override
      2. public void service(ServletRequest req, ServletResponse res)
      3. throws ServletException, IOException {
      4. HttpServletRequest request;
      5. HttpServletResponse response;
      6. try {
      7. request = (HttpServletRequest) req;
      8. response = (HttpServletResponse) res;
      9. } catch (ClassCastException e) {
      10. throw new ServletException("non-HTTP request or response");
      11. }
      12. service(request, response);
      13. }
  1. overload service()【重载service()】 ```java protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    String method = req.getMethod(); if(“GET”.eq(method)){ doGet(req,resp); }else if(“POST”.eq(method)){ doPost(req,resp); }else if(){ //PUT | DELETE

    }…

}

  1. <a name="4aad3b2c"></a>
  2. ### 6. request【请求】与response【响应】对象
  3. <a name="7d7eebed"></a>
  4. #### 6.1 request
  5. -
  6. 类型:HttpServletRequest
  7. -
  8. 概述:request相当于浏览器向服务器发送请求报文,封装到request对象。该对象由服务器创建,并以参数的形式发送到service()方法中,最终传入doGet()或doPost()方法中。
  9. -
  10. 作用:
  11. 1.
  12. 获取请求参数
  13. > 什么参数
  14. > 1.
  15. ?后面内容:<a href="EndServlet?uname=zs&pwd=123456"></a>
  16. > 2.
  17. 表单中参数:name属性值

用户名:
密码:

  1. - request.getParameter():获取单个请求参数
  2. - request.getParameterValues():获取多个请求参数
  3. 2.
  4. 获取请求头中的信息
  5. - request.getHeader("User-Agent|Cookie|Referer")
  6. 3.
  7. 获取URL信息【[http://localhost:8080/day06_servlet/](http://localhost:8080/day06_servlet/)】
  8. - 获取协议:request.getScheme()
  9. - 获取服务器名称:request.getServerName()
  10. - 获取服务器端口:request.getServerPort()
  11. - 获取上下文路径【带/项目名】:request.getContextPath()
  12. 4.
  13. 转发请求【路径跳转】
  14. ```java
  15. //1. 获取转发器
  16. RequestDispatcher requestDispatcher = request.getRequestDispatcher("login_success.html");
  17. //2. 执行转发
  18. requestDispatcher.forward(request,response);
  1. 域对象【共四个,ServletContext|request】

6.2 response

  • 类型:HttpServletResponse
  • 概述:response相当于服务器向浏览器做出响应报文,封装到response对象。该对象由服务器创建,并以参数的形式发送到service()方法中,最终传入doGet()或doPost()方法中。
  • 作用:

    1. 获取响应流,响应数据

      • PrintWriter writer = response.getWriter();
      • writer.writer();|writer.print()
    2. 设置响应头

      • response.setHeader(“Content-Type”,”text/html;charset=UTF-8”);
    3. 重定向【路径跳转】

      • response.sendRedirect(“url”);

7. 转发与重定向区别

  • 转发地址栏不变,重定向地址改变。
  • 转发可以携带request对象到目标资源,重定向未携带request对象。
  • 转发浏览器发送一次,重定向浏览器发送两次请求
  • 转发可以访问WEB-INF下资源,重定向不能直接访问WEB-INF下资源

    • WEB-INF属于服务器私有目录【服务器内部可以访问,浏览器不能直接访问】

8. web应用中的乱码问题

默认在请求与响应过程中,都会出现乱码情况

8.1 基本术语

  • 字符集:各种字符的集合,包括汉字,英文,标点符号等等。

    • 常用字符集:UTF-8【支持大量中文】、GB2312【GBK:支持少量中文】
  • 编码:将字符转换为二进制数

  • 解码:将二进制数转换为字符

  • 乱码:一段字符的编码与解码的过程使用了不同字符集时,会出现乱码现象。

8.2 乱码种类【B/S】

  • 请求乱码:浏览器向服务器发送请求时,出现乱码

    • 浏览器编码与服务器解码,不一致
  • 响应乱码:服务器向浏览器做出响应时,出现乱码

    • 服务器编码与浏览器解码,不一致

8.3 服务器与浏览器默认编码与解码问题

  • 服务器默认编码与解码一致:ISO-8859-1【不支持中文】
  • 浏览器默认情况

    • 编码:UTF-8【
    • 解码:GBK【GB2312】

8.4 乱码解决

  • 解决请求乱码

    • GET请求

      • 思路:找到设置URL字符集位置

      • 代码

        1. <Connector URIEncoding="UTF-8" port="8080" protocol="HTTP/1.1"
        2. connectionTimeout="20000"
        3. redirectPort="8443" />
  • POST请求

    • 思路:将服务器解码设置为:UTF-8。【浏览器编码:UTF-8与服务器解码:ISO-8859-1】

    • 代码

      1. request.setCharacterEncoding("UTF-8");
  • 解决响应乱码

    • 思路&代码:【服务器编码:ISO-8859-1,浏览器解码:GBK】

      1. 设置服务器编码:GBK【支持少量中文】
        1. response.setCharacterEncoding("GBK"); //设置服务器编码
  1. 2.

设置服务器编码与浏览器解码:UTF-8【推荐使用】

  1. //方式一
  2. response.setHeader("Content-Type","text/html;charset=UTF-8");
  3. //方式二【推荐使用】
  4. response.setContentType("text/html;charset=UTF-8");
  • 总结:三行代码,解决请求与响应的乱码问题

9. web应用中的路径问题

由于使用转发跳转路径,地址栏不变。此时使用相对路径【../】可能会出现404,所以不建议使用相对路径,建议绝对路径。

9.1 什么是绝对路径

  • 以”/“开头的路径,称之为绝对路径

9.2 “/”代表什么

  • 服务器解析“/”,“/”代表当前上下文路径【当前web应用路径】eg:http://localhost:8080/day06_servlet

    • 以下两种路径中的“/” 由服务器解析

      1. web.xml中配置的“/”
        1. <url-pattern>/RegistServlet</url-pattern>
  1. 2.

转发请求中的“/”

  • 浏览器解析”/“,”/“代表当前服务器路径。eg:http://localhost:8080/

    • 以下两种路径中的“/”由浏览器解析

      1. 重定向中的“/”
      2. 书写在静态资源中的“/”【最终在浏览器中加载运行的内容】

        • 如:html\css\js
  • IDEA中编译期间web目录,等同于运行期间上下文路径【/项目名】

9.3 代码

  • 页面中代码【html|jsp】
    1. <base href="/day06_servlet/">
  • Servlet中代码
    1. request.getRequestDispatcher("/pages/login_success.html").forward(request,response);
    2. response.sendRedirect(request.getContextPath()+"/pages/login.html");

10. 基于JavaEE6及以上版本【web3.0】,创建Servlet

  1. @WebServlet(name = "Servlet30",value = "/Servlet30")
  2. public class Servlet30 extends HttpServlet {
  3. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  4. doGet(request,response);
  5. }
  6. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  7. System.out.println("Servlet30!");
  8. }
  9. }