首页 > Web开发 > 详细

【Head First Servlets and JSP】实践记录01:从有脚本到无脚本

时间:2017-06-19 15:09:25      阅读:490      评论:0      收藏:0      [点我收藏+]

试图章节式的阅读《Head First Servlets and JSP》总感觉不对劲,这本书前后的联系性很强,有点类似于“连续剧”,而不是通常的“知识清单”。

从有脚本到无脚本

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

技术分享

 

【Head First Servlets and JSP】实践记录01:从有脚本到无脚本

原文:http://www.cnblogs.com/xkxf/p/7045532.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!