JavaWeb学习(九)—JSP原理/JSP基本语法/JSP指令/JSP标签
01 JSP原理
JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术。
JSP这门技术的最大的特点在于,写jsp就像在写html,但它相比html而言,html只能为用户提供静态数据,而Jsp技术允许在页面中嵌套java代码,为用户提供动态数据。
JSP原理:浏览器向服务器发请求,不管访问的是什么资源,其实都是在访问Servlet,所以当访问一个jsp页面时,其实也是在访问一个Servlet,服务器在执行jsp的时候,首先把jsp翻译成一个Servlet,所以我们访问jsp时,其实不是在访问jsp,而是在访问jsp翻译过后的那个Servlet。举例:当我们通过浏览器访问index.jsp时,服务器首先将index.jsp翻译成一个index_jsp.class,在Tomcat服务器的work\Catalina\localhost\项目名\org\apache\jsp目录下可以看到index_jsp.class的源代码文件index_jsp.java,index_jsp.java。我们可以看到,index_jsp这个类是继承 org.apache.jasper.runtime.HttpJspBase这个类的,通过查看Tomcat服务器的源代码,可以知道在apache-tomcat-6.0.20-src\java\org\apache\jasper\runtime目录下存HttpJspBase这个类的源代码文件。HttpJspBase类是继承HttpServlet的,所以HttpJspBase类是一个Servlet,而index_jsp又是继承HttpJspBase类的,所以index_jsp类也是一个Servlet,所以当浏览器访问服务器上的index.jsp页面时,其实就是在访问index_jsp这个Servlet,index_jsp这个Servlet使用_jspService这个方法处理请求。
**JSP如何输出页面到客户端的?**在jsp中编写的java代码和html代码都会被翻译到_jspService方法中去通过Out对象输出。
JSP八大对象:查看_jspService方法可以看到,Web服务器在调用jsp时,会给Jsp提供如下的8个java对象
PageContext pageContext;//作用域
HttpSession session;//会话
ServletContext application;//应用,其实就是servletContext
ServletConfig config;//配置
JspWriter out;//输出
Object page = this;//页面
HttpServletRequest request;//请求
HttpServletResponse response//响应
其中page对象,request和response已经完成了实例化,而其它5个没有实例化的对象通过下面的方式实例化
pageContext = _jspxFactory.getPageContext(this, request, response,null, true, 8192, true);
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
02 JSP基本语法
JSP是JAVA上的一种应用,在JSP中,所有的JAVA语句都可以使用。它的扩充语法为:
<%--赋值--%>
<%= 变量或表达式 %>
<%--在<% %>中可以定义变量、编写语句,不能定义方法--%>
<%
多行java代码
%>
<%--
声明:JSP声明可用于定义JSP页面转换成的Servlet程序的静态代码块、成员变量和方法 。
--%>
<%!
java代码
%>
<!--HTML风格注释-->
<%
//JAVA中的单行注释
/*
JAVA中的多行注释
*/
%>
<%--JSP自己的注释--%>
注意事项:
- JSP脚本片断中只能出现java代码,不能出现其它模板元素, JSP引擎在翻译JSP页面中,会将JSP脚本片断中的Java代码将被原封不动地放到Servlet的_jspService方法中。
- JSP脚本片断中的Java代码必须严格遵循Java语法,例如,每执行语句后面必须用分号(;)结束。
- 在一个JSP页面中可以有多个脚本片断,在两个或多个脚本片断之间可以嵌入文本、HTML标记和其他JSP元素。
- HTML的注释在浏览器中查看源文件的时候是可以看得到的,而JAVA注释和JSP注释在浏览器中查看源文件时是看不到注释的内容的,这就是这三种注释的区别。
03 JSP指令
JSP指令只有三个,分别是page
include
taglib
- 常用Page指令
<%--设置页面文本类型--%>
<%@ page contentType="text/html;charset=UTF-8" %>
<%--设置页面自动刷新,默认值为false--%>
<%@ page autoFlush="true" %>
<%--设置JSP编程语言--%>
<%@ page language="java" %>
<%--跳转至错误页面(不推荐使用,推荐在XML中配置)--%>
<%@ page errorPage="/error/404.jsp" %>
<%--导包--%>
<%@ page import="com.hooi.pojo.Student" %>
<%--设置页面编码方式--%>
<%@ page pageEncoding="utf-8" %>
在xml中配置error page
<!--如果错误代码是404,则跳转至error文件下的404错误页面-->
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
</error-page>
<!--如果错误代码是500,则跳转至error文件下的500错误页面-->
<error-page>
<error-code>500</error-code>
<location>/error/500.jsp</location>
</error-page>
- 常用include指令
<%@ include file="{要包含的页面}"%>
通常,网站中会有一些可以通用的位置可以被提取出来,比如网站的头部和尾部。
为了方便测试,我们将网页的头部和尾部设计为:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<head>
<style>
div h2 {
margin: 0 auto;
text-align: center;
}
</style>
</head>
<div>
<% int i = 1; //定义一个全局变量%>
<h2>Header_Page</h2>
<h3>i=<%=i%></h3>
</div>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<head>
<style>
div h2 {
margin: 0 auto;
text-align: center;
}
</style>
</head>
<div>
<% int i = 1;//定义一个与头部页面中同名的全局变量%>
<h2>Footer_Page</h2>
<h3>i=<%=i%></h3>
</div>
如何使用include指令包含页面?
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首页</title>
</head>
<body>
<%--插入页面--%>
<h1>@include测试</h1>
<%@ include file="common/header.jsp"%>
<h1>@include测试</h1>
<%@ include file="common/footer.jsp"%>
</body>
</html>
运行效果如图:(这里我们将500的报错页面通过xml配置为了自己定义的页面。)由于header.jsp和footer.jsp定义了同名变量,因此在使用include指令包含页面时,会出现500错误。我们由此可以知道:使用@include指令包含页面,会把包含进来的页面和自己的页面融合成一个servlet,在同一个servlet下定义同名变量会提示500错误。
-
taglib
使用jstl或者其他标签库需要下载对应的jar包,然后导入。
再使用taglib指令将jar包添加为依赖
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%-- 属性说明: prefix:需要使用的标签库名 tagdir:标签库的本地目录 uri : 对应库的网络地址 --%>
需要注意的是:
- 项目要导入对应的标签库的jar包。
- Tomcat中也需要放置对应的jar包
- 代码中,有些特殊符号需要使用转义字符;
04 JSP标签
语法:jsp:xxx
JSP常用标签有三个:
<jsp:include>
:用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称之为动态引入。
<jsp:forward>
:用于把请求转发给另外一个资源。
<jsp:param>
:当使用<jsp:include>
和<jsp:forward>
标签引入或将请求转发给其它资源时,可以使用jsp:param标签向这个资源传递参数。
测试代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>jsp:include测试</h1>
<jsp:include page="common/header.jsp"/>
<jsp:forward page="index.jsp">
<jsp:param name="username" value="DOGIOOH"/>
<jsp:param name="age" value="24"/>
</jsp:forward>
<h1>jsp:include测试</h1>
<jsp:include page="common/footer.jsp"/>
</body>
</html>
<html>
<head>
<title>首页</title>
</head>
<body>
<div>
测试jsp:forward 通过request拿到传入参数 (使用request对象需要导包)
<h1>jsp:forward测试</h1>
<h2>User:<%=request.getParameter("username")%></h2>
<h2>Age:<%=request.getParameter("age")%></h2>
</div>
</body>
</html>
测试结果:
首先是jsp:include的测试结果:由于jsp:include为动态包含,不会把包含进来的页面和自己的页面融合成为一个servlet,因此不会因为头部和脚步页面中出现同名变量而报错。
jsp:forward和jsp:param的测试结果如下:
jsp:useBean标签
首先我们需要了解JavaBean是一个遵循特定写法的Java类,它通常有如下特点:
- 这个Java类必须具有一个无参的构造函数
- 属性必须私有化。
- 私有化的属性必须通过public类型的方法暴露给其它程序,并且方法的命名也必须遵守一定的命名规范。
示例:
public class Student {
private String name;
private int age;
private String id;
private String sex;
private boolean graduated;
public Student() {
}
public Student(String name, int age, String id, String sex, boolean graduated) {
this.name = name;
this.age = age;
this.id = id;
this.sex = sex;
this.graduated = graduated;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public boolean isGraduated() {
return graduated;
}
public void setGraduated(boolean graduated) {
this.graduated = graduated;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", id='" + id + '\'' +
", sex='" + sex + '\'' +
", graduated=" + graduated +
'}';
}
}
<jsp:useBean>
标签用于在指定的域范围内查找指定名称的JavaBean对象,如果存在则直接返回该JavaBean对象的引用,如果不存在则实例化一个新的JavaBean对象并将它以指定的名称存储到指定的域范围中。
<jsp:useBean>
标签使用范例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.hooi.pojo.Student" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--Java代码实现方式:前提,需要导包--%>
<% Student stu1 = new Student(); %>
<% stu1.setName("Jackson"); %>
<% stu1.setAge(18); %>
<% stu1.setSex("male"); %>
<% stu1.setId("0000001"); %>
<% stu1.setGraduated(false); %>
<%--jsp标签实现方式--%>
<jsp:useBean id="stu2" class="com.hooi.pojo.Student" scope="page"/>
<jsp:setProperty name="stu2" property="name" value="Curry"/>
<jsp:setProperty name="stu2" property="age" value="31"/>
<jsp:setProperty name="stu2" property="sex" value="male"/>
<jsp:setProperty name="stu2" property="id" value="0000002"/>
<jsp:setProperty name="stu2" property="graduated" value="true"/>
<%--=============================================================--%>
<%--Java代码方式获取属性--%>
<div>
<h1>Java实现</h1>
<h2>User:<%=stu1.getName()%></h2>
<h2>Age:<%=stu1.getAge()%></h2>
<h2>Sex:<%=stu1.getSex()%></h2>
<h2>ID:<%=stu1.getId()%></h2>
<h2>Graduated:<%=stu1.isGraduated()%></h2>
</div>
<%--EL表达式:不能表达对象--%>
<div>
<h1>EL表达式实现</h1>
<h2>User:${stu2.name}</h2>
<h2>Age:${stu2.age}</h2>
<h2>Sex:${stu2.sex}</h2>
<h2>ID:${stu2.id}</h2>
<h2>Graduated:${stu2.graduated}</h2>
</div>
<%--jsp标签实现获取属性--%>
<div>
<h1>JSP实现</h1>
<h2>
User:<jsp:getProperty name="stu2" property="name"/>
</h2>
<h2>
Age:<jsp:getProperty name="stu2" property="age"/>
</h2>
<h2>
Sex:<jsp:getProperty name="stu2" property="sex"/>
</h2>
<h2>
ID:<jsp:getProperty name="stu2" property="id"/>
</h2>
<h2>
Graduated:<jsp:getProperty name="stu2" property="graduated"/>
</h2>
</div>
</body>
</html>