从有脚本到无脚本

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. (随用随总结)Linux下面的特殊权限&不同的文件类型

    一.Linux的文件信息   linux文件被保存在文件系统下,由以下属性组成: ls -l 之后看到的信息 从左到右可以看到文件的以下属性 各种类型 访问权限 链接数(跟 inode相关,ln 硬链 ...

  2. 【BZOJ】3391: [Usaco2004 Dec]Tree Cutting网络破坏(dfs)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3391 显然判断每个点只需要判断子树是否小于等于n/2即可 那么我们虚拟一个根,然后计算每个子树的si ...

  3. 用MathType编辑异或与非符号有什么方法

    在数学中我们会遇到各种数学符号,有运算符号,希腊符号,还有表示逻辑关系的逻辑符号等,这些大多都是比较常用的符号.其中逻辑符号中我们经常会用到异或与非等,这些符号的编辑我们常常会需要用MathType这 ...

  4. Python实现生命游戏

    1. 生命游戏是什么 生命游戏是英国数学家约翰·何顿·康威在1970年发明的细胞自动机.它包括一个二维矩形世界,这个世界中的每个方格居住着一个活着的或死了的细胞.一个细胞在下一个时刻生死取决于相邻八个 ...

  5. iOS-layoutSubvies和drawRect何时调用

  6. 5秒后跳转到另一个页面的js代码

    今天看视频学习时学习了一种新技术,即平时我们在一个页面点击“提交”或“确认”会自动跳转到一个页面. 在网上搜了一下,关于这个技术处理有多种方法,我只记下我在视频里学到的三种: 1.用一个respons ...

  7. 转载:定位ARM Hard Fault 的方法

    转载自:http://www.openedv.com/posts/list/25030.htm 1.用Keil的话,可以做如下操作: 先将fault中断函数的内容改为: HardFault_Handl ...

  8. Faster R-CNN利用新的网络结构来训练

    前言 最近利用Faster R-CNN训练数据,使用ZF模型,效果无法有效提高.就想尝试对ZF的网络结构进行改造,记录下具体操作. 一.更改网络,训练初始化模型 这里为了方便,我们假设更换的网络名为L ...

  9. linux一台机器文件传到另一台机器上

    登录一台机器35.73: scp -P 端口 要传的文件 user@xxx.xxx.xxx.xxx:/目标文件夹/ 例子 :scp -r -P3561 /home/ismp/build/app/bec ...

  10. 关于ajax里边不能识别$(this)的解决方法

    在ajax外面弄个变量var mythis = $(this),然后在里面用就行