JSP

一、概念

ldea下面的tomcat的目录:C:\Users\adiminstor\AppData\Local\JetBrains

1.jsp的运行原理:

1.jsp实际上编译后会变成一个class文件,继承了一个类org.apache.jasper.runtime.HttpJspBase;会发现这实际上就是一个servlet类

1
2
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase---->
===>public abstract class HttpJspBase extends HttpServlet implements HttpJspPage
2.内置对象
1
2
3
4
5
6
7
8
9
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;

3.运行过程

用户客户端发出请求,服务器在自己项目内寻找jsp,找到后,先把jsp转换成Java文件,在把Java文件编译成class文件,再交给服务器,由服务器交给用户,那么用户拿到的就是真正的class对象,实际上就是一个servlet;

4.对比jsp和jsp.java

jsp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<%@ page contentType="text/html;charset=UTF-8" language="java"  pageEncoding="utf-8" %>
<html>
<body>
<h2>Hello World!</h2>
<%--pageContext.request.contextPath 当前目录/url pattern--%>
<% String name="saxon";%>
name=<%=name%>
<form action="${pageContext.request.contextPath}/re" method="get" >
<p><label>username:<input type="text" name="username"></label></p>
<p><label>password:<input type="password" name="password"></label></p>
<p>爱好:
<input type="checkbox" name="hobbies" value="篮球" required>篮球
<input type="checkbox" name="hobbies" value="游戏">游戏
<input type="checkbox" name="hobbies" value="休息">休息
<input type="checkbox" name="hobbies" value="唱歌">唱歌
</p>
<input type="submit">
</form>
</body>
</html>

java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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("\n");
out.write("<html>\n");
out.write("<body>\n");
out.write("<h2>Hello World!</h2>\n");
out.write('\n');
String name="saxon";//我们写的Java代码
out.write("\n");
out.write("name=");
out.print(name);//原样输出
out.write("\n");
out.write("<form action=\"");
out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${pageContext.request.contextPath}", java.lang.String.class, (javax.servlet.jsp.PageContext)_jspx_page_context, null));
out.write("/re\" method=\"get\" >\n");
out.write(" <p><label>username:<input type=\"text\" name=\"username\"></label></p>\n");
out.write(" <p><label>password:<input type=\"password\" name=\"password\"></label></p>\n");
out.write(" <p>爱好:\n");
out.write(" <input type=\"checkbox\" name=\"hobbies\" value=\"篮球\" required>篮球\n");
out.write(" <input type=\"checkbox\" name=\"hobbies\" value=\"游戏\">游戏\n");
out.write(" <input type=\"checkbox\" name=\"hobbies\" value=\"休息\">休息\n");
out.write(" <input type=\"checkbox\" name=\"hobbies\" value=\"唱歌\">唱歌\n");
out.write(" </p>\n");
out.write(" <input type=\"submit\">\n");
out.write("</form>\n");
out.write("</body>\n");
out.write("</html>\n");

==通过对比我们明白,如果我们写在jsp中的代码是Java,那么就会原模原样的输出Java代码,如果是html代码就会改写成out.write方法输出到页面上==

二、基本语法

一、导入依赖的包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<dependencies>
<!-- servlet的依赖包-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<!-- jsp的包-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl-api -->
<!-- JSTL的包-->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/taglibs/standard -->
<!-- standard标签库-->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>

</dependencies>

二、基本语法

1.表达式(<%= %>)

1
<h1><%=3%></h1>

2.jsp脚本片段(<% %>)

1
2
3
4
5
6
7
8
9
10
11
12
13
<%
int sum=0;
for (int i = 0; i <1000 ; i++) {
sum+=i;
}
out.println (sum);
%>
<hr>
<%
for (int i = 0; i <5 ; i++) {
%>
<h1>hello world!</h1>
<%} %>

3.jsp声明(<%! %>)

1
2
3
4
5
<%!
static {
int i=0;
}
%>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<%--
Created by IntelliJ IDEA.
User: saxon
Date: 2020/7/28
Time: 21:08
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1><%=3%></h1>
<hr>
<%
int sum=0;
for (int i = 0; i <1000 ; i++) {
sum+=i;
}
out.println (sum);
%>
<hr>
<%
for (int i = 0; i <5 ; i++) {
%>
<h1>hello world!</h1>
<%} %>

<%!
static {
int i=0;
}
%>
</body>
</html>

除了声明,编译后会在类的里面,其他的编译了会在service方法里面;

三、jsp指令

1、配置错误页面
1
2
3
4
5
6
7
8
9
<!-- code要写在location前面-->
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error/500.jsp</location>
</error-page>

404错误界面,没有页面时跳转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%--
Created by IntelliJ IDEA.
User: Saxon
Date: 2020/7/28
Time: 22:18
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>404</title>
</head>
<body>
<img src="${pageContext.request.contextPath}/images/404.jpg" alt="404 error">
</body>
</html>

主页面显示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%--
Created by IntelliJ IDEA.
User: Saxon
Date: 2020/7/28
Time: 22:16
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<% int x=1/0;%> <%--500错误--%>
</body>
</html>

2.include标签的区别

1
2
<%@include file="index.jsp"%> 
<jsp:include page="index.jsp"/>
  • <%@include file=”index.jsp”%> ,就是一个页面,把全部的代码用Java写出来,就是out.write();可能出现变量重名的情况
1
2
3
4
5
6
7
8
9
10
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write(" <title>Title</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write("<h1>this is my include</h1>\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
out.write("\r\n");
out.write("<h1>hello world</h1>\r\n");
  • <jsp:include page=”index.jsp”/>是页面的拼接,是对象拼在一起,区别就在于如果写Java代码会不会出现变量重名的情况
1
2
3
4
5
6
7
8
9
  static {
_jspx_imports_packages = new java.util.HashSet<>();
_jspx_imports_packages.add("javax.servlet");
_jspx_imports_packages.add("java.util");
_jspx_imports_packages.add("javax.servlet.http");
_jspx_imports_packages.add("javax.servlet.jsp");
_jspx_imports_classes = null;
}
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "index.jsp", out, false);

四、jsp的四大作用域和9大内置对象

1.9大内置对象

1.PageContext: javax.servlet.jsp.PageContext 存储信息
2**.request :javax.servlet.http.HttpServletrequest **存储信息
3.response: javax.servlet.http.HttpServletResponse 服务器向客户端的回应信息
4**.session**: javax.servlet.http.HttpSession 存储信息
5.application: javax.servlet.ServletContext 存储信息
6.config :javax.servlet.ServletConfig 配置文件
7.out :javax.servlet.jsp.jspWriter
8.page :不常用
9.exception java.lang.Throwable 异常

2、四大作用域

1
2
3
4
pageContext.setAttribute ("NO1", "saxon1");
request.setAttribute ("NO2", "saxon2");
session.setAttribute ("NO3", "saxon3");
application.setAttribute ("NO4", "saxon4");
  • pageContext:只有当前页面有用,其他页面数据就失效;
  • request:只有这个请求页有效;但是转发数据也会被带到新的页面;
  • session:在这个浏览器关闭前有效;
  • application:只有服务器炸裂时,才会失效;

测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<%--
Created by IntelliJ IDEA.
User: Saxon
Date: 2020/7/28
Time: 21:08
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Index</title>
</head>
<body>
<%
pageContext.setAttribute ("NO1", "saxon1");
request.setAttribute ("NO2", "saxon2");
session.setAttribute ("NO3", "saxon3");
application.setAttribute ("NO4", "saxon4");
%>
<%
String no1 = (String) pageContext.findAttribute ("No1");
String no2 = (String) pageContext.findAttribute ("No2");
String no3 = (String) pageContext.findAttribute ("No3");
String no4 = (String) pageContext.findAttribute ("No4");
String no5 = (String) pageContext.findAttribute ("No2");
%>
<%pageContext.forward("/Test.jsp");%>
${NO1}
${NO2}
${NO3}
${NO4}
${NO5}
</body>
</html>

转发页:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<%--
Created by IntelliJ IDEA.
User:Saxon
Date: 2020/7/28
Time: 22:16
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>
<head>
<title>test</title>
</head>
<body>
<%
String no1 = (String) pageContext.findAttribute ("No1");
String no2 = (String) pageContext.findAttribute ("No2");
String no3 = (String) pageContext.findAttribute ("No3");
String no4 = (String) pageContext.findAttribute ("No4");
String no5 = (String) pageContext.findAttribute ("No5");
%>
${NO1}
${NO2}
${NO3}
${NO4}
${NO5}
</body>
</html>

常见场景:

1.看了一次就不会在看的,例如新闻,可以放在request中

2.用户会一直使用的信息,例如购物车,放在session中

3.这个网页,网站一直要用的,例如,浏览人数,放在application中

4.一些只在当前页面要用到的,就放在pagecontext

五、JSP标签,JSTL标签,EL表达式

一、JSTL标签

种类:

  • 核心标签
  • sql标签
  • xml标签
  • 格式化标签

测试一:

1
2
3
4
5
6
<form action="#" method="get">
用户:<input type="text" name="username" value="${param.username}">
分数:<input type="text" name="score" value="${param.score}">
<br>
<input type="submit" value="提交">
</form>

JSTL标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<c:if test="${param.username=='saxon'}" var="saxon"><!-- 这里的值-->
<c:out value="登录成功"/>
<c:out value="${saxon}"/>
</c:if>
<c:set value="${param.score}" var="score"/>
<c:choose>
<c:when test="${score>90}">
你的成绩优秀
</c:when>
<c:when test="${score>80}">
你的成绩一般
</c:when>
<c:when test="${score>70}">
你的成绩可以
</c:when>
<c:when test="${score>60}">
你的成绩罪恶
</c:when>
</c:choose>

java实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<%
if (request.getParameter ("username") != null && request.getParameter ("username").equals ("saxon")) {
out.print (request.getParameter ("username") + ",欢迎你");
}

%>
<%
if (request.getParameter ("username") != null && request.getParameter ("username").equals ("saxon")) {
if (request.getParameter ("score") != null) {
String score = request.getParameter ("score");
int i = Integer.parseInt (score);
out.print ("\n");
out.print ("你的成绩是:");
switch (i / 10) {
case 9:
out.println ("good");
break;
case 8:
out.println ("better");
break;
case 7:
out.println ("Just-so-so");
break;
case 6:
out.println ("Usual");
break;
default:
out.println ("worse or in put again");
}
}
}
%>

测试二:

1
2
3
4
5
6
7
8
9
<%
ArrayList<String> str = new ArrayList<> ();
str.add ("张三");
str.add ("李四");
str.add ("王五");
str.add ("田六");
str.add ("李七");
request.setAttribute ("people",str);
%>

JSTL标签:

1
2
3
4
5
6
7
8
9
10
<!--
var:名字;
items:来源
begin:开始节点
step:下标递增的次序
end:最后一个的下标
-->
<c:forEach var="list" items="${people}" begin="0" step="2" end="5">
<c:out value="${list}"/>
</c:forEach>

Java代码:

1
2
3
4
5
<%
for (int i = 0; i <5 ; i+=2) {
out.println (str.get (i));
}
%>

通过对比我们就可以明白,标签可以做的,我们的Java语言也可以做。那么用标签的原因就是简化代码,看起来美观一些;

二、EL表达式

格式: ${}

作用:

  • 获取数据
  • 执行运算
  • 获得web执行的对象;
1
2
3
${param.score} //获得数据
${score>90} //执行运算
${param.score}//获得web对象