JavaWeb-5、JSP
jsp技術雖然現在使用的已經非常少了,但畢竟java知識是一個體系,還是可以稍微瞭解瞭解
一、概述
JSP全稱Java Server Pages,是一種動態網頁開發技術。它使用JSP標籤在HTML網頁中插入Java代碼。
如果還是使用傳統的html開發的話,所有用戶看到的界面將會一模一樣,網頁就很難從數據庫或者後臺拿到數據以針對不同用戶進行顯示。
但是有了jsp技術,通過內嵌的java代碼,就可以實現動態網頁開發!
JSP是Java EE不可或缺的一部分,是一個完整的企業級應用平臺。
jsp的優勢:
- 與ASP相比:JSP有兩大優勢。首先,動態部分用Java編寫,而不是VB或其他MS專用語言,所以更加強大與易用。第二點就是JSP易於移植到非MS平臺上。
- 與純 Servlet 相比:JSP可以很方便的編寫或者修改HTML網頁而不用去面對大量的println語句。
- 與SSI相比:SSI無法使用表單數據、無法進行數據庫鏈接。
- 與JavaScript相比:雖然JavaScript可以在客戶端動態生成HTML,但是很難與服務器交互,因此不能提供複雜的服務,比如訪問數據庫和圖像處理等等。
- 與靜態HTML相比:靜態HTML不包含動態信息。
二、原理
我們學一個東西,如果能究其底層,究其原理,那我們必然會更加理解這門技術,我們現在也來看看jsp到底是何方神聖。
在我們每個人的tomcat文件夾中,都會有work這麼個文件夾,我們點進去看看。這裏我們進到idea中的tomcat中,隨便選一個項目:
一直點到最裏頭髮現居然有個jsp文件夾!
快康康!
裏面居然是jsp的java文件和編譯後的class文件,到底咋回事兒啊!快康康java的源碼。
我們發現這玩意繼承了這個類,往下翻翻我們發現了一個驚天的祕密!!
這底下不就是我項目中jsp文件裏那幾段簡單的代碼麼!這不是應該是在servlet裏寫的麼?
原來這jsp就是個servlet類啊!
然後我們再點進去其他項目中的jsp類,發現僅僅是中間out.write輸出的前端那幾行頁面有所不同,其他都一樣啊!
所以我們可以把具體流程歸爲以下:
1、我們去服務器端請求,服務端找到jsp文件
2、將jsp轉換爲java文件
3、編譯java文件,使其轉換爲class文件
4、把class文件回傳給服務器
5、用戶訪問class文件(其實就是個servlet!)
三、jsp基礎語法和指令
我們來寫寫看看吧
先導包!
這裏我們需要servlet、jsp、jstl以及taglibs的包
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
然後我們編寫一個jsp文件看看
<%@ page import="java.util.Date" %>
<html>
<body>
<%--註釋!!!!--%>
<%--<%=>標籤可以取相關變量的值--%>
<%=new Date()%>
<%--<% %>標籤可以執行相關的java代碼!--%>
<%
for (int i = 0; i < 5; i++) {
out.print("<h1>dirtyLily,handsome!!");
}
%>
<%--<%! %>標籤可以在類外定義全局變量!--%>
<%!
int m =55;
static{
System.out.println("方法在執行!");
}
%>
</body>
</html>
最後執行出來!
idea中也正常打印了相關的語句
我們進入他的.java文件看看
我們發現!中的語句在類一開始就已經被執行!其他語句則是在下面_jspService方法中執行。
其實就是把我們在jsp中寫的java代碼在後臺搞出來,嵌入進去。沒啥稀奇的!
我們當然也可以搞點騷操作!
<%
for (int i = 0; i < 5; i++) {%>
<button type="button">真的帥!</button>
<%
}
%>
hhh,這種騷操作其實挺多的,大家可以自己試試。
之後來聊聊jsp的相關指令吧。
其主要包含以下三種指令標籤:
我們來用inculde標籤搞個header玩兒玩兒!
我們在jsp中寫這麼行代碼
<%@include file="header.jsp"%>
自己寫一個簡單的header.jsp,運行下!
這就被包含進來了!
在jsp中還存在以下幾種行爲,
我們還是拿include來舉例,
<jsp:include page="header.jsp"></jsp:include>
在jsp中添加這行代碼,運行下。
發現和之前那種寫法出來的結果是一樣的,但是他們之間有什麼不同呢?
打開class文件看一下。
我們發現,使用第一種<%@include寫法的只是將兩個界面合二爲一,俄日下面jsp:include這種寫法則是引用header.jsp這個界面!
四、傳值方法及相關作用域
jsp支持以下九大對象
- request 傳值的
- responce
- out 把東西輸出到頁面
- session 傳值的
- application 傳值的,是servletcontext
- config 裏面的一些配置文件,是ServletConfig
- pageContext 傳值的
- page 類似java中的this
- Exception 代表頁面中的異常對象
我們現在來試試其中四個傳值的對象
首先還是創建好個jsp頁面。
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/6/22
Time: 12:47
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>
<%
pageContext.setAttribute("name1","zjj1");
request.setAttribute("name2","zjj2");
session.setAttribute("name3","zjj3");
application.setAttribute("name4","zjj4");
%>
<%
String name1 = (String)pageContext.findAttribute("name1");
String name2 = (String)pageContext.findAttribute("name1");
String name3 = (String)pageContext.findAttribute("name1");
String name4= (String)pageContext.findAttribute("name1");
%>
<h1>${name1}</h1>
<h1>${name2}</h1>
<h1>${name3}</h1>
<h1>${name4}</h1>
<%--這裏讓其取一個不存在的值--%>
</body>
</html>
這裏我們都在當頁取一個值看看能不能取到。然後這裏我們使用EL表達式進行取值,EL表達式的主要語法是${表達式的值}。
發現相關的值都可以取到,最後一個不存在的值直接不顯示!
如果我們使用傳統的取值方法則會顯示null。
然後我們再新建一個jsp頁面,看看還能不能取值?
<%
String name1 = (String)pageContext.findAttribute("name1");
String name2 = (String)pageContext.findAttribute("name2");
String name3 = (String)pageContext.findAttribute("name3");
String name4= (String)pageContext.findAttribute("name4");
%>
<h1>${name1}</h1>
<h1>${name2}</h1>
<h1>${name3}</h1>
<h1>${name4}</h1>
我們發現j2只能取到name3和name4了
這是爲啥啊!
我們網上查資料發現了他們的作用域原來非常不同!
- pageContext傳值只在當前頁面有效,出了頁面就涼涼
- request傳值在當前請求有效,轉發之後也ok,出了請求就不行了
- session傳值在當前會話中有效,關了瀏覽器就不行了
- application在當前服務器中有效,服務器一關就不行了
這裏我們j1裏再加一個轉發操作。
pageContext.forward("j2.jsp");
運行後我們發現轉發後name2的值也顯示出來了,轉發後的url地址也是不變的
使用場景:
根據小狂神的總結,request主要是用作傳遞用戶用完就不用的那種值,比如說新聞啥的,session主要是存儲用戶用完還有點用的值,比如說購物車之類的,還有就是application主要是用作統計數據,聊天數據等需要存到數據庫裏的值的存儲。
五、JSP、JSTL、EL表達式
EL表達式 ${}
我們要使用相關表達式首先需要導包
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jstl-impl</artifactId>
<version>1.2</version>
</dependency>
el表達式主要可以做以下的事情
- 獲取數據
- 執行運算
- 獲取web開發常用運算
具體例子將配合下面jstl一起實現
jsp標籤
在之前我們曾經舉過jsp include標籤的相關例子,這裏jsp標籤主要分爲下面幾種
這裏再給大家舉一個forward標籤的例子
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--這裏具體url可以視爲http://localhost:8080/basic/jsp1.jsp?username=zjj&password=zhx--%>
<jsp:forward page="jsp2.jsp">
<jsp:param name="username" value="zjj"/>
<jsp:param name="password" value="zhx"/>
</jsp:forward>
</body>
</html>
最後它可以跳轉到jsp2.jsp,輸出我們頁面中的內容。
jstl標籤
根據JSTL標籤所提供的功能,可以將其分爲5個類別。
- 核心標籤
- 格式化標籤
- SQL 標籤
- XML 標籤
- JSTL 函數
在這裏我們主要掌握一部分核心標籤即可
這裏我們注意下,要首先把項目中jstl和standard兩個jar包複製到tomcat的lib目錄下
if標籤
這裏我們寫一個小例子
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/6/22
Time: 14:03
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="coreif.jsp" method="post">
<%-- EL表達式可以通過param.參數名的形式獲取表單中的參數值--%>
<input name="username" type="text" value="${param.username}" >
<input type="submit" value="提交" > 提交
</form>
<%-- test中寫條件--%>
<c:if test="${ param.username=='adimin'}">
<h1>歡迎您,管理員</h1>
</c:if>
</body>
</html>
輸入admin執行下!發現顯示完全沒啥問題
set choose when標籤
其實set主要用處就是設置變量值
choose標籤一般搭配when標籤使用,其效果與switch標籤很像,主要語法格式爲
<c:choose>
<c:when test="<boolean>">
...
</c:when>
<c:when test="<boolean>">
...
</c:when>
...
...
<c:otherwise>
...
</c:otherwise>
</c:choose>
來一個小例子,設置一個變量,讓下面的choose語句根據相關值顯示不同信息
<html>
<head>
<title>Title</title>
</head>
<body>
<c:set var="score" value="85"></c:set>
<c:choose>
<c:when test="${score>=85}">
<h1>您真優秀</h1>
</c:when>
<c:when test="${score>=75}">
<h1>您真良好</h1>
</c:when>
<c:when test="${score>=60}">
<h1>您真合格</h1>
</c:when>
<c:when test="${score<60}">
<h1>您不行</h1>
</c:when>
</c:choose>
</body>
</html>
foreach標籤
foreach標籤封裝了Java中的for,while,do-while循環。平常我們經常在開發時使用其遍歷集合。
還是用個小例子說話
<%@ page import="java.util.ArrayList" %><%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/6/22
Time: 14:45
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--先創建一個集合--%>
<%
ArrayList<String> man = new ArrayList<>();
man.add("zjj");
man.add("zhx");
man.add("lj");
man.add("kl");
man.add("marbury");
request.setAttribute("list",man);
%>
<%--這裏的意思是遍歷一個叫list的東西,從index爲1開始,到index爲4結束,步長爲2--%>
<c:forEach var="person" items="${list}" begin="1" end="4" step="2">
<h1>${person}</h1>
</c:forEach>
</body>
</html>
我們var中定義的每次循環取到的值,可以在下面使用el表達式直接取出,最後輸出結果爲:
其他的表達式各位可以自己在網上找找資源練練手,這裏就不贅述啦!
六、JAVA Bean
在jsp標籤中有三個使我們平常經常使用的,他們可以拿到、設置相關對象的值。他們就是usebean 、getproperty和setproperty這哥仨。我們還是通過一個小例子演示下如何使用吧!
首先先寫一個類,裏面包含一些屬性,設置好其中的getter和setter方法。
public class People {
private String name;
private int age;
private String hobby;
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 getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public People() {
}
public People(String name, int age, String hobby) {
this.name = name;
this.age = age;
this.hobby = hobby;
}
}
jsp代碼如下
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--<%@ page import="com.zjj.pojo.People" %>--%>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--獲取相關bean,其id設置爲people,是其唯一標誌符--%>
<jsp:useBean id="people" class="com.zjj.pojo.People" scope="page"/>
<%--設置id爲people中相關屬性的值 --%>
<jsp:setProperty name="people" property="name" value="小俊男"></jsp:setProperty>
<jsp:setProperty name="people" property="age" value="21"></jsp:setProperty>
<jsp:setProperty name="people" property="hobby" value="學java"></jsp:setProperty>
<h1>名字是:<jsp:getProperty name="people" property="name"/></h1>
<h1>年齡是:<jsp:getProperty name="people" property="age"/></h1>
<h1>愛好是:<jsp:getProperty name="people" property="hobby"/></h1>
<h1></h1>
</body>
</html>
最後在頁面中可以拿到相關的值!
總之,jsp雖然現在已經過時了,但是大家還是要稍作了解,畢竟有的公司的項目技術沒有重構,依然在使用jsp作爲相關技術。