• 第十八章 Servlet


    1.练习

    1.创建web项目

    2.创建一个Servlet类

    3.实现当客户端发请求 http://localhost:8080/test 时,Servlet类像浏览器返回一个Hello wolrd网页内容

    1. @WebServlet(urlPatterns = "/test")
    2. public class Servlet extends HttpServlet {
    3. @Override
    4. protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    5. //设置编码格式避免中文乱码
    6. resp.setContentType("text/html;charset=UTF-8");
    7. PrintWriter out = resp.getWriter();
    8. out.print("

      Hello world

      "
      );
    9. out.flush();
    10. out.close();
    11. }
    12. }

    主要练习的是web项目的创建过程:

    ①添加web框架支持;

    ②导入Tomcat中的jsp-api.jar和servlet-api.jar 包;

    ③配置Tomcat。

    2.Servlet 

    2.1 什么是Servlet

            运行在服务端的小程序,用来处理客户端的请求并给予响应的Java类HttpServlet类。

    2.1.1 servlet体系结构

     2.1.2 Servlet接口

    Servlet的框架是由两个Java包组成的:javax.servlet与javax.servlet.http;

    在javax.servlet包中定义了所有的Servlet类都必须实现或者扩展的通用接口和类;

    在javax.servlet.http包中定义了采用Http协议通信的HttpServlet类;

    Servlet的框架的核心是javax.servlet.Servlet接口,所有的Servlet都必须实现这个接口。

     

     2.1.3 Servlet继承关系

    2.1.4 GenericServlet

    编写Servlet需要通过实现Servlet接口来编写Servlet,但是我们每次都必须为Servlet中的所有方法都提供实现,还需要将ServletConfig对象保存到一个类级别的变量中, GenericServlet抽象类就是为了为我们省略一些模板代码,实现了Servlet和ServletConfig。

    2.2 Servlet访问

            无法通过类名直接访问Servlet ,需要通过映射的路径去访问:url

    2.2.1 web.xml中配置路径映射

    1. <servlet>
    2. <servlet-name>HelloServletservlet-name>
    3. <servlet-class>com.aaa.servlet.HelloServletservlet-class>
    4. <load-on-startup>1load-on-startup>
    5. servlet>
    6. <servlet-mapping>
    7. <servlet-name>HelloServletservlet-name>
    8. servlet-mapping>
    9. <servlet-mapping>
    10. <servlet-name>HelloServletservlet-name>
    11. <url-pattern>/hello2url-pattern>
    12. servlet-mapping>

    oad-on-start标签的作用:

    ①load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方 法);

    ②它的值必须是一个整数,表示servlet应该被载入的顺序;

    ③当值为0或者大于0时,表示容器在启动时就加载并初始化这个servlet;

    ④当值小于0或者没有指定时,则表示容器在该Servlet被请求时,才会去加载;

    ⑤正数的值越小,该Servlet的优先级就越高,应用启动时就优先加载;

    ⑥当值相同的时候,容器就会自己选择优先加载;取值1,2,3,4,5代表的是优先级,而非启动延迟时间。

     2.2.2 添加注释

    @WebServlet(urlPatterns = "/test")
    

    2.3 Servlet生命周期

    2.3.1 Servlet工作原理

            当Web服务器接收到一个HTTP请求时,它会先判断请求内容——如果是静态网页数据,Web服务器将会自行处理,然后产生响应信息;如果牵涉到动态数据,Web服务器会将请求转交给Servlet容器;此时Servlet容器会找到对应的处理该请求的Servlet实例来处理,结果会送回Web服务器,再由Web服务器传回用户端;针对同一个Servlet,Servlet容器会在第一次收到http请求时建立一个Servlet实例,然后启动一个线程(从容器线程池中获取一个);第二次收到http请求时,Servlet容器无须建立相同的Servlet实例,而是启动第二个线程来服务客户端请求;所以多线程方式不但可以提高Web应用程序的执行效率,也可以降低Web服务器的系统负担。

            Servlet是单例的。

    2.3.2 Servlet工作流程

    ①Web Client 向Servlet容器(Tomcat)发出Http请求;

    ②Servlet容器接收Web Client的请求;

    ③Servlet容器创建一个HttpRequest对象,将Web Client请求的信息封装到这个对象中;

    ④Servlet容器创建一个HttpResponse对象;

    ⑤Servlet容器调用HttpServlet对象的service方法,把HttpRequest对象与 HttpResponse对象作为参数传给 HttpServlet对象;

    ⑥HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息;

    ⑦HttpServlet调用HttpResponse对象的有关方法,生成响应数据;

    ⑧Servlet容器把HttpServlet的响应结果传给Web Client。

    2.3.3 Servlet生命周期

            Servlet生命周期,是指Servlet从加载、初始化、处理请求、返回响应、直到销毁的过程。

    Servlet中跟生命周期相关的方法:

    ①init():初始化,在之前先通过构造方法创建对象;②service(ServletRequest,ServletResponse):服务方法,用来处理各种请求的方法; ③destroy():销毁。

     

    ①实例化(创建对象:调用构造方法)(只实例化一次)

    ②初始化(数据的赋初值,或者获取配置信息的过程)(只初始化一次)

    ③提供服务(doGet,doPost)(多次)

    ④销毁(关闭容器时销毁)(一次)

     2.3.4 实例化

    创建Servlet对象:

    ①默认情况下(懒汉模式),在Servlet容器启动后:客户首次向Servlet发出请求, Servlet容器会判断内存中是否存在指定的Servlet对象,如果没有则创建它,然后根据客户的请求创建HttpRequest、HttpResponse对象,从而调用Servlet对象的service方法;

    ②Servlet容器启动时(饿汉模式):当web.xml文件中如果元素中指定了子元素时,Servlet容器在启动web服务器时,将按照顺序创建并初始化Servlet对象;

    ③Servlet的类文件被更新后,重新创建Servlet;Servlet容器在启动时自动创建Servlet,这是由在web.xml文件中为Servlet设置的属性决定的,从中我们也能看到同一个类型的Servlet对象在Servlet容器中以单例的形式存在。

    销毁Servlet对象的时机:

    Servlet容器停止或者重新启动:Servlet容器调用Servlet对象的destroy方法来释放资源。

    1. @WebServlet(urlPatterns = "/TestServlet")
    2. public class TestServlet extends HttpServlet {
    3. private static final transient String GET = "GET";
    4. public TestServlet() {
    5. System.out.println("TestServlet 被创建了!");
    6. }
    7. @Override
    8. public void init() throws ServletException {
    9. System.out.println("TestServlet 被调用-初始化");
    10. System.out.println("TestServlet:"+this.getServletName());
    11. }
    12. @Override
    13. protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    14. if(GET.equals(req.getMethod())){
    15. this.doGet(req,resp);
    16. }else {
    17. this.doPost(req,resp);
    18. }
    19. }
    20. @Override
    21. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    22. System.out.println("处理get请求");
    23. }
    24. @Override
    25. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    26. System.out.println("处理post请求");
    27. }
    28. @Override
    29. public void destroy() {
    30. System.out.println("TestServlet 被销毁");
    31. }
    32. }

    2.3.5 处理请求和响应

    ①对于每一个HTTP请求,servlet容器会创建一个封装了HTTP请求的ServletRequest实例传递给servlet的service方法,ServletResponse则表示一个Servlet响应,其隐藏了将响应发给浏览器的复杂性;

    ②通过ServletRequest的方法你可以获取一些请求相关的参数,而ServletResponse则可以将设置一些返回参数信息,并且设置返回内容。

    HttpServletResquest常用方法:

    getParameter(String);  //根据名字获取参数的值:表单中的参数,地址栏中的参数 getParameterValues(String);;//根据名字获取一组参数的值(复选框)

    getParameterMap();//获得一个Map对象,所有的参数值都放在字符串数组中

    getAttribute(String); //根据名字获取属性的值 setAttribute(String,Object);//根据属性设置值 getRequestDispatcher(String);//请求转发 setCharactorEncoding();  //设置编码方式

    HttpServletResponse常用方法:

    sendRirect();  //重定向:重新请求指定的地址

    setContentType();  //设置响应的编码方式

    addCookie();  //添加cookie

    2.3.6 转发和重定向区别

    服务器转发:

    ①地址栏不会发生改变,在服务器端完成,效率高;

    ②携带数据可以在Servlet,jsp之间进行传递;

    ③客户端发送一次请求,服务器进行一次跳转。

    //请求转发,服务器转发

    request.setAttribute("msg","欢迎你登陆成功"); //request存储数据 request.getRequestDispatcher("/welcomeServlet").forward(request,response);

     客户端重定向:

    ①地址栏会发生改变;

    ②客户端重新发送新的请求,无法用request携带数据;

    ③客户端发起两次请求。

    //客户端重定向

    //服务器会向客户端浏览器发送一个响应:url, 客户端会重新请求该URL request.setAttribute("msg","欢迎你登陆成功"); //request存储数据 response.sendRedirect("/login.html");

     3. 表单验证登录

    login.jsp 文件:

    1. <%--
    2. Created by IntelliJ IDEA.
    3. User: wen
    4. Date: 2022/7/27
    5. Time: 17:10
    6. To change this template use File | Settings | File Templates.
    7. --%>
    8. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    9. <html>
    10. <head>
    11. <title>学生系统title>
    12. <style>
    13. h1{
    14. text-align: center;
    15. }
    16. form{
    17. margin: 0px auto;
    18. width :50%;
    19. height: 100px;
    20. text-align: center;
    21. }
    22. style>
    23. head>
    24. <body>
    25. <h1>登录界面h1>>
    26. <form action="/loginServlet" method="get">
    27. 用户名:<br/>
    28. <input type="text" name="userName" /><br/>
    29. 密码:<br/>
    30. <input type="password" name="password" /><br/>
    31. <input type="submit" value="登录" />
    32. <a href="register.jsp">还没有账号?点击注册a>
    33. form>
    34. body>
    35. html>

    loginServlet:

    1. @WebServlet(urlPatterns = "/loginServlet")
    2. public class LoginServlet extends HttpServlet {
    3. ILoginAndRegisterService loginAndRegisterService = new LoginAndRegisterService();
    4. IStudentDao studentDao = new StudentDaoImpl();
    5. Student student = null;
    6. @Override
    7. protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    8. String userName = req.getParameter("userName");
    9. String password = req.getParameter("password");
    10. System.out.println(userName);
    11. System.out.println(password);
    12. int userId = loginAndRegisterService.userLogin(userName,password);
    13. if(userId>0){
    14. System.out.println("登录成功!");
    15. student = studentDao.selectStu(userId);
    16. req.setAttribute("userName",userName);
    17. req.setAttribute("stuId",student.getStuId());
    18. req.setAttribute("stuName",student.getStuName());
    19. req.setAttribute("sex",student.getSex());
    20. req.setAttribute("birthday",student.getBirthday());
    21. RequestDispatcher rd = req.getRequestDispatcher("/main.jsp");
    22. rd.forward(req,resp);
    23. }else {
    24. System.out.println("登录失败!");
    25. }
    26. }
    27. }

    main.jsp:

    1. <%--
    2. Created by IntelliJ IDEA.
    3. User: wen
    4. Date: 2022/7/27
    5. Time: 17:09
    6. To change this template use File | Settings | File Templates.
    7. --%>
    8. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    9. <html>
    10. <head>
    11. <title>系统主界面title>
    12. <style>
    13. h1{
    14. text-align: center;
    15. color: crimson;
    16. }
    17. a{
    18. text-align: center;
    19. }
    20. form{
    21. margin: 0px auto;
    22. width :50%;
    23. height: 100px;
    24. text-align: center;
    25. }
    26. style>
    27. head>
    28. <body>
    29. <h1>用户<%=request.getAttribute("userName")%>你好!h1>
    30. <form action="/mainServlet" method="get">
    31. 该学生信息<br/>
    32. 学生号(stuId):<input type="text" value="<%=request.getAttribute("stuId")%>" name="stuId" readonly="true"/><br/>
    33. 姓名:<input type="text" value="<%=request.getAttribute("stuName")%>" name = "stuName"/><br/>
    34. 性别:<input type="text" value="<%=request.getAttribute("sex")%>" name = "sex"/><br/>
    35. 生日:<input type="text" value="<%=request.getAttribute("birthday")%>" name = "birthday"/><br/>
    36. <input type ="submit" value="提交" /><a href="index.jsp">退出系统a>
    37. form>
    38. body>
    39. html>

  • 相关阅读:
    渗透测试常用书签
    数据清洗(data clean)
    一步步实现React-Hooks核心原理
    ubuntu 20.04 passwd 指令不能使用
    非互联网客户收入近6成,阿里云进入新周期
    【面试题】ES6语法五之箭头函数
    JavaSE 第六章 面向对象基础-中(封装)
    面试题:Flink反压机制及与Spark Streaming的区别
    K-最近邻算法
    10 个很棒的 Python 3.9 特性
  • 原文地址:https://blog.csdn.net/m0_71674778/article/details/126023703