zoukankan      html  css  js  c++  java
  • 【Head First Servlets and JSP】笔记21:从有脚本到无脚本

    从有脚本到无脚本

    1、快速搭建一个测试环境:输入用户名,返回“Hello, 用户名”

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            body {
                font-family:'comic sans ms',sans-serif;
            }
        </style>
    </head>
    
    <body>
        <form action="checking" method="post">
            <p>Name:</p>
            <p><input type="text" name="name" value="admin"></p>
            <p>Comments: </p>
            <p><textarea name="comments" rows="7" cols="30">Your comments</textarea></p>
            <p><input type="submit"></p>
        </form>
    </body>
    
    </html>

    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_3_1.xsd"
             version="3.1">
    
            <servlet>
                <servlet-name>checking</servlet-name>
                <servlet-class>com.demo.checking</servlet-class>
            </servlet>
    
            <servlet-mapping>
                <servlet-name>checking</servlet-name>
                <url-pattern>/checking</url-pattern>
            </servlet-mapping>
    
    </web-app>

    com.demo.checking

    package com.demo;
    
    import javax.servlet.RequestDispatcher;
    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 checking extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req, resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String name = req.getParameter("name");
            req.setAttribute("name", name);
    
            RequestDispatcher view = req.getRequestDispatcher("/index.jsp");
            view.forward(req, resp);
        }
    }

    index.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
      <head>
        <title>$Title$</title>
        <style>
          body {
            font-family:'comic sans ms',sans-serif;
          }
        </style>
      </head>
      <body>
        <p>Hello, <%=request.getAttribute("name")%></p>
        <%--<p>Hello, <%=request.getParameter("name")%></p>--%>
      </body>
    </html>

    2、把传递“值”改为传递“对象”

    com.demo.Person

    package com.demo;
    
    public class Person implements java.io.Serializable {
        private String name;
    
        public Person() {
    
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }

    com.demo.checking

    package com.demo;
    
    import javax.servlet.*;
    import javax.servlet.http.*;
    import java.io.IOException;
    
    public class checking extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req, resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            Person person = new Person();
            person.setName(req.getParameter("name"));
            req.setAttribute("person", person);
    
            RequestDispatcher view = req.getRequestDispatcher("/index.jsp");
            view.forward(req, resp);
        }
    }

    index.jsp

    <%@ page import="com.demo.Person" %>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
      <head>
        <title>$Title$</title>
        <style>
          body {
            font-family:'comic sans ms',sans-serif;
          }
        </style>
      </head>
      <body>
        <p>Hello, <%=((Person)request.getAttribute("person")).getName()%></p>
      </body>
    </html>

    3、不过,还记得那个备忘录吗?可以用一句话来总结:“使用脚本则死”。所以我们需要另一种方法。

    Person是一个JavaBean,所以我们使用与bean相关的标准动作

    <%@ page import="com.demo.Person" %>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
      <head>
        <title>$Title$</title>
        <style>
          body {
            font-family:'comic sans ms',sans-serif;
          }
        </style>
      </head>
      <body>
        <jsp:useBean id="person" class="com.demo.Person" scope="request" />
        <p>Person created by servlet: <jsp:getProperty name="person" property="name" /></p>
      </body>
    </html>

    <jsp:useBean>与<jsp:getProperty>的关系

    <jsp:useBean>可以用来声明和初始化你在<jsp:getProperty>中使用的具体bean对象。

    <jsp:getProperty>中的“name”值与<jsp:useBean>中的“id”值相对应;<jsp:useBean>中的“id”值与requst中的person属性对应。// req.setAttribute("person", person);

    事实上,上述代码在_jspService()中将会变成这样

          com.demo.Person person = null;
          person = (com.demo.Person) _jspx_page_context.getAttribute("person", javax.servlet.jsp.PageContext.REQUEST_SCOPE);
          if (person == null){
            person = new com.demo.Person();
            _jspx_page_context.setAttribute("person", person, javax.servlet.jsp.PageContext.REQUEST_SCOPE);
          }

     关于PageContext可以参考这里

    4、使用JavaBean标准动作设置对象的成员值。

    <%@ page import="com.demo.Person" %>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
      <head>
        <title>$Title$</title>
        <style>
          body {
    
            font-family:'comic sans ms',sans-serif;
          }
        </style>
      </head>
      <body>
        <%-- id值对应request的实例域中的person --%>
        <jsp:useBean id="person" class="com.demo.Person" scope="request" />
        <jsp:setProperty name="person" property="name" value="fuck_admin" />
        <p>Person created by servlet: <jsp:getProperty name="person" property="name" /></p>
      </body>
    </html>

    5、但是,上述代码有一个问题:覆盖了用户输入的name。而我们只想在查找不到用户输入的时候,自行创建bean并设置实例域的值。

    也就是说,我们希望_jspService()中是这样的:

    对应的JavaBean标准动作就是:

      <body>
        <%-- id值对应request的实例域中的person成员 --%>
        <jsp:useBean id="person" class="com.demo.Person" scope="request">
          <jsp:setProperty name="person" property="name" value="fuck_admin" />
        </jsp:useBean>
        <p>Person created by servlet: <jsp:getProperty name="person" property="name" /></p>
      </body>

    可以建立多态的bean引用吗?——为<jsp:useBean>增加一个type属性

    也就是说,我们希望用一个父类引用持有子类对象。类似于:

            Person p = new Employee();

    首先,我们把Person改为抽象类(这样就无法创建Person类对象了),然后实现一个Employee类:

    package com.demo;
    
    public class Employee extends Person {
        private int empID;
    
        public int getEmpID() {
            return empID;
        }
    
        public void setEmpID(int empID) {
            this.empID = empID;
        }
    }

    接着修改servlet和JSP,如下所示:

        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            Person person = new Employee();
            person.setName(req.getParameter("name"));
            req.setAttribute("person", person);
    
            RequestDispatcher view = req.getRequestDispatcher("/index.jsp");
            view.forward(req, resp);
        }

    <<<<——IDE报错,修改:

      <body>
        <%-- id值对应request的实例域中的person成员 --%>
        <jsp:useBean id="person" type="com.demo.Person" class="com.demo.Employee" scope="request">
          <jsp:setProperty name="person" property="name" value="fuck_admin" />
        </jsp:useBean>
        <p>Person created by servlet: <jsp:getProperty name="person" property="name" /></p>
      </body>

     

    type不仅可以是抽象类,也可以是接口类型、普通类。(共同点是都可以作为实现类or子类的持有者)

     

    使用type,但没有class

    试一下就知道了,修改一下JSP;

      <body>
        <%-- id值对应request的实例域中的person成员 --%>
        <jsp:useBean id="person" type="com.demo.Person" scope="request">
          <jsp:setProperty name="person" property="name" value="fuck_admin" />
          <%-- 通过这个体内语句我们可以判断bean是不是新创建的 --%>
        </jsp:useBean>
        <p>Person created by servlet: <jsp:getProperty name="person" property="name" /></p>
      </body>

    完全修改servlet;

        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            Employee employee = new Employee();
            employee.setName(req.getParameter("name"));
            req.setAttribute("person", employee);
    
            RequestDispatcher view = req.getRequestDispatcher("/index.jsp");
            view.forward(req, resp);
        }

    重新部署,输出结果仍是admin,证明Person引用正确持有了Employee对象因此“使用type,但没有class”是可行的这个时候如果我把

    上面的一句代码注释掉;

            // req.setAttribute("person", employee);

    将无法正常运行(并不会输出fuck_admin),所以,只有type的前提是bean已经在指定作用域存在。

    scope属性默认为page

  • 相关阅读:
    Jquery中的bind()方法绑定事件总结
    composer常用命令
    Activity四种启动模式
    谷歌搜索技巧
    关于Android studio Haxm加速器安装
    关于Ping和Tracert命令原理详解
    皮尔逊相关系数
    head标签
    wireshark抓包
    数据结构与算法自学系列之动态规划(一)
  • 原文地址:https://www.cnblogs.com/xkxf/p/7045532.html
Copyright © 2011-2022 走看看