从有脚本到无脚本

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. Mac OSX使用隐藏文件夹

    直接修改文件夹名字,前面加个"." 小圆点就隐藏了,下去进入可以在finder图标右键点菜单“前往文件夹...",输入你文件夹的路径即可

  2. Sublime Text 加入右键菜单

    Sublime Text 2 是现在很受大家欢迎的编辑器了,不仅是在web前端,在书定简单的php.Js等代码时,也是相当的好用,再配合多种的插件和新颖的界面,更是让人欲罢不能. 在使用时,我们通过喜 ...

  3. (推荐JsonConvert )序列化和反序列化Json

    在Json文本和.Net对象之间转换最快的方法是试用JsonSerializer. JsonSerializer通过将.Net对象属性名称映射到Json属性名称,并为其复制值,将.Net对象转换为其J ...

  4. web.xml配置文件详解

    笔者从大学毕业一直从事网上银行的开发,都是一些web开发项目.接下来会写一些关于web开发相关的东西,也是自己工作以来经常用到的内容.本篇先从web.xml文件开始介绍,笔者接触到的项目中都有这个文件 ...

  5. Delphi TreeView – 自动给标题上加图片

    Delphi TreeView – 自动给标题上加图片 当处理完TreeView控件树形结构的数据后,根据不同的树形节点Level,加上不同的图片. 图片的ImageList已经放置好,并且TreeV ...

  6. [HEOI2015]兔子与樱花[贪心]

    4027: [HEOI2015]兔子与樱花 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1043  Solved: 598[Submit][Stat ...

  7. mysql中给表添加字段

    添加字段: 格式:alter table 表名 add 字段名 字段类型 ; 如:给表stu_info 添加一个字段type,类型为varchar(30) alter table stu_info a ...

  8. plotplayer声道设置原声

    1.打开plotplayer.根据按键F5,选择声音——>语言/同步/其他-流选择 2.重启plotplayer

  9. Visual Assist X助手的一些使用技巧和快捷键

    部分快捷键 Shift+Alt+F // Find References 查找引用 Shift+Alt+S // FindSynbolDialog打开查找符号对话框 Alt+G // GotoImpl ...

  10. 第5章 IDA Pro实验题

    Question: 1.DLLMain的地址是什么? 2.使用import窗口并浏览到gethostbyname,导入函数定位到什么位置 3.有多少函数调用了gethostbyname? 4.将精力放 ...