JSP学习
全称Java Server Page,Java服务器 页面,可以用于构建动态页面
JSP语法
脚本<% %>
脚本实际是卸载JSP生成的.java文件的类_jspService方法的里面,脚本变量时局部变量,定义内部类时方法里面的局部内部类
表达式<%= %>
表达式实际是写在JSP生成的.java文件的类_jspService方法的里面输出变量
在<%! %>中声明的变量属于成员变量
在<% %>中声明的变量属于局部变量
<!-- HTML注释 声明 ->
会显示在源代码和右键查看源代码
<%-- JSP注释 脚本–%>
不会显示在源代码和右键查看源代码
JSP和Servlet的关系
注意,JSP不同于Servlet是可以直接被访问的,当JSP被访问的时候,服务器会先生成.java代码,再生成.class文件,最后执行。
JSP可以当作Servlet来配置
所以JSP就是一个Servlet
<servlet>
<!-- jsp也可以当作Servlet来进行配置 -->
<servlet-name>index</servlet-name>
<jsp-file>/jspApp01/src/main/webapp/jsp/index.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>index</servlet-name>
<url-pattern>/index</url-pattern>
</servlet-mapping>
生命周期
三个指令
Page指令
主要内容
page指令主要是描述页面相关的信息:
language=“java”:支持的语言,目前主要是支持Java语言
contextType=“text/html;charet=UTF-8”:输出客户端的内容的形式以及编码
pageEncoding=“UTF-8”:页面编码
isELIgnored=“false”:是否忽略EL表达式,默认为false,false支持表示El表达式
import=“”:导包,因为jsp中可以写java代码,因此导包
extends=“”:jsp就是Serlvet们就是Java代码,因此也存在继承机制
isThreadSafe=“true”:是否线程安全,默认是线程安全
buffer=“8kb”:默认缓冲大小是8kb
autoFlush=“true”:当缓冲满了之后是否自动刷新,默认自动刷新
isErrorPage=“false”:指定当前页面是否是错误信息的处理页面
errorPage=“”:指定处理错误信息页面的地址,如果errorPage=true,那么就会多一个内置对象exception供我们使用‘
使用方法
<%@ page language="java"%>
Include指令
主要内容
当有很多代码在每个jsp文件中都要使用到时,可以把公共代码抽取出来到一个jsp文件,然后通过include指令调用
include也叫做静态包含,后面还会有动态包含
静态包含的意义是将被包含文件中的内容放到引用文件中进行编译,所以被包含文件中最好不要定义变量,以免发生冲突!
假设以下代码统一放在一个jsp文件 commond.jsp中
<script type="text/javascript" src="commond.js"></script>
<script type="text/javascript" src="main.js"></script>
<script type="text/javascript" src="page.js"></script>
使用方法
<%@ include file="commond.jsp" %>
Taglib指令
主要内容
导入标签库
使用方法
<%@ taglib %>
七个常用动作
标签,通常也称作动作,是一组按照XML语法格式编写的代码片段,在JSP中,用来封装在页面中可重复利用的逻辑,通过标签可以使JSP页面变得简洁并且易于维护。由于标签是XML元素,所以他的名称和属性都是大小写敏感的。
jsp中包含多个已经封装好的可以直接使用的动作,常用的有七个
常规动作
<jsp:include>
主要内容
动态包含,可以包含一个页面
与静态包含的区别:动态包含可以包含有同名变量的页面,相当于编译之后以及执行的结果引入当前页面
使用方法
<jsp:include page="xxxx.jsp"></jsp:include>
<% String name="jack";%> 同名变量不会产生冲突
<jsp:forward>
主要内容
服务器内部跳转,请求链不会断开
使用方法
<jsp:forward page="xxxx.jsp">
<jsp:param value="20" name="age"/> 参数传递
</jsp:forward>
<%= request.getParameter("age") %> 在跳转的目标页面中获取传递的参数
<jsp:param>
一般是配合<jsp:foward>一起使用,用于传递参数
<jsp:plugin>
在页面加入插件,但是现在已经不怎么使用了
操作JavaBean的一组动作标签
JavaBean一般都有如下几个特征:1.有无参构造器 2.成员有对应的get、set方法 3.实现Serializable序列化接口
<jsp:getProperty>
<jsp:setProperty>
<jsp:useBean>
使用方法
以下代码相当于 User user = new User();
<jsp:useBean id="user" class="User" scope="" beanName=""></jsp:useBean>
class为引用的类,scope为作用域,beanName为
以下代码相当于 user.setName(“admin”)
<jsp:setProperty property="name" name="user" value="admin"/>
以下代码相当于user.getName();
<jsp:getProperty property="name" name="user"/>
九个内置对象
pageContext
javax.servlet.jsp.PageContext
请求上下文内容 ,pageContext对象的创建和初始化都是由容器来完成的,jsp页面中可以直接使用pageContext对象。
存放在pageContext中的数据只能在当前页面访问
<%
pageContext.setAttribute("pageContext","pageContext中的数据");
%>
<%=
pageContext.getAttritube("pageContext");
%>
request
javax.servlet.http.HeepServletRequest
请求对象,封装了由客户端生成的HTTP请求的所有细节,主要包括HTTP头信息,系统信息,请求方式和请求参数等。通过request对象提供的相应方法可以处理客户端浏览器提交的HTTP求情中的各项参数。
存放在request中的数据只能在同一个请求中获取
<%
request.setAttribute("request","request中的数据");
%>
<%=
request.getAttritube("request");
%>
session
javax.servlet.http.HttpSession
会话对象,session对象会一直存在直到关闭浏览器。如果长时间不进行交互,自动关闭session,默认时间是30分钟。
存放在session中的数据只能在同一个会话中获取
<%
session.setAttribute("session","session中的数据");
%>
<%=
session.getAttritube("session");
%>
application
javax.servlet.ServletContext
应用程序对象,用于保存所有应用中的共有数据。他在服务器启动时自动创建,在服务器停止时销毁,所有用户都可以共享该application对象。
存放在application中的数据只要项目没有关闭就可以访问到,相当于是全局的
<%
application.setAttribute("application","application中的数据")
%>
<%=
application.getAttribute("application")
%>
response
javax.servlet.http.HttpServletResponse
响应对象,用于响应客户请求,向客户端输出信。它封装了JSP产生的响应,并发送到客户端以响应客户端的请求。请求的数据可以是各种数据类型,甚至是文件。response对象在JSP页面内有效
config
javax.servlet.ServletConfig
配置对象,主要用去取得服务器的配置信息。当一个Servlet初始化时,容器把某些信息通过config对象传递给这个Servlet。开发者可以在web.xml文件中为应用程序环境中的Servlet程序和JSP页面提供初始化参数。
page
java.lang.Object
页面对象,page对象代表JSP本身,只有在JSP页面内才是合法的。page对象本质上时包含当前Servlet接口引用的变量,可以看作是this关键字的别名
out
java.servlet.jsp.JspWriter
输出对象,用于在Web浏览器内输出信息,并且管理应用服务器上的输出缓冲区。在使用out对象输出数据时,可以对数据缓冲区进行操作,及时清除缓冲区中的残余数据,为其他的输出让出缓冲空间。待数据输出完毕后,要及时关闭输出流。
exception
java.lang.Throwable
例外对象,需要设置page指令中的属性isErrorPage=“true”,用来处理JSP文件执行时发生的所有错误和异常。如果在JSP页面中出现没有捕获到的异常,就会生成exception对象,并把exception对象传送到page指令中定义的错误页面中,然后再错误页面处理相应的exception对象。
EL表达式
EL全称为Expression Language 表单式语言
EL主要作用
获取数据:
El表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域中检索java对象、获取数据。(某个web域中的对象,访问JavaBean的属性、访问list集合、访问map集合、访问数组)
(1)执行运算
利用EL表达式可以在JSP页面中执行一些基本的关系运算,逻辑运算和算术运算,以在JSP页面中完成一些简单的逻辑运算。${user==null}
(2)获取web开发常用对象
EL表达式定义了一些隐式对象,利用这些隐式对象,web开发人员可以很轻松地获得对web常用对象的应用,从而获得这些对象的数据。
(3)EL表达式语法非常简洁,可以大大简化开发难度,提升开发效率
使用EL表达式获取数据语法:“${标识符}”
EL表达式:
算术表达式
1+1:${1+1}
10-5:${10-5}
22:${22}
10/5:${10/5}
10对3求模:${10%3}
关系表达式
1=1:${1==1}
1!=1:${1!=1}
1>1:${1>1}
1<1:${1<1}
1>=1:${1>=1}
1<=1:${1<=1}
逻辑表达式
true&&true:${true&&true}
true&&false:${true&&false}
true||true:${true||true}
true||false:${true||false}
判断name是否为空:${empty name}
JSTL标签库
JSTL全称Java Standard Tag Library
标签,通常也称作动作,是一组按照XML语法格式编写的代码片段,在JSP中,用来封装在页面中可重复利用的逻辑,通过标签可以使JSP页面变得简洁并且易于维护。由于标签是XML元素,所以他的名称和属性都是大小写敏感的。
使用标签库步骤
1.导入jar包
2.在taglib指令中制定标签库
3.使用标签
使用案例
(1)循环
<%@page import="java.util.ArrayList"%>
<%@page import="xyf.bean.User"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!-- 引入标签库 -->
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!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=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 循环 -->
<c:forEach var="i" begin="1" end="10" step="1">
${i}
</c:forEach>
<%
List<User> users = new ArrayList<>();
User u1 = new User("jack","123");
User u2 = new User("tom","321");
users.add(u1);
users.add(u2);
request.setAttribute("users", users);
%>
<c:forEach items="${requestScope.users}" var="user">
用户名:${user.name}------密码:${user.password}
</c:forEach>
</body>
</html>
(2)判断
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!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=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
request.setAttribute("age", 50);
%>
<!-- jsp中有if,但没有else -->
<c:if test="${requestScope.age<30}">
你还年轻,还有很多机会!<br>
</c:if>
<!-- 比较复杂的判断可以用过以下配合使用 -->
<c:choose>
<c:when test="${age<25 }">
你太年轻了!
</c:when>
<c:when test="${age>25 && age<45 }">
你正当壮年!
</c:when>
<c:otherwise>
你已经事业有成了!
</c:otherwise>
</c:choose>
</body>
</html>
(3)函数标签
<%@page import="java.util.ArrayList"%>
<%@page import="org.apache.naming.java.javaURLContextFactory"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!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=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
java.util.ArrayList<String> arr = new java.util.ArrayList<String>();
arr.add("1111");
arr.add("2222");
arr.add("3333");
request.setAttribute("arr", arr);
%>
<!-- 获取长度 -->
数组长度为:${fn:length(arr)}
<hr>
<!-- 判断是否包含指定的元素 -->
${fn:contains("ABC","c")}<br>
${fn:contains("ABC","C")}<br>
<hr>
<!-- 判断是否包含指定的元素,忽略大小写 -->
${fn:containsIgnoreCase("ABC","a")}<br>
${fn:containsIgnoreCase("ABC","A")}<br>
<hr>
<!-- 判断是否以某个值开头 -->
${fn:startsWith("ABC","C")}<br>
${fn:startsWith("ABC","c")}<br>
<hr>
<!-- 判断是否以某个值结尾 -->
${fn:endsWith("ABC","bc")}<br>
${fn:endsWith("ABC","BC")}<br>
<hr>
<!-- 在母句中索引子句 -->
${fn:indexOf("ABCD","aBC")}<br>
${fn:indexOf("ABCD","BCD")}<br>
<hr>
<!-- 进行查询替换 -->
${fn:replace("ABC","A","B")}<br>
<hr>
<!-- 分割字符串 -->
<c:forEach items="${fn:split('a+b+c','+')}" var="temp">
${temp}
</c:forEach>
<hr>
<!-- 求子串 -->
${fn:substring("ABC",1,3)}<br>
</body>
</html>
(4)格式化标签
<%@page import="org.apache.naming.java.javaURLContextFactory"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!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=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
java.util.Date date = new java.util.Date();
request.setAttribute("nowDate", date);
request.setAttribute("price", 199.98730);
%>
<!-- 格式化输出日期时间 -->
当前时间:<fmt:formatDate value="${nowDate}" pattern="yyyy-MM-dd"/><br>
<!-- 格式化输出两位小数 -->
商品价格:<fmt:formatNumber value="${price}" pattern="0.00"></fmt:formatNumber>
</body>
</html>
(5)其他标签
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!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=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 将pageContext.request.contextPath赋值给path -->
<c:set value="${pageContext.request.contextPath}" var="path"></c:set>
path=${path}
<!-- 输出num,如果num不存在则输出 数据不存在 -->
<c:out value="${num}" default="数据不存在"></c:out>
<!-- 跳转 重定向到百度 -->
<c:redirect url="http://www.baidu.com">跳转到百度</c:redirect>
</body>
</html>
(6)自定义标签
1.需要准备标签处理类,标签处理类需要继承TagSupport
重写doStartTag以及doEndTag方法
2.需要准备一个tld文件,放在WEB-INF下,该文件在tomcat下可以找到
3.哪一个页面需要用到该标签就引入即可
演示模仿<c:out>
标签配置文件tld
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<!-- a tag library descriptor -->
<taglib>
<!-- 版本号 -->
<tlib-version>1.0</tlib-version>
<!-- 版本号 -->
<jsp-version>1.2</jsp-version>
<!-- 标签简称 -->
<short-name>simple</short-name>
<!-- uri非常重要 页面通过引入该uri使用标签 -->
<uri>/firstTag</uri>
<description>
模仿JSTL中的c:out
</description>
<!-- This is a dummy tag solely to satisfy DTD requirements -->
<tag>
<!-- 标签名字 -->
<name>myOut</name>
<!-- 标签处理类 -->
<tag-class>xyf.bean.MyOut</tag-class>
<body-content>TAGDEPENDENT</body-content>
<!-- 描述信息 -->
<description>
Perform a server side action; Log the message.
</description>
<!-- 属性 -->
<attribute>
<!-- 属性名 -->
<name>value</name>
<!-- 是否必须有该属性 -->
<required>false</required>
<!-- 是否支持EL表达式 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<!-- 属性名 -->
<name>defaultValue</name>
<!-- 是否必须有该属性 -->
<required>false</required>
<!-- 是否支持EL表达式 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
标签处理java类
需要继承TagSupport类
package xyf.bean;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
/*
* 标签处理类
*/
public class MyOut extends TagSupport {
private String value;
private String defaultValue;
@Override
public int doStartTag() throws JspException {
System.out.println("--------------doStart----------------");
try {
JspWriter jspWriter = this.pageContext.getOut();
if("".equals(value) || value==null) {
jspWriter.write(defaultValue);
}else {
jspWriter.write(value);
}
} catch (Exception e) {
e.printStackTrace();
}
return super.doStartTag();
}
@Override
public int doEndTag() throws JspException {
System.out.println("--------------doEnd----------------");
return super.doEndTag();
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
}
效果测试
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="a" uri="/firstTag" %>
<!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=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a:myOut value="abc" defaultValue="123"></a:myOut>
</body>
</html>
MVC模式
在服务器端表示层的框架中,早期蹭列举了两种架构,分别为Module1和Module2,演化成MVC模式
MVC思想是将一个应用分成三个基本部分:Model(模型)、View(视图)和Controller(控制器),这三个部分以最少的耦合协同工作,从而提高应用的可扩展性和可维护性。
MVC:model view controller
M:model,模型,用来传递数据
V:view,视图,用来显示页面的jsp
C:controller,控制器,用来接收参数,调用JavaBean处理业务,转发请求Servlet
Model1
在Model1模式下,整个Web应用几乎全部由JSP页面组成,JSP页面接收处理客户端请求,对请求处理后直接做出回应,用少量的Javabean来处理数据库连接、数据库访问等操作。
Model1模式的实现比较简单适用于快速开发小规模项目。
从工程化的角度看,Model1模式的局限性非常明显:JSp页面身兼VIew和Controller两种角色,将控制逻辑和表现逻辑混杂在一起,导致代码的重用性低,增加了应用的扩展性和维护的难度。
Model2
Model2模式,即为JSP+JavaBean+Servlet模式,这是因为在该模式开发中将显示数据、控制页面跳转、数据层操作分别交给JSP、Servlet、JavaBean进行处理
Model 2是基于MVC架构的设计模式。即M(Model:业务逻辑),V(View:用户界面 UI),C(Controller:控制)分离,
JSP只用负责显示,而控制器则由Servlet充当,模型由JavaBean充当。
用户的所有请求提交给Controller,由Controller进行统一分配,并且采用推的方式将不同的UI显示给用户。
这样做得好处是:
可以统一控制用户的行为,例如在Controller中添加统一日志记录等功能是非常方便的
职责分离,有利于各部分的维护。用户不直接访问分散的UI,这样可以通过配置文件或则流程定义的方式,在不同的环节、时间将不同的页面推向给用户
主要思想是使用一个或多个Servlet作为控制器。请求由前沿的Servlet处理后,会重新定向到JSP。在Servlet作为控制器时,每个Servlet通常只实现很少一部分功能,多个Servlets控制器就可以结合起来完成复杂的任务,这样的好处是Servlets的可重用性好,一个副作用是导致响应时间过长。在此模式里,JavaBean作为模型的角色,它充当JSP和Servlet通信的工具。Servlet处理完后设置Bean的属性,JSP读取此Bean的属性,然后进行显示。综上所述,此模式明显的地把显示和逻辑分离