jsp的全称是Java Server page(Java的服务器界面)它将java和html相结合
jsp的主要作用是代替Servlet程序回传html页面的数据。
因为Servlet程序回传html页面数据是一件非常繁琐的事情,开发成本和维护成本都极高。
javax.servlet
jsp-api
2.0
tomcat
jasper-runtime
5.5.23
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write("DOCTYPE html>");
writer.write("");
writer.write("<head>");
writer.write("");
writer.write("<title>Titletitle>");
writer.write("head>");
writer.write("<body>");
writer.write("<h1>testh1>");
writer.write("body>");
writer.write("html>");
}
jsp本质上是一个servlet。
当我们第一次访问jsp页面的时候,Tomcat服务器会帮我们把jsp页面翻译成一个Java源文件。并且对它进行编译成为.class字节码程序。
打开jsp翻译后的Java文件:
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/8.5.59
* Generated at: 2021-09-02 20:01:50 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class a_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private static final java.util.Set<java.lang.String> _jspx_imports_packages;
private static final java.util.Set<java.lang.String> _jspx_imports_classes;
static {
_jspx_imports_packages = new java.util.HashSet<>();
_jspx_imports_packages.add("javax.servlet");
_jspx_imports_packages.add("javax.servlet.http");
_jspx_imports_packages.add("javax.servlet.jsp");
_jspx_imports_classes = null;
}
private volatile javax.el.ExpressionFactory _el_expressionfactory;
private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public java.util.Set<java.lang.String> getPackageImports() {
return _jspx_imports_packages;
}
public java.util.Set<java.lang.String> getClassImports() {
return _jspx_imports_classes;
}
public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
if (_el_expressionfactory == null) {
synchronized (this) {
if (_el_expressionfactory == null) {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
}
}
}
return _el_expressionfactory;
}
public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
if (_jsp_instancemanager == null) {
synchronized (this) {
if (_jsp_instancemanager == null) {
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
}
}
return _jsp_instancemanager;
}
public void _jspInit() {
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final java.lang.String _jspx_method = request.getMethod();
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
return;
}
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
out.write(" Title \r\n");
out.write("\r\n");
out.write("\r\n");
out.write(" 这是jsp页面
\r\n");
out.write("\r\n");
out.write("\r\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LVFJQ9TB-1660554820856)(C:\Users\66496\AppData\Roaming\Typora\typora-user-images\image-20210903041937366.png)]](https://1000bd.com/contentImg/2022/08/19/001056027.png)
接下来我们修改index.jsp的内容,定义一个java变量,并取出输出到页面:
<%
String name = "zhangsan";
%>
<%=name%>
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
out.write(" Title \r\n");
out.write("\r\n");
out.write("\r\n");
String name = "zhangsan";
out.write('\r');
out.write('\n');
out.print(name);
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
观察翻译出来的源代码不难发现,其底层实现也是通过输出流把页面数据回传给客户端。所以jsp其实还是一个servlet,只不过它代替了人们以前在servlet中拼接html代码的工作,使得在开发中jsp只用专注于html代码的编写,由于html代码和java代码分离,也使维护起来更省力。
jsp的执行过程
•客户端发出Request (请求);
•tomcat 容器将JSP 转译成Servlet 的源代码;
•将产生的Servlet 的源代码经过编译后,并加载到内存执行;
•进入Servlet的执行过程;
指令(Directives)主要用来提供整个JSP 网页相关的信息,并且用来设定JSP网页的相关属性,例如:网页的编码方式、语法、信息等。
–起始符号为: <%@
–终止符号为: %>
–中间部分就是一些指令和一连串的属性设定,如下所示:
–<%@ directive attribute =“value” %>
jsp页面包含三种指令:
–page指令
–include指令
–taglib指令
page指令可以修改jsp页面的一些重要属性
表示jsp翻译后是什么语言文件。目前只支持java
表示jsp返回的数据类型是什么,也是源码中response.setContentType()的参数值
用于导包和导类
errorPage="/error500.jsp"


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gGInYf18-1660554820862)(C:\Users\66496\AppData\Roaming\Typora\typora-user-images\image-20210903045137849.png)]](https://1000bd.com/contentImg/2022/08/19/001056862.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m1H7gdzk-1660554820863)(C:\Users\66496\AppData\Roaming\Typora\typora-user-images\image-20210903045157157.png)]](https://1000bd.com/contentImg/2022/08/19/001057082.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MJ1cRZKg-1660554820865)(C:\Users\66496\AppData\Roaming\Typora\typora-user-images\image-20210903045226789.png)]](https://1000bd.com/contentImg/2022/08/19/001057275.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yWUNTHke-1660554820866)(C:\Users\66496\AppData\Roaming\Typora\typora-user-images\image-20210903045248643.png)]](https://1000bd.com/contentImg/2022/08/19/001057482.png)
在jsp页面上输出数据
表达式脚本都会被翻译成out.print(),输出到页面上
表达式脚本中的表达式不能以分号结束


动态路径:
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
html注释会被翻译到Java源代码中。以out.write输出到客户端
单行注释://
多行注释:/**/
Java注释会被翻译到Java源代码中
<%-- -->
jsp注释,可以注释掉jsp页面中的所有代码
jsp内建对象是: 在jsp中预定义好的对象;开发者可以在jsp直接使用,无需定义和创建。

–page
–out
–request
–response
–session
–application
–config
–exception
pageContext






scope.jsp:

scope2.jsp:

scope.jsp中加上跳转语句

直接跳转:pageContext为null
直接在浏览器输入scope2:request为null
关闭浏览器再访问scope2:session为null
重启tomcat再访问scope2:application为null
使用的优先级顺序

•动作元素实际就是jsp页面的一些标记,通过解释转换成相应的java代码,达到某些功能。
•动作元素与指令元素不同,动作元素是在客户端请求时动态执行的,每次有客户端请求时可能都会被执行一次,而指令元素是在编译时被编译执行,它只会被编译一次。
•一个JSP动作元素,通过它可以操作隐含对象和其它服务器端对象,也能够定义新的脚本变量。
•动作元素(Actions)遵循XML的语法,由一个开始标记开始,一个主体和一个结束标记。如果主体是空的,它也可以使用空标记。标记必须有一个前缀 ”jsp:”。




<jsp:include page=“userinfo.jsp”>
<jsp:param name=“username” value=“hellking”>
….
jsp:include>
<jsp:forward page=“userinfo.jsp”>
<jsp:param name=“username” value=“hellking”>
…
jsp:forward>
<jsp:plugin type=“applet” code=“com.imageapplet”>
<jsp:param name=“username” value=“hellking”>
jsp:plugin>

//一个javaBean
public class LoginInfoBean {
private String suser = "";
private String spwd = "";
public String getSpwd() {
return spwd;
}
public void setSpwd(String spwd) {
this.spwd = spwd;
}
public String getSuser() {
return suser;
}
public void setSuser(String suser) {
this.suser = suser;
}
}

//上面的动作元素相当于下面的java代码;即jsp转化为servlet时也会被转换成类似下面的代码;
<%
LoginInfoBean login =null;
login =request.getAttribute("login");
if(login ==null){
login =new LoginInfoBean();
request.setAttribute("login", login);
}
%>
//useBean作用: a)在jsp页面中定义变量; b)查找作用域中的数据对象;如找到赋给jsp中的变量;如没找到创建并放到作用域中


JSP技术提供了三个关于JavaBean组件的动作元素,即JSP标签,它们分别为:
"id"属性用于指定JavaBean实例对象的引用名称和其存储在域范围中的名称。
"class"属性用于指定JavaBean的完整类名(即必须带有包名)。
"scope"属性用于指定JavaBean实例对象所存储的域范围,其取值只能是page、request、session和application等四个值中的一个,其默认值是page。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
jspTest1
<%=person.getName()%>
<%=person.getPassword()%>
<%=person.getAge()%>
<%=person.getSex()%>
项目路径:
<%
String path = request.getContextPath();
String basePath = request.getScheme()+“😕/”+request.getServerName()+“:”+request.getServerPort()+path+“/”;
%>
在jsp页面中输出99乘法表:


输出10个学生信息到table




请求转发:通过request域回传给jsp
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8RjnrE0D-1660554820906)(C:\Users\66496\AppData\Roaming\Typora\typora-user-images\image-20210903062505586.png)]](https://1000bd.com/contentImg/2022/08/19/001105811.png)
EL表达式的全称是:Expression Language。是表达式语言。
作用:
EL表达式的主要作用是代替jsp页面中的表达式脚本在jsp页面中进行数据的输出。因为EL表达式在输出数据的时候要比jsp的表达式脚本简洁很多。
格式:
${表达式}
<%
request.setAttribute("key","值");
%>
表达式脚本输出的key的值是:<%=request.getAttribute("key")%>
EL表达式输出的key的值是:${key}
//如果值不存在,表达式脚本输出null,EL表达式不输出内容
<%
request.setAttribute("key","值");
%>
表达式脚本输出的key的值是:<%=request.getAttribute("key1")%>
EL表达式输出的key的值是:${key1}
<%=request.getAttribute("key1")==null?"":request.getAttribute("key1")%>
当四个域中都有相同的key数据的时候,EL表达式会按照四个域从小到大的顺序进行搜索,找到就输出。
<%
//往四个域中都保存了相同的key数据
pageContext.setAttribute("key","pageContext");
request.setAttribute("key","request");
session.setAttribute("key","session");
application.setAttribute("key","application");
%>
key的值:${key}
JavaBean:
package com.cykj.web.bean;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class Person {
private String name;
private String[] phones;
private List<String> cities;
private Map<String,Object> map;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getPhones() {
return phones;
}
public void setPhones(String[] phones) {
this.phones = phones;
}
public List<String> getCities() {
return cities;
}
public void setCities(List<String> cities) {
this.cities = cities;
}
public Map<String, Object> getMap() {
return map;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
@Override
public String toString() {
return "Person{" +
"name=" + name +
", phones=" + Arrays.toString(phones) +
", cities=" + cities +
", map=" + map +
'}';
}
public Person() {
}
public Person(String name, String[] phones, List<String> cities, Map<String, Object> map) {
this.name = name;
this.phones = phones;
this.cities = cities;
this.map = map;
}
}
jsp:
<%
Person p = new Person();
p.setName("张三");
p.setPhones(new String[]{"123","234"});
List cityes = new ArrayList();
cityes.add("beijing");
cityes.add("sh");
cityes.add("gz");
p.setCities(cityes);
Map map = new HashMap();
map.put("key1","value1");
map.put("key2","value2");
map.put("key3","value3");
map.put("key4","value4");
p.setMap(map);
pageContext.setAttribute("person",p);
%>
person:${person}
person的name属性:${person.name}
person的数组:${person.phones}
person的集合:${person.cities}
person的集合中的个别元素:${person.cities[0]}
person的Map:${person.map}
person的Map中的某个Key:${person.map.key1}
EL表达式找的不是属性,而是get方法对应的内容(举例)
==或eq:等于 !=或ne:不等于 <或lt:小于 >或gt:大于 <=或le:小于等于 >=或ge:大于等于
- 1
- 2
- 3
- 4
- 5
- 6

&&或and:与运算
||或or:或运算
!或not:非运算

+:加法
-:减法
*:乘法
/或div:除法
%或mod:取余

empty运算可以判断一个数据是否为空,如果为空,则输出true,不为空输出false


${gender eq 0?"男":"女"}










javax.servlet.jsp.jstl
jstl-api
1.2
taglibs
standard
1.1.2




${requestScope.name}
没有else,只能写多个if
<c:if test="${12==12}">
<h1>12等于12h1>
c:if>
<c:if test="${12!=12}">
<h1>12不等于12h1>
c:if>

<c:set scope="request" var="score" value="85">c:set>
<c:choose>
<c:when test="${requestScope.score<60}">
<h1>不及格h1>
c:when>
<c:when test="${requestScope.score<75}">
<h1>及格h1>
c:when>
<c:when test="${requestScope.score<85}">
<h1>良好h1>
c:when>
<c:otherwise>
<h1>优秀h1>
c:otherwise>
c:choose>
注意:
1、标签里面不能使用html注释,要使用jsp注释
2、when标签的父标签一定要是choose标签
begin:开始的索引
end:结束的索引
var:变量名称
遍历1-10
遍历Object类型的数组
items:表示遍历的数据源(数组)
var:表示当前遍历到的数据
<%
request.setAttribute("arr",new String[]{"a","b","c","d"});
%>
${item}
遍历Map
<%
Map map = new HashMap();
map.put("k1","v1");
map.put("k2","v2");
map.put("k3","v3");
map.put("k4","v4");
request.setAttribute("map",map);
%>
${entry.key}=${entry.value}
遍历List集合
<%
List list = new ArrayList();
for(int i=0;i<10;i++){
Tbluserinfo tbluserinfo = new Tbluserinfo();
tbluserinfo.setMoney(10000);
tbluserinfo.setPhone("13588888888");
tbluserinfo.setRid(i);
tbluserinfo.setUname("tbl"+i);
tbluserinfo.setUpwd("123456");
tbluserinfo.setUsersid(i);
list.add(tbluserinfo);
}
request.setAttribute("list",list);
%>
sid
rid
name
pwd
money
phone
${tbl.usersid}
${tbl.rid}
${tbl.uname}
${tbl.upwd}
${tbl.money}
${tbl.phone}
练习:遍历一个表格
