Servlet讲解【Part1】

68 阅读5分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路。

哈喽,大家好!我是Why,一名在读学生,目前刚刚开始进入自己的编程学习生涯。虽然学习起步较晚,但我坚信做了才有0或1的可能。学了一段时间以后也是选择在掘金上分享自己的日常笔记,也希望能够在众多道友的大家庭中打成一片。 本文主要讲解Servlet,如果大家读后觉得有用的话,还请大家多多支持博主:欢迎 ❤️点赞👍、收藏⭐、留言💬 ✨✨✨个人主页:JinHuan

Servlet生命周期

 创建的servlet实例对象有两种被实例化的时候:
     1、在tomcat服务器启动的时候
     2、在该对象被用到的时候

第一个Servlet

 package com.jinhuan.controller;
 ​
 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 Servlet01 extends HttpServlet {
     public Servlet01() {
         System.out.println("第一个Servlet被创建成功了!");
     }
 ​
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 ​
     }
 ​
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         System.out.println("第一个Servlet的doget被调用!");
     }
 }
 ​

第二个Servlet

 public class Servlet02 extends HttpServlet {
     public Servlet02() {
         System.out.println("Servlet02被创建成功!");
     }
 ​
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 ​
     }
 ​
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         System.out.println("Servlet02的doGet方法被调用了!");
     }
 }

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">
     <servlet>
         <servlet-name>Servlet01</servlet-name>
         <servlet-class>com.jinhuan.controller.Servlet01</servlet-class>
     </servlet>
     <servlet>
         <servlet-name>Servlet02</servlet-name>
         <servlet-class>com.jinhuan.controller.Servlet02</servlet-class>
         <!--表示该Servlet实例对象在Tomcat启动的时候创建-->
         <load-on-startup>1</load-on-startup>
     </servlet>
     <servlet-mapping>
         <servlet-name>Servlet01</servlet-name>
         <url-pattern>/one</url-pattern>
     </servlet-mapping>
     <servlet-mapping>
         <servlet-name>Servlet02</servlet-name>
         <url-pattern>/two</url-pattern>
     </servlet-mapping>
 </web-app>

运行结果

HttpServletResponse

 public class Servleto1 extends HttpServlet {
 ​
     /*protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         暂时用不上
     }*/
 ​
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         String test = "jinhuan";
         //--------响应对象将结果写入到响应体--------------start
         //1.通过响应对象,向Tomcat索要输出流
         PrintWriter out = response.getWriter();
         //2.通过输出流,将执行结果以二进制形式写入到响应体
         out.write(test);
         //--------响应对象将结果写入到响应体--------------start
     }//doGet执行完毕
     //Tomcat将响应包推送给浏览器
 }
 ​
 public class ThreeServlet extends HttpServlet {
 /*
 *  问题描述: Java<br/>Mysql<br/>HTML<br/>
 *           浏览器在接收到响应结果时,将<br/>作为
 *           文字内容在窗口展示出来,没有将<br/>
 *           当做HTML标签命令来执行
 *
 *  问题原因:
 *           浏览器在接收到响应包之后,根据【响应头中content-type】
 *           属性的值,来采用对应【编译器】对【响应体中二进制内容】进行
 *           编译处理
 *
 *           在默认的情况下,content-type属性的值“text” content-type="text"
 *           此时浏览器将会采用【文本编译器】对响应体二进制数据进行解析
 *
 *  解决方案:
 *           一定要在得到输出流之前,通过响应对象对响应头中content-type属性进行
 *           一次重新赋值用于指定浏览器采用正确编译器
 */
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 ​
         String result="Java<br/>Mysql<br/>HTML<br/>"; //既有文字信息又有HTML标签命令
         String result2="红烧排骨<br/>梅菜肘子<br/>糖醋里脊";
 ​
         //设置响应头content-type
         response.setContentType("text/html;charset=utf-8");
         //向Tomcat索要输出流
         PrintWriter out = response.getWriter();
         //通过输出流将结果写入到响应体
         out.print(result);
         out.print(result2);
     }
 }

会自动跳转到指定的URl(可携带参数)

 public class FourServlet extends HttpServlet {
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
               String result ="http://www.baidu.com?userName=mike";
               //通过响应对象,将地址赋值给响应头中location属性
               response.sendRedirect(result);//[响应头  location="http://www.baidu.com"]
     }
     /*
     *  浏览器在接收到响应包之后,如果
     *  发现响应头中存在location属性
     *  自动通过地址栏向location指定网站发送请求
     *
     *  sendRedirect方法远程控制浏览器请求行为【请求地址,请求方式,请求参数】
     */
 }

HttpServletResquest

 public class OneServlet extends HttpServlet {
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         //1.通过请求对象,读取【请求行】中【url】信息
          String url = request.getRequestURL().toString();
         //2.通过请求对象,读取【请求行】中【method】信息
          String method = request.getMethod();
         //3.通过请求对象,读取【请求行】中uri信息
         /*
         * URI:资源文件精准定位地址,在请求行并没有URI这个属性。
         *      实际上URL中截取一个字符串,这个字符串格式"/网站名/资源文件名"
         *      URI用于让Http服务器对被访问的资源文件进行定位
         */
         String uri =  request.getRequestURI();// substring
         System.out.println("URL "+url);
         System.out.println("method "+method);
         System.out.println("URI "+uri);
         }
     }
 ​

解决Post乱码情况

 public class ThreeServlet extends HttpServlet {
    /*
    *  问题:
    *      以GET方式发送中文参数内容“尽欢很帅哦”时,得到正常结果
    *      以POST方式发送中文参数内容"尽欢很坏哦",得到【乱码】“è?????????????·???”
    *
    *  原因:
    *
    *      浏览器以GET方式发送请求,请求参数保存在【请求头】,在Http请求协议包到达Http服务器之后,第一件事就是进行解码
    *      请求头二进制内容由Tomcat负责解码,Tomcat9.0默认使用【utf-8】字符集,可以解释一切国家文字
    *
    *      浏览器以POST方式发送请求,请求参数保存在【请求体】,在Http请求协议包到达Http服务器之后,第一件事就是进行解码
    *      请求体二进制内容由当前请求对象(request)负责解码。request默认使用[ISO-8859-1]字符集,一个东欧语系字符集
    *      此时如果请求体参数内容是中文,将无法解码只能得到乱码
    *
    *  解决方案:
    *
    *      在Post请求方式下,在读取请求体内容之前,应该通知请求对象使用utf-8字符集对请求体内容进行一次重新解码
    */
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         //通知请求对象,使用utf-8字符集对请求体二进制内容进行一次重写解码
         request.setCharacterEncoding("utf-8");
         //通过请求对象,读取【请求体】参数信息
         String value = request.getParameter("userName");
         System.out.println("从请求体得到参数值 "+value);
     }
 ​
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          //通过请求对象,读取【请求头】参数信息
          String userName = request.getParameter("userName");
          System.out.println("从请求头得到参数值 "+userName);
     }
 }
 ​

请求和相应对象的生命周期

 1、在HTTP服务器收到浏览器发送的【请求协议包】的时候,自动为当前的【请求协议包】生成一个【请求对象】和一个【响应对象】
 2.在Http服务器调用doGet/doPost方法时,负责将【请求对象】和【响应对象】
           作为实参传递到方法,确保doGet/doPost正确执行
 3.在Http服务器准备推送Http响应协议包之前,负责将本次请求关联的【请求对象】和【响应对象】进行销毁
 ​
 ***【请求对象】和【响应对象】生命周期贯穿一次请求的处理过程中
 *** 【请求对象】和【响应对象】相当于用户在服务端的代言人