JSP基础知识
2018-02-08 15:26
477 查看
一、什么是JSP
二、Eclipse下动态Web项目的结构
三、JSP程序的执行过程
用户首先向服务器发起访问jsp文件的请求,web容器读取jsp文件后,生成对应的java文件(准确的说是Servlet源文件),web容器再将java文件编译成class文件,最后由web容器加载编译后的class文件并执行,把执行结果相应给客户端。
四、JSP基本语法
1、声明语法
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> <!-- 声明成员变量和成员方法 --> <%! String str = "hello world"; String getStr(){ return "hello world2"; } %> <hr> <!-- 输出成员变量 --> <% out.println(this.str); %> <hr> <!-- 调用成员方法 --> <% out.println(this.getStr()); %> </body> </html>
2、程序脚本
需要注意的是程序脚本里面声明的变量为局部变量,而不是成员变量。
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> <% int i = 10; %> <% if(i >10){ out.println("i > 10"); } else{ out.println("i <= 10"); } %> <hr> <!-- 注意这种Java代码段和HTML标签组合的写法,JSP特色,注意程序脚本块中是不允许出现HTML标签的 但是HTML标签中是允许使用程序脚本的 例如<div> <% out.println("Hello World") %> </div> --> <% if(i > 10){ %> <span>i > 10</span> <% }else{ %> <span>i <= 10</span> <%} %> </body> </html>
运行效果如下图
3、JSP注释
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> <%! String str = "hello world";%> <!-- 注释JSP脚本 --> <%-- <% out.println(str); %> --%> <% //out.println("hello,world"); %> </body> </html>
4、JSP内容输出表达式
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> <%! int i = 10; %> i的值是: <!-- jsp输出内容表达式 不用加分号 --> <%= i %> <br> i的值是: <% out.println(i); %> </body> </html>
上题代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>居中</title> <style> div{ text-align: center; } </style> </head> <body> <% int x = -5; int y = 0; %> <% if(x < 0){ y = -1; }else if(x == 0){ y = 0; }else{ y = 1; } %> <div>当x<0时,输出</div> <div>x= <%= x %></div> <div>y= <%= y %></div> </body> </html>
4、JSP包引入语法
下面我们引入Java中的格式化时间和日期相关的类,并将获取的时期显示在页面上
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!-- 包引入 --> <%@ page import = "java.util.*" %> <%@ page import = "java.text.*" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> <%! public String getNow(){ //获取日期格式化类 SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss"); //获取日期 Date currentTime = new Date(); return formatter.format(currentTime); } %> <!-- 调用获取日期的成员方法 --> <%= getNow() %> </body> </html>
运行效果如下:
下面再试着做一道习题:
上题代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!-- 导入ArrayList包 --> <%@ page import = "java.util.ArrayList" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>List</title> </head> <body> <% ArrayList<String> list = new ArrayList<String>(); %> <% list.add("第一条:\t\t JSP基础入门"); list.add("第二条:\t\t Servlet视频详解"); list.add("第三条:\t\t EL表达式初识"); list.add("第四条:\t\t JSTL标签库初识"); %> <div> <% out.print(list.get(0)); %> </div> <br> <div> <% out.print(list.get(1)); %> </div> <br> <div> <% out.print(list.get(2)); %> </div> <br> <div> <% out.print(list.get(3)); %> </div> </body> </html>
五、JSP内置对象
JSP一共有九大内置对象:
输出输入对象:request对象、response对象、out对象
通信控制对象:pageContext对象、session对象、application对象
Servlet对象:page对象、config对象
错误处理对象:exception对象
我们首先来通过一个人事管理系统学习输入输出对象:request、response以及out
1、request、response、out
Request(Javax.servlet.ServletRequest)它包含了有关浏览器请求的信息.通过该对象可以获得请求中的头信息、Cookie和请求参数。
Response(Javax.servlet.ServletResponse)作为JSP页面处理结果返回给用户的响应存储在该对象中。并提供了设置响应内容、响应头以及重定向的方法(如cookies,头信息等)
Out(Javax.servlet.jsp.JspWriter)用于将内容写入JSP页面实例的输出流中,提供了几个方法使你能用于向浏览器回送输出结果。
人事管理系统需要实现这么一个功能,首先打开人事管理系统后需要输入用户名和密码进行登录,之后将登录的信息交由jsp程序判定是否能和数据库中的用户信息匹配,若匹配成功则显示出所有用户信息。
那么我们首先新建一个Java Web项目(IntelliJ idea),首先在src目录下新建如下的包和类,其中DBUtil是模拟数据库的一个类,Emp是用户类。
接着实现Emp用户类
package com.imooc.bean; //员工类 public class Emp { private String account; private String name; private String passord; private String email; public Emp(String account, String name, String passord, String email) { this.account = account; this.name = name; this.passord = passord; this.email = email; } public String getAccount() { return account; } public void setAccount(String account) { this.account = account; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassord() { return passord; } public void setPassord(String passord) { this.passord = passord; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
再实现DBUtil类
package com.imooc.db; import com.imooc.bean.Emp; import java.util.HashMap; import java.util.Map; public class DBUtil { //使用Map集合模拟数据库存储员工信息 public static Map<String,Emp> map = new HashMap<String, Emp>(); //使用静态代码块初始化Map集合,存储用户信息 static { //Map集合初始化 map.put("101", new Emp("101", "AA", "123456", "AA@imooc.com")); map.put("102", new Emp("102", "BB", "123456", "BB@imooc.com")); map.put("103", new Emp("103", "CC", "123456", "CC@imooc.com")); map.put("104", new Emp("104", "DD", "123456", "DD@imooc.com")); } //判断用户名和密码是否正确 public static boolean selectEmpByAccountAndPassoword(Emp emp){ boolean flag = false; for (String key : map.keySet()){ //遍历Map集合判断输入的用户名和密码是否在集合中存在 if (emp.getAccount().equals(map.get(key).getAccount()) && emp.getPassord().equals(map.get(key).getPassord())){ flag = true; } } return flag; } }
在web文件夹下创建JSP文件logon.jsp以及controller.jsp,前者用来显示登录页面,后者用来处理用户输出的登录信息是否正确。
首先是logon.jsp
<%-- 人事管理系统登录页面 --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>人事管理系统</title> <style> h3{ text-align: center; } </style> </head> <body> <h3>人事管理系统登录页面</h3> <hr> <!--action代表服务器端的处理程序--> <!--当我们按下表单的submit按钮后,浏览器会将表单信息封装到request内置对象中,并发送给controller.jsp处理--> <form action="controller.jsp"> <table align="center"> <tr> <td> 账号: </td> <td> <!--服务器端通过name属性来获取到用户在浏览器表单里输入的账户信息--> <input type="text" name="account"/> </td> </tr> <tr> <td> 密码: </td> <td> <input type="password" name="password"/> </td> </tr> <tr> <td> <input type="submit" value="登录"/> </td> </tr> </table> </form> </body> </html>
接着是controller.jsp,这里注意不要忘记导包
<%-- 处理登录请求的jsp --%> <%@ page contentType="text/html;charset=UTF-8" language="java" import="com.imooc.db.*,com.imooc.bean.*,java.util.*" %> <%@ page import="java.util.Map" %> <html> <head> <title>Title</title> <style> table{ border: 1px solid black; width: 500px; } </style> </head> <body> <!-- 获取账号以及密码,调用DBUtil中的方法判断是否存在指定的用户信息 1、如果正确,DBUtil返回true,显示成功页面 2、如果错误,DBUtil返回false,显示失败页面 使用request内置对象获取登录界面传来的表单内的用户信息 request.getParameter(String name):通过表单内的控件的name属性来获取控件的值 out内置对象:输出流对象,可以向页面输出指定的信息 out.println(); --> <% String account = request.getParameter("account"); String password = request.getParameter("password"); //用Emp对象封装输入的用户信息 Emp emp = new Emp(account, null, password, null); // boolean flag = DBUtil.selectEmpByAccountAndPassoword(emp); Map<String,Emp> map = DBUtil.map; if (flag == true){ %> <h3 align="center">欢迎来到人事管理系统首页!</h3> <hr> <table align="center"> <tr> <td> 账号 </td> <td> 姓名 </td> <td> 邮箱 </td> </tr> <% for (String key : map.keySet()){ Emp e = map.get(key); %> <!--循环输出所有用户信息--> <tr> <td> <%= e.getAccount() %> </td> <td> <%= e.getName()%> </td> <td> <%= e.getEmail()%> </td> </tr> <% } %> </table> <% }else { } %> </body> </html>
这时如果我们输入正确的用户密码,点击登录后,页面就会从logon.jsp跳转到controller.jsp并且显示所有的用户信息了!
request作用域
这样说可以还比较抽象,那么借用刚刚的人事管理系统来试验一次。先在logon.jsp中加入以下代码
<!--request.setAttribute(String key, String value)--> <% requset.setAttribute("name", "imooc") %>
接着在controller.jsp中加入
<!--request.getAttribute(String key)--> <h3>name对应的值:<%= request.getAttribute %></h3>
那么按照我们正常的理解,应该是我们在logon.jsp中点击登录,跳转到controller.jsp后,会在页面上显示出imooc这个值,但实际上并未如此,我们在controller.jsp中获取的值为null。
原因是当我们第一次访问logon.jsp,首先会向服务器发起请求request,服务器将logon.jsp响应给我们之后,这时我们刚刚发起的请求request就会在logon.jsp中执行
requset.setAttribute("name", "imooc")
但是当我们点击登录之后,就相当于发送了一个新的request,因此controller.jsp接收到的request并不是在logon.jsp中执行了对应操作的request,因此这个新的request中存放的name对应的值自然为null。
这里注意,表单内容封装到request中发送给controller.jsp和我们上面讲是不一样的,我们点击表单的提交按钮后,logon.jsp会将表单内容封装到一个新的request对象中发送给controller.jsp,而我们上面所说的使用了setAttribute方法的request是从上一级请求生成的request,这两个request并不是一个request对象
如果我们要想让一个jsp页面和logon.jsp共享那个存放了imooc值的request对象的话,我们需要在logon.jsp中调用
request.getRequestDispatcher("result.jsp").forward(request, response);
这段代码的意思是将request对象直接转发给result.jsp,那么我们就能在result.jsp中获取到request对象中存放的imooc值了,但需要注意的是,这时我们直接访问logon.jsp时,虽然地址是logon.jsp,但是显示的内容却直接是result.jsp的内容了
result.jsp的代码如下
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> 从logon.jsp中传来的request对象获取的数据:<%= request.getAttribute("name") %> </body> </html>
效果如下,注意地址和内容
2、pageContext、page
pageContext
首先学习pageContext转发请求的功能
创建一个index.jsp,在jsp页面中调用pageContext的forward方法转发request请求到a.jsp,并且在request请求中以键值对的形式存放参数
//使用pageContext对象转发request请求,并通过key value的形式存放一个值,若有多个值可通过&分割 pageContext.forward("a.jsp?name=imooc");
接着在a.jsp中获取这个request请求及其存放的参数
//注意这里不是使用getAttribute来获取值,而是getParameter //注意这里如果使用<% request.getParameter("name")的话,只会执行不会输出,只有使用<%= %>才会输出到页面上! %> request.getParameter("name")
打开index.jsp,发现请求转发成功,页面上显示的是imooc。
接着学习pageContext包含其他jsp页面的功能,在index页面中使用如下代码(注释掉之前)
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <!-- pageContext对象的作用 1、forward方法来完成request请求的转发 2、include方法完成jsp页面的包含关系 3、获取其他内置对象:getRequest、getSession等 --> <% pageContext.include("header.jsp"); //使用pageContext对象转发request请求,并通过key value的形式存放一个值,若有多个值可通过&分割 //pageContext.forward("a.jsp?name=imooc"); %> </body> </html>
header.jsp的代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> 这是一个Header头部分 </body> </html>
这时我们运行index.jsp,发现header.jsp的内容已经被index.jsp包含进来了!
至于pageContext的获取其他内置对象的方法就比较简单了,就是getSession、getRequest之类。
pageContext的作用域是当前jsp页面
page
page对象代表的是当前正在运行的jsp文件产生的类对象,一般用this可以指代。
比方说我们在logon.jsp中运行下面这段代码,getServletInfo()方法的作用是显示当前Servlet的基本信息
<%= this.getServletInfo() %>
运行效果如下:说明我们用的是JSP2.3的引擎
3、session、config、exception
session
因此session可以用来实现这样一种功能:用户登录后,使用session保存用户数据,这样当用户在浏览其他页面时,因为session的作用域是整个会话期间,因此就可以在其他页面也显示出当前用户的信息,例如用户名、用户性别等。
而使用session进行保存和读取数据的方法也和前面一样:session.setAttribute和session.getAttribute()
此外,还可以修改session的有效时间,Session超时理解为:浏览器和服务器之间创建了一个Session,由于客户端长时间(休眠时间)没有与服务器交互,服务器将此Session销毁,客户端再一次与服务器交互时之前的Session就不存在了。
修改session的有效时间的方法为:
config
config 对象代表当前JSP 配置信息,但JSP 页面通常无须配置,因此也就不存在配置信息。该对象在JSP 页面中非常少用,但在Servlet 则用处相对较大。因为Servlet 需要配置在web.xml 文件中,可以指定配置参数。
exception
exception:异常对象
我们在之前的controller.jsp页面中进行修改,在判断用户名和密码错误的情况下抛出一个异常:
throw new Exception("用户名和密码错误!");
如果我们直接运行,那么当我们输入错误的用户名和密码进入到controller.jsp时,页面会出现500报错。
那么我们现在为controller.jsp页面添加一个错误处理页面error.jsp,因此我们需要在jsp页面的头部分为page声明一个新属性
<!--声明当该页面产生异常exception时交由error.jsp页面进行处理--> <%@ page errorPage="error.jsp" %>
接着我们完成error.jsp,注意错误处理页面也需要为page声明一个属性isErrorPage = “true”,否则无法调用exception对象
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <!--声明当前为错误处理页面,否则无法使用exception内置对象--> <%@ page isErrorPage="true" %> <html> <head> <title>Title</title> </head> <body> <!-- 1、exception对象智能在错误页面中使用,page加入一个属性isErrorPage = "true" 2、如果有一个页面出现了异常,可以在这个页面中指定一个错误处理的页面,page加入一个属性errorPage = "...." --> <!--获取异常信息message--> <%= exception.getMessage() %> </body> </html>
那么我们现在再输入错误的用户名和密码,跳转到controller.jsp的效果就是下面这样的了:
4、application
application代表整个Web应用本身。
因为application的作用域是整个Web容器的生命周期,因此我们可以通过application统计web访问量。
进入controller.jsp,在用户名密码判断正确的逻辑中加入统计访问量的逻辑:
if (flag == true){ //使用session保存登录用户的信息 session.setAttribute("account", account); //统计web应用访问量 Object o = application.getAttribute("count"); if (o == null){ //如果是该web应用是第一次访问,则将访问量置1 application.setAttribute("count", 1); } else { //不是第一次被访问则访问量加一 int count = (int) application.getAttribute("count"); application.setAttribute("count", count + 1); }
上面就实现了用户成功登录后访问量+1的功能。
最后我们来实现这个人事管理系统的修改信息功能,这里我们就不讲每一步的步骤了,单讲需要用到的技术知识点。
1、不同页面之间通过URL传递数据
例如我要从controller.jsp点击修改按钮跳转到update.jsp的同时也将对应用户的信息传递到update.jsp并显示在对应的输入框中:
点击第一栏之后,跳转到update.jsp
那么我们这时就需要使用到URL来在两个页面之间传递数据了,具体实现方式如下:
<a href="update.jsp?account=<%= e.getAccount() %>&name=<%= e.getName() %>&email=<%= e.getEmail() %>">修改</a>
这种跳转规则就是:资源?key=value&key=value,可能有些人单看这一串代码不是很明白,那么我放上整个controller.jsp页面的代码
<%-- 处理登录请求的jsp --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" import="com.imooc.db.*,com.imooc.bean.*,java.util.*" %>
<%@ page import="java.util.Map" %>
<!--声明当该页面产生异常exception时交由error.jsp页面进行处理--> <%@ page errorPage="error.jsp" %>
<html>
<head>
<title>Title</title>
<style>
table{
border: 1px solid black;
width: 500px;
}
</style>
</head>
<body>
<!--
获取账号以及密码,调用DBUtil中的方法判断是否存在指定的用户信息
1、如果正确,DBUtil返回true,显示成功页面
2、如果错误,DBUtil返回false,显示失败页面
使用request内置对象获取登录界面传来的表单内的用户信息
request.getParameter(String name):通过表单内的控件的name属性来获取控件的值
out内置对象:输出流对象,可以向页面输出指定的信息
out.println();
-->
<h3>响应的字符编码集:<%= response.getCharacterEncoding() %></h3>
<%
String account = request.getParameter("account");
String password = request.getParameter("password");
//用Emp对象封装输入的用户信息
Emp emp = new Emp(account, null, password, null);
//判断用户名和密码是否正确
boolean flag = DBUtil.selectEmpByAccountAndPassoword(emp);
Map<String,Emp> map = DBUtil.map;
if (flag == true){
//使用session保存登录用户的信息
session.setAttribute("account", account);
//统计web应用访问量
Object o = application.getAttribute("count");
if (o == null){
//如果是该web应用是第一次访问
application.setAttribute("count", 1);
}
else {
//不是第一次被访问则访问量加一
int count = (int) application.getAttribute("count");
application.setAttribute("count", count + 1);
}
%>
<!--在页面右上角显示访问量-->
<h3 align="right">访问量:<%= application.getAttribute("count") %></h3>
<!--在页面右上角显示登录账户信息-->
<h3 align="right">登录账户:<%= session.getAttribute("account") %></h3>
<h3 align="center">欢迎来到人事管理系统首页!</h3>
<hr>
<table align="center">
<tr>
<td>
账号
</td>
<td>
姓名
</td>
<td>
邮箱
</td>
<td>
修改
</td>
</tr>
<%
for (String key : map.keySet()){
Emp e = map.get(key);
%>
<!--循环输出所有用户信息-->
<tr>
<td>
<%= e.getAccount() %>
</td>
<td>
<%= e.getName()%>
</td>
<td>
<%= e.getEmail()%>
</td>
<td>
<!--
相邻两个JSP页面传递数据的时候,通过URL参数的方式来传递数据
规则:
资源?key=value&key=value
-->
<!--将这一行对应的用户名、名字和邮箱传递给修改页面update.jsp-->
<a href="update.jsp?account=<%= e.getAccount() %>&name=<%= e.getName() %>&email=<%= e.getEmail() %>">修改</a>
</td>
</tr>
<%
}
%>
</table>
<%
}else{
//用户名密码错误则抛出异常,并传入message
throw new Exception("用户名和密码错误!");
}
%>
</body>
</html>
当我们点击了第一行的修改,跳转到update.jsp时,注意地址:
我们会发现我们要传递的数据出现在了url中,这就是所谓的通过url在不同资源(页面)之间传递数据,那么通过URL方式传递的数据我们需要使用request.getParameter(String key)来取得。
在update页面中,完成数据的获取
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h3 align="center">修改页面</h3> <!--在页面右边显示当前登录用户--> <h3 align="right">登录用户:<%= session.getAttribute("account") %></h3> <hr> <form action="update_control.jsp"> <table align="center"> <tr> <td>用户名</td> <td><input type="text" name="account" value="<%= request.getParameter("account") %>"></td> </tr> <tr> <td>名字</td> <td><input type="text" name="name" value="<%= request.getParameter("name") %>"></td> </tr> <tr> <td>邮箱</td> <td><input type="text" name="email" value="<%= request.getParameter("email") %>"></td> </tr> <tr> <td colspan="2" align="center"><input type="submit" value="修改"></td> </tr> </table> </form> </body> </html>
这样就完成一个数据从controller.jsp通过URL的方式传递到update.jsp并显示在页面上的效果了。最后我们还需要实现在update.jsp中点击修改后,用户的数据得到修改的效果。
我们注意到上面的update.jsp代码中的表单在点击修改按钮后,会将表单信息交由update_control.jsp处理,因此我们创建update_control.jsp,在里面完成相应的数据处理
<%@ page import="java.util.Map" %> <%@ page import="com.imooc.bean.Emp" %> <%@ page import="com.imooc.db.DBUtil" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% //获取到存放用户数据的集合 Map<String,Emp> map = DBUtil.map; //获取到要修改的用户对象 Emp emp = map.get(request.getParameter("account")); //修改用户信息 emp.setAccount(request.getParameter("account")); emp.setName(request.getParameter("name")); emp.setEmail(request.getParameter("email")); %> <h3 align="center">修改员工信息成功</h3> </body> </html>
这样就完成了整个人事管理系统的用户信息修改功能!
相关文章推荐
- jsp基础知识
- JavaWeb学习笔记 ---- Jsp基础知识归纳篇(上)
- jsp基础知识(一)
- JSP基础知识一
- J2EE应用讲解(3)——JSP基础知识
- tomcat基础知识——jsp访问错误(一)
- JSP基础知识之JSP的构成元素
- jsp基础知识点详解
- jsp基础知识一
- jsp基础知识-6.17
- JSP 杂项基础知识
- JSP基础知识
- JSP 基础知识点总结 01
- jsp基础知识
- JSP学习笔记-基础知识
- Jsp基础知识
- JavaWeb学习笔记 ---- Jsp基础知识归纳篇(上)
- JSP基础知识
- Jsp基础知识二
- Jsp开发基础知识+九大隐式对象+11个内置对象+标签库(实际web开发中的典型)