从有脚本到无脚本

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】笔记21:从有脚本到无脚本的更多相关文章

  1. 【Head First Servlets and JSP】笔记23:Expression Language(EL) 完全攻略

    基本上是<Head First Servlets and JSP>内容的整理.扩充.顺便推荐一个供参考的JSP教程:JSP Tutorial内容很全面,还有一些有趣的实例. 完整代码参考 ...

  2. 【Head First Servlets and JSP】笔记22:直接从请求到JSP & 获取Person的嵌套属性

    直接从请求到JSP,不经过servlet <!DOCTYPE html> <html lang="en"> <head> <meta ch ...

  3. Ext.Net学习笔记21:Ext.Net FormPanel 字段验证(validation)

    Ext.Net学习笔记21:Ext.Net FormPanel 字段验证(validation) 作为表单,字段验证当然是不能少的,今天我们来一起看看Ext.Net FormPanel的字段验证功能. ...

  4. SQL反模式学习笔记21 SQL注入

    目标:编写SQL动态查询,防止SQL注入 通常所说的“SQL动态查询”是指将程序中的变量和基本SQL语句拼接成一个完整的查询语句. 反模式:将未经验证的输入作为代码执行 当向SQL查询的字符串中插入别 ...

  5. JAVA自学笔记21

    JAVA自学笔记21 1.转换流 由于字节流操作中文不是非常方便,因此java提供了转换流 字符流=字节流+编码表 1)编码表 由字符及其对应的数值组成的一张表 图解: 2)String类的编码和解码 ...

  6. SpringMVC内容略多 有用 熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。

    熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器.过滤器等Web组件以及MVC架构 ...

  7. 【Head First Servlets and JSP】笔记 27: web 应用安全

    典型的安全问题:假冒者.窃听者.非法升级者 认证方式: Base64 .摘要认证 .客户端证书.表单认证,重点熟悉摘要算法( HASH . MD5 等) 安全机制:授权.认证.数据完整性.机密性 80 ...

  8. 【Head First Servlets and JSP】笔记 26: web 应用部署

    物理目录结构与虚拟目录结构的差异 WAR 实际上就是 JAR 什么东西应该放在 WEB-INF 文件夹下? <mime-mapping> 相关 <env-entry> 相关 [ ...

  9. 【Head First Servlets and JSP】笔记18:JSP指令

    mark. jetbrain tomcat配置:https://www.jetbrains.com/help/idea/2017.1/creating-and-running-your-first-w ...

随机推荐

  1. c# 可变数目参数params实例

    一般来说,参数个数都是固定的,定义为集群类型的参数可以实现可变数目参数的目的,但是.NET提供了更灵活的机制来实现可变数目参数,这就是使用params修饰符 一般来说,参数个数都是固定的,定义为集群类 ...

  2. Java逍遥游记读书笔记<二>

    Abstract抽象类 1.抽象类不能被实例化 2.抽象方法没有方法体 如: public abstract class Weapen { public abstract void attack(); ...

  3. 如何利用jQuery检查浏览器是否是IE6-8

    $.support.leadingWhitespace是IE特有的属性,用来检查浏览器是否是IE6-8

  4. <pre>标签让<textarea>标签的内容原样输出

    当通过<textarea>插数据进数据的库,取出来后都变成一行变成,用这个<pre>标签能原样输入插入时的格式. 当时要对<pre>加一些CSS样式才行啦. 以下为 ...

  5. ios开源东西

    今天,我们将介绍20个在GitHub上非常受开发者欢迎的iOS开源项目,你准备好了吗? 1. AFNetworking 在众多iOS开源项目中,AFNetworking可以称得上是最受开发者欢迎的库项 ...

  6. 170306、wamp中的Apache开启gzip压缩提高网站的响应速度

    一个网站的响应速度决定该网站的人气和质量,所以wamp配置的服务器也需要支持giz压缩来提高网站的响应速度,如何开启wamp的gzip压缩呢,经过在网站查找资料结合自己服务器中的配置,现在将这个方法分 ...

  7. 巨蟒python全栈开发flask3

    首先,我们新建一个项目: 这个时候,我们调用ab函数,可以在所有的模板中使用. 上边是一个特殊装饰器, 1.flask特殊装饰器 下面说几个特殊的装饰器 再请求之前的装饰器 运行: 这个时候,服务端打 ...

  8. Windows File 管理工具:junction And Subinacl

    junction.exe   是 Sysinternals 出品的命令行工具.使用前建议将其复制到%SystemRoot%/system32目录下 创建一个名为 D:/LINK 的[junction ...

  9. MYSQ无法启动

    http://bbs.51cto.com/thread-433491-1.html http://www.linuxdiyf.com/viewarticle.php?id=97065 http://b ...

  10. mysql 数据库表名大小写问题

    lower_case_table_names=1 原来Linux下的MySQL默认是区分表名大小写的,通过如下设置,可以让MySQL不区分表名大小写:1.用root登录,修改 /usr/my.cnf: ...