jsp概念
JSP全称Java Server Pages
简化的servlet设计,在html标签中嵌套Java代码,用以高效开发web应用的动态标签。
- jsp的作用:
替换显示页面部分的servlet(使用*.jsp文件替换XXXJSP.java)
jsp结构
- 网络服务器需要一个 JSP 引擎,也就是一个容器来处理 JSP 页面。容器负责截获对 JSP 页面的请求
- JSP 容器与 Web 服务器协同合作,为JSP的正常运行提供必要的运行环境和其他服务,并且能够正确识别专属于 JSP 网页的特殊元素。
- jsp处理流程
- 详细解析图
- 大体图(概括)
jsp的生命周期
-
以下是JSP生命周期中所走过的几个阶段:
编译阶段: servlet容器编译servlet源文件,生成servlet类,分为三个步骤 --------------------------------------------------- * 解析JSP文件。 * 将JSP文件转为servlet。 * 编译servlet。 初始化阶段: 加载与JSP对应的servlet类,创建其实例,并调用它的初始化方法 --------------------------------------------------- * 容器载入JSP文件后,它会在为请求提供任何服务前调用jspInit()方法。 * 如果您需要执行自定义的JSP初始化任务,复写jspInit()方法就行了 执行阶段: 调用与JSP对应的servlet实例的服务方法 --------------------------------------------------- * 当JSP网页完成初始化后,JSP引擎将会调用_jspService()方法。 销毁阶段: 调用与JSP对应的servlet实例的销毁方法,然后销毁servlet实例 --------------------------------------------------- * jspDestroy()方法在JSP中等价于servlet中的销毁方法
-
生命周期的代码练习
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>life</title>
</head>
<body>
<%!
private int initVar=0;
private int serviceVar=0;
private int destoryVar=0;
%>
<%!
//初始化的方法
public void jspInit(){
initVar++;
System.out.println("jspInit(): JSP被初始化了"+initVar+"次");
}
// 销毁jsp的方法
public void jspDestory(){
destoryVar++;
System.out.println("jspDestroy(): JSP被销毁了"+destoryVar+"次");
}
%>
<%
serviceVar++;
System.out.println("_jspService(): JSP共响应了"+serviceVar+"次请求");
String content1="初始化次数 : "+initVar;
String content2="响应客户请求次数 : "+serviceVar;
String content3="销毁次数 : "+destoryVar;
%>
<h1>菜鸟教程jsp测试实例</h1>
<p><%=content1 %></p>
<p><%=content2 %></p>
<p><%=content3 %></p>
</body>
</html>
- 第一次请求
- 第二次访问
jsp的语法
- 脚本程序
脚本程序可以包含任意量的Java语句、变量、方法或表达式,只要它们在脚本语言中是有效的。
- 脚本程序的格式
<% 代码片段 %>
- or
<jsp:scriptlet>
代码片段
</jsp:scriptlet>
任何文本、HTML标签、JSP元素必须写在脚本程序的外面。
- 中文编码问题
- 如果我们要在页面正常显示中文,我们需要在 JSP 文件头部添加以下代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
- JSP注释
- <%-- 该部分注释在网页中不会被显示–%>
- 快捷键:单行注释 Ctrl+/
- 多行注释: Shift+Ctrl+/
- jsp的指令
- jsp 行为
- jsp的格式
<jsp:action_name attribute="value" />
- jsp中的控制流语句
- 判断语句的代码演示
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<%
int day =3;
%>
</head>
<body>
<h3>IF...ELSE 实例</h3>
<%
if(day> 1& day<7){
%>
<h4>今天是周内</h4>
<%}else {
%>
<h4>今天不是周内</h4>
<%
}
%>
</body>
</html>
- switch case
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%! int day = 3; %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
<%
int day=3;
%>
</head>
<body>
<h3>SWITCH...CASE 实例</h3>
<%
switch(day) {
case 0:
out.println("星期天");
break;
case 1:
out.println("星期一");
break;
case 2:
out.println("星期二");
break;
case 3:
out.println("星期三");
break;
case 4:
out.println("星期四");
break;
case 5:
out.println("星期五");
break;
default:
out.println("星期六");
}
%>
</body>
</html>
- 循环语句
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>for循坏练习</title>
<%
int a;
%>
</head>
<body>
<h3>for循环的练习</h3>
<%
for (a=1;a<=5;a++){
out.println(a);
}%>
</body>
</html>
- while循环
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%! int fontSize=0; %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<h3>While 循环实例</h3>
<%while ( fontSize <= 3){ %>
<font color="green" size="<%= fontSize %>">
菜鸟教程
</font><br />
<%fontSize++;%>
<%}%>
</body>
</html>
jsp 的隐式对象
JSP隐式对象是JSP容器为每个页面提供的Java对象,开发者可以直接使用它们而不用显式声明。
JSP隐式对象也被称为预定义变量。
-
request对象
每当客户端请求一个JSP页面时,JSP引擎就会制造一个新的request对象来代表这个请求。
-
response对象
当服务器创建request对象时会同时创建用于响应这个客户端的response对象。 response对象也定义了处理HTTP头模块的接口。 通过这个对象,开发者们可以添加新的cookies,时间戳,HTTP状态码等等。
-
out对象
用来在response对象中写入内容。是一个输出流
-
session对象
和Java Servlets中的session对象有一样的行为。 session对象用来跟踪在各个客户端请求间的会话。
-
application对象
这个对象在JSP页面的整个生命周期中都代表着这个JSP页面。 这个对象在JSP页面初始化时被 创建,随着jspDestroy()方法的调用而被移除。 通过向application中添加属性,则所有组成您web应用的JSP文件都能访问到这些属性。
-
config对象
这个对象允许开发者访问Servlet或者JSP引擎的初始化参数,比如文件路径等。
-
pageContext 对象
pageContext对象是javax.servlet.jsp.PageContext 类的实例,用来代表整个JSP页面。 这个对象主要用来访问页面信息,同时过滤掉大部分实现细节。 这个对象存储了request对象和response对象的引用。 application对象,config对象,session对象,out对象可以通过访问这个对象的属性来导出。 pageContext对象也包含了传给JSP页面的指令信息, 包括缓存信息,ErrorPage URL,页面scope等。 PageContext类定义了一些字段, 包括PAGE_SCOPE,REQUEST_SCOPE,SESSION_SCOPE, APPLICATION_SCOPE。 它也提供了40余种方法,有一半继承自javax.servlet.jsp.JspContext 类。 其中一个重要的方法就是 removeAttribute(),它可接受一个或两个参数。 比如,pageContext.removeAttribute("attrName") 移除四个scope中相关属性, 但是下面这种方法只移除特定 scope 中的相关属性:
-
page 对象
这个对象就是页面实例的引用。它可以被看做是整个JSP页面的代表。 page 对象就是this对象的同义词。
-
exception 对象
exception 对象包装了从先前页面中抛出的异常信息。 它通常被用来产生对出错条件的适当响应。
-
jsp动作属性
- jsp:include动作元素
jsp:include动作元素用来包含静态和动态的文件。该动作把指定文件插入正在生成的页面
而这里的jsp:include动作不同,插入文件的时间是在页面被请求的时候。
<jsp:include page="相对 URL 地址" flush="true" />
- 代码实现案里
- date.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>date</title>
</head>
<body>
<p>
今天是你的生日:<%= (new java.util.Date()).toLocaleString() %>
</p>
</body>
</html>
- main.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>main</title>
</head>
<body>
<h2>include实例</h2>
<jsp:include page="07-date.jsp" flush="true"/>
</body>
</html>
2. jsp:useBean动作元素
用来加载一个将在JSP页面中使用的JavaBean
在类载入后,我们既可以通过 jsp:setProperty 和 jsp:getProperty 动作来修改和检索bean的属性。
<jsp:useBean id="name" class="package.class" />
- jsp:setProperty动作元素
jsp:setProperty用来设置已经实例化的Bean对象的属性,
- jsp:getProperty动作元素
jsp:getProperty动作提取指定Bean属性的值,转换成字符串,然后输出
- 2,3,4相关的案例
- 先创建一个bean
package com.lty.pojo;
public class Student {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- 测试的jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Title</title>
</head>
<body>
<h3>jsp:useBean动作元素案例</h3>
<jsp:useBean id="student" class="com.lty.pojo.Student"/>
<%--设置学生的姓名--%>
<jsp:setProperty name="student" property="name" value="lty"/>
<p>输出学生的信息</p>
<%--获取学生的姓名--%>
<jsp:getProperty name="student" property="name"/>
</body>
</html>
5. jsp:forward 动作元素
jsp:forward动作把请求转到另外的页面。jsp:forward标记只有一个属性page。
page属性包含的是一个相对URL。page的值既可以直接给出,也可以在请求的时候动态计算,可以是一个JSP页面或者一个 Java Servlet.
<jsp:forward page="相对 URL 地址" />
- 案例
- date页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>date</title>
</head>
<body>
<p>
今天是你的生日:<%= (new java.util.Date()).toLocaleString() %>
</p>
</body>
</html>
- main页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>main</title>
</head>
<body>
<%--<h2>include实例</h2>
<jsp:include page="07-date.jsp" flush="true"/>--%>
<h2>forward动作实例</h2>
<jsp:forward page="07-date.jsp"/>
</body>
</html>
- 输出结果
访问的是main页面,因为有<jsp:forward page=“07-date.jsp”/>,
所以最后我们看到的是date页面
如下图所示
-
jsp:plugin动作元素
jsp:plugin动作用来根据浏览器的类型,插入通过Java插件 运行Java Applet所必需的OBJECT或EMBED元素。 如果需要的插件不存在,它会下载插件,然后执行Java组件。 Java组件可以是一个applet或一个JavaBean。 plugin动作有多个对应HTML元素的属性用于格式化Java 组件。param元素可用于向Applet 或 Bean 传递参数。
<jsp:plugin type="applet" codebase="dirname" code="MyApplet.class"
width="60" height="80">
<jsp:param name="fontcolor" value="red" />
<jsp:param name="background" value="black" />
<jsp:fallback>
Unable to initialize Java Plugin
</jsp:fallback>
</jsp:plugin>
- jsp:element 、 jsp:attribute、 jsp:body动作元素
jsp:element 、 jsp:attribute、 jsp:body动作元素动态定义XML元素。动态是非常重要的,这就意味着XML元素在编译时是动态生成的而非静态。
- 案例
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<jsp:element name="xmlElement">
<jsp:attribute name="xmlElementAttr">
属性值
</jsp:attribute>
<jsp:body>
XML 元素的主体
</jsp:body>
</jsp:element>
</body>
</html>
- jsp:text动作元素
元素允许在JSP页面和文档中使用写入文本的模板,语法格式如下:
<jsp:text>模板数据</jsp:text>
jsp客户端请求
https://www.runoob.com/jsp/jsp-client-request.html
jsp服务器响应
https://www.runoob.com/jsp/jsp-server-response.html
jsp的表单处理
我们在浏览网页的时候,经常需要向服务器提交信息,并让后台程序处理。浏览器中使用 GET 和 POST 方法向服务器提交数据。
- get方法
GET方法将请求的编码信息添加在网址后面,网址与编码信息通过"?"号分隔。如下所示:
http://www.runoob.com/hello?key1=value1&key2=value2
GET方法是浏览器默认传递参数的方法,一些敏感信息,如密码等建议不使用GET方法。
用get时,传输数据的大小有限制 (注意不是参数的个数有限制),最大为1024字节。
- post方法
一些敏感信息,如密码等我们可以通过POST方法传递,POST提交数据是隐式的。
POST提交数据是不可见的,GET是通过在url里面传递的(可以看一下你浏览器的地址栏)。
JSP使用getParameter()来获得传递的参数,getInputStream()方法用来处理客户端的二进制数据流的请求。
- jsp读取表单的信息
- getParameter(): 使用 request.getParameter() 方法来获取表单参数的值。
- getParameterValues(): 获得如checkbox类(名字相同,但值有多个)的数据。 接收数组变量 ,如checkbox类型
- getParameterNames():该方法可以取得所有变量的名称,该方法返回一个 Enumeration。
- getInputStream():调用此方法来读取来自客户端的二进制数据流。
- 案例
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<html>
<head>
<title>表单接受信息</title>
</head>
<body>
<h3>使用get方法读取表单的信息</h3>
<ul>
<li>
<p>
<b>站点名:</b>
<%= request.getParameter("name")%>
</p>
</li>
<li>
<p>
<b>网址:</b>
<%= request.getParameter("url")%>
</p>
</li>
</ul>
</body>
</html>
- 当访问如下路径的时候。会出现下以效果
http://localhost:8080/web_jsp/11-get.jsp?name=%E8%8F%9C%E9%B8%9F%E6%95%99%E7%A8%8B&url=http://ww.runoob.com
- 编写一个html页面来传入访问参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="11-get.jsp" method="get">
站点名:<input type="text" name="name">
网址名:<input type="text" name="url">
<input type="submit" value="提交">
</form>
</body>
</html>
- 当访问http://localhost:8080/web_jsp/mian%E8%AE%BF%E9%97%AEget%E9%A1%B5%E9%9D%A2.html
时,界面如下
- 当输入参数之后提交表单结果如下
- 使用表单的 POST 方法实例
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<meta charset="utf-8">
</head>
<body>
<h1>使用 POST 方法读取数据</h1>
<ul>
<li><p><b>站点名:</b>
<%
// 解决中文乱码的问题
String name = new String((request.getParameter("name")).getBytes("ISO-8859-1"),"UTF-8");
%>
<%=name%>
</p></li>
<li><p><b>网址:</b>
<%= request.getParameter("url")%>
</p></li>
</ul>
</body>
</html>
- post测试
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>测试post</title>
</head>
<body>
<form action="12-post.jsp" method="POST">
站点名: <input type="text" name="name">
<br />
网址: <input type="text" name="url" />
<input type="submit" value="提交" />
</form>
</body>
</html>
- 传递 Checkbox 数据到JSP程序
- html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="13-checkedPost.jsp" method="post">
<input type="checkbox" name="google" checked="checked">google
<input type="checkbox" name="lty">lty
<input type="checkbox" name="zly" checked="checked">zly
<input type="submit" value="选择">
</form>
</body>
</html>
- jsp页面
<%--
Created by IntelliJ IDEA.
User: admin
Date: 2020/12/22
Time: 14:52
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>
<h3>从复选框中选择数据</h3>
<ul>
<li>
<p>
<b>google是否选中</b>
<%=request.getParameter("google")%>
</p>
</li>
<li>
<p>
<b>lty是否选中</b>
<%=request.getParameter("lty")%>
</p>
</li>
<li>
<p>
<b>zly是否选中</b>
<%=request.getParameter("zly")%>
</p>
</li>
</ul>
</body>
</html>
运行结果
- 读取表单的所有数据并且遍历
<%
Enumeration paramNames = request.getParameterNames();
while(paramNames.hasMoreElements()) {
String paramName = (String)paramNames.nextElement();
out.print("<tr><td>" + paramName + "</td>\n");
String paramValue = request.getParameter(paramName);
out.println("<td> " + paramValue + "</td></tr>\n");
}
%>
jsp过滤器[存在疑难问题]
-
javax.servlet.Filter 接口定义了三个方法:
1. public void doFilter (ServletRequest, ServletResponse, FilterChain) * 该方法完成实际的过滤操作,当客户端的请求与过滤器设置的 URL 匹配时, * Servlet 容器将先调用过滤器的 doFilter 方法。FilterChain 用于访问后续过滤器。 2. public void init(FilterConfig filterConfig) * 初始化 3. public void destroy() * 删除拦截器
JSP Cookie 处理
Cookie 是存储在客户机的文本文件,它们保存了大量轨迹信息。在 Servlet 技术基础上,JSP 显然能够提供对 HTTP cookie 的支持
- JSP Cookie 处理需要对中文进行编码与解码,方法如下:
String str = java.net.URLEncoder.encode(“中文”, “UTF-8”); //编码
String str = java.net.URLDecoder.decode(“编码后的字符串”,“UTF-8”); // 解码
Cookie 通常在 HTTP 信息头中设置(虽然 JavaScript 能够直接在浏览器中设置 cookie)。在 JSP 中,设置一个 cookie 需要发送如下的信息头给服务器:
HTTP/1.1 200 OK
Date: Fri, 04 Feb 2015 21:03:38 GMT
Server: Apache/1.3.9 (UNIX) PHP/4.0b3
Set-Cookie: name=runoob; expires=Friday, 04-Feb-17 22:03:38 GMT;
path=/; domain=runoob.com
Connection: close
Content-Type: text/html
- 使用 JSP 设置 cookie
(1)创建一个 cookie 对象: 调用 cookie 的构造函数,使用一个 cookie 名称和值做参数,它们都是字符串。
Cookie cookie = new Cookie("key","value");
- 设置有效期:调用 setMaxAge() 函数表明 cookie 在多长时间(以秒为单位)内有效。下面的操作将有效期设为了 24 小时。
cookie.setMaxAge(60*60*24);
(3) 将 cookie 发送至 HTTP 响应头中:调用 response.addCookie() 函数来向 HTTP 响应头中添加 cookie。
response.addCookie(cookie);
- 案例
<%
// 编码,解决中文乱码
String str = URLEncoder.encode(request.getParameter("name"),"utf-8");
// 设置 name 和 url cookie
Cookie name = new Cookie("name",
str);
Cookie url = new Cookie("url",
request.getParameter("url"));
// 设置cookie过期时间为24小时。
name.setMaxAge(60*60*24);
url.setMaxAge(60*60*24);
// 在响应头部添加cookie
response.addCookie( name );
response.addCookie( url );
%>
- 使用 JSP 读取 Cookie
调用 request.getCookies() 方法来获得一个 javax.servlet.http.Cookie 对象的数组,然后遍历这个数组,使用 getName() 方法和 getValue() 方法来获取每一个 cookie 的名称和值。
- 案例
<%
Cookie cookie = null;
Cookie[] cookies = null;
// 获取 cookies 的数据,是一个数组
cookies = request.getCookies();
if( cookies != null ){
out.println("<h2> 查找 Cookie 名与值</h2>");
for (int i = 0; i < cookies.length; i++){
cookie = cookies[i];
out.print("参数名 : " + cookie.getName());
out.print("<br>");
out.print("参数值: " + URLDecoder.decode(cookie.getValue(), "utf-8") +" <br>");
out.print("------------------------------------<br>");
}
}else{
out.println("<h2>没有发现 Cookie</h2>");
}
%>
- 使用 JSP 删除 cookie
- 获取一个已经存在的 cookie 然后存储在 Cookie 对象中。
- 将 cookie 的有效期设置为 0。
- 将这个 cookie 重新添加进响应头中。
JSP Session
HttpSession接口来识别一个用户,存储这个用户的所有访问信息。
<%
// 获取session创建时间
Date createTime = new Date(session.getCreationTime());
// 获取最后访问页面的时间
Date lastAccessTime = new Date(session.getLastAccessedTime());
String title = "再次访问菜鸟教程实例";
Integer visitCount = new Integer(0);
String visitCountKey = new String("visitCount");
String userIDKey = new String("userID");
String userID = new String("ABCD");
// 检测网页是否有新的访问用户
if (session.isNew()){
title = "访问菜鸟教程实例";
session.setAttribute(userIDKey, userID);
session.setAttribute(visitCountKey, visitCount);
} else {
visitCount = (Integer)session.getAttribute(visitCountKey);
visitCount += 1;
userID = (String)session.getAttribute(userIDKey);
session.setAttribute(visitCountKey, visitCount);
}
%>
-
删除Session数据
移除一个特定的属性: 调用public void removeAttribute(String name) 方法来移除指定的属性。 删除整个会话: 调用public void invalidate() 方法来使整个session无效。
JSP 连接数据库
- 链接数据库
<sql:setDataSource var="snapshot"
driver="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/RUNOOB?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
user="root"
password="12345"/>
- select
<sql:setDataSource var="snapshot" driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/RUNOOB?useUnicode=true&characterEncoding=utf-8"
user="root" password="123456"/>
<sql:query dataSource="${snapshot}" var="result">
SELECT * from websites;
</sql:query>