Java第三十二天(JSP & EL & JSTL)
jsp
Java Server Page
- 什麼是jsp
從使用者角度看待 ,就是是一個網頁 , 從程式設計師角度看待 , 其實是一個java類, 它繼承了servlet,所以可以直接說jsp 就是一個Servlet.
- 為什麼會有jsp?
html 多數情況下用來顯示靜態內容 , 一成不變的。 但是有時候我們需要在網頁上顯示一些動態資料, 比如: 查詢所有的學生資訊, 根據姓名去查詢具體某個學生。 這些動作都需要去查詢資料庫,然後在網頁上顯示。 html是不支援寫java程式碼 , jsp裡面可以寫java程式碼。
指令寫法-三個指令
<%@ 指令名字 %>
1.page指令
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
- language
表明jsp頁面中可以寫java程式碼
- contentType
其實即使說這個檔案是什麼型別,告訴瀏覽器我是什麼內容型別,以及使用什麼編碼
contentType="text/html; charset=UTF-8"
text/html MIMEType 這是一個文字,html網頁
-
pageEncoding jsp內容編碼
-
extends 用於指定jsp翻譯成java檔案後,繼承的父類是誰,一般預設不用改。
-
import 導包使用的,一般不用手寫。
-
session
值可選的有true or false .
用於控制在這個jsp頁面裡面,能夠直接使用session物件。
具體的區別是,請看翻譯後的java檔案 如果該值是true , 那麼在程式碼裡面會有getSession()的呼叫,如果是false : 那麼就不會有該方法呼叫,也就是沒有session物件了。在頁面上自然也就不能使用session了。
- errorPage
指的是錯誤的頁面, 值需要給錯誤的頁面路徑
- isErrorPage
上面的errorPage 用於指定錯誤的時候跑到哪一個頁面去。 那麼這個isErroPage , 就是宣告某一個頁面到底是不是錯誤的頁面true/false。
2.include指令
包含另外一個jsp的內容進來。
<%@ include file="other02.jsp"%>
- 背後細節:
把另外一個頁面的所有內容拿過來一起輸出。 所有的標籤元素都包含進來。
3.taglib指令
<%@ taglib prefix="" uri=""%>
uri: 標籤庫路徑
prefix : 標籤庫的別名
##JSP 動作標籤
<jsp:include page=""></jsp:include>
<jsp:param value="" name=""/>
<jsp:forward page=""></jsp:forward>
jsp:include
<jsp:include page="other02.jsp"></jsp:include>
包含指定的頁面, 這裡是動態包含。 也就是不把包含的頁面所有元素標籤全部拿過來輸出,而是把它的執行結果拿過來。
jsp:forward
<jsp:forward page=""></jsp:forward>
前往哪一個頁面,等同於請求轉發。
<%
//請求轉發
request.getRequestDispatcher("other02.jsp").forward(request, response);
%>
jsp:param
意思是: 在包含某個頁面的時候,或者在跳轉某個頁面的時候,加入這個引數。
<jsp:forward page="other02.jsp">
<jsp:param value="beijing" name="address"/>
</jsp:forward>
在other02.jsp中獲取引數
<br>收到的引數是:<br>
<%= request.getParameter("address")%>
##JSP內建物件(重點)
所謂內建物件,就是我們可以直接在jsp頁面中使用這些物件。 不用建立。
- pageContext
- request
- session
- application
以上4個是作用域物件 ,
* 作用域物件(四個)
表示這些物件可以存值,他們的取值範圍有限定。 setAttribute 和 getAttribute
使用作用域來儲存資料<br>
<%
pageContext.setAttribute("name", "page");
request.setAttribute("name", "request");
session.setAttribute("name", "session");
application.setAttribute("name", "application");
%>
取出四個作用域中的值<br>
<%=pageContext.getAttribute("name")%>
<%=request.getAttribute("name")%>
<%=session.getAttribute("name")%>
<%=application.getAttribute("name")%>
作用域範圍大小:
pageContext -- request --- session -- application
四個作用域的區別
- pageContext 【PageContext】
作用域僅限於當前的頁面。跳到其他介面就會顯示null
還可以獲取到其他八個內建物件。
- request 【HttpServletRequest】
作用域僅限於一次請求, 只要伺服器對該請求做出了響應。 這個域中存的值就沒有了。
在請求轉發的介面中可以顯示,重定向中就是null了
- session 【HttpSession】
作用域限於一次會話(多次請求與響應) 當中。
- application 【ServletContext】
整個工程都可以訪問, 伺服器關閉後就不能訪問了。
輸出物件(2個)
- out 【JspWriter】
- response 【HttpServletResponse】 其實jsp<body>中的內容也是out寫的,reponse輸出先建立一個流物件再寫入,要優先於out,因為out寫的內容要先放到response的緩衝區,所以直接用response輸出的內容先顯示
其他(3個)
- exception 【Throwable】
- page 【Object】 ---就是這個jsp翻譯成的java類的例項物件
- config 【ServletConfig】
EL表示式
是為了簡化咱們的jsp程式碼,具體一點就是為了簡化在jsp裡面寫的那些java程式碼。
- 寫法格式
${表示式 }
如果從作用域中取值,會先從小的作用域開始取,如果沒有,就往下一個作用域取。 一直把四個作用域取完都沒有, 就沒有顯示。
主要用於取值
1. 取出4個作用域中存放的值。
<%
pageContext.setAttribute("name", "page");
request.setAttribute("name", "request");
session.setAttribute("name", "session");
application.setAttribute("name", "application");
%>
按普通手段取值<br>
<%= pageContext.getAttribute("name")%>
<%= request.getAttribute("name")%>
<%= session.getAttribute("name")%>
<%= application.getAttribute("name")%>
<br>使用EL表示式取出作用域中的值<br>
${ pageScope.name }
${ requestScope.name }
${ sessionScope.name }
${ applicationScope.name }
2. 如果域中所存的是陣列
<%
String [] a = {"aa","bb","cc","dd"};
pageContext.setAttribute("array", a);
%>
使用EL表示式取出作用域中陣列的值<br>
${array[0] } , ${array[1] },${array[2] },${array[3] }
3. 如果域中存的是集合
使用EL表示式取出作用域中集合的值<br>
${li[0] } , ${li[1] },${li[2] },${li[3] }
<br>-------------Map資料----------------<br>
<%
Map map = new HashMap();
map.put("name", "zhangsna");
map.put("age",18);
map.put("address","北京..");
map.put("address.aa","深圳..");
pageContext.setAttribute("map", map);
%>
4. 取出Map集合的值
<%
Map map = new HashMap();
map.put("name", "zhangsna");
map.put("age",18);
map.put("address","北京..");
map.put("address.aa","深圳..");
pageContext.setAttribute("map", map);
%>
使用EL表示式取出作用域中Map的值<br>
${map.name } , ${map.age } , ${map.address } , ${map["address.aa"] }
程式碼注意的地方:
1. 從域中取值,得先存值。
```html
<%
//pageContext.setAttribute("name", "zhangsan");
session.setAttribute("name", "lisi...");
%>
<br>直接指定說了,到這個作用域裡面去找這個name<br>
${ pageScope.name }
<br>//先從page裡面找,沒有去request找,去session,去application <br>
${ name }
<br>指定從session中取值<br>
${ sessionScope.name }
```
2. 取值方式
如果這份值是有下標的,那麼直接使用[]
<%
String [] array = {"aa","bb","cc"}
session.setAttribute("array",array);
%>
${ array[1] } --> 這裡array說的是attribute的name
如果沒有下標, 直接使用 .的方式去取
<%
User user = new User("zhangsan",18);
session.setAttribute("u", user);
%>
${ u.name } , ${ u.age }
一般使用EL表示式,用的比較多的,都是從一個物件中取出它的屬性值,比如取出某一個學生的姓名。
EL表示式 的11個內建物件。
${ 物件名.成員 }
內建物件(11個)
- pageContext
作用域相關物件
- pageScope
- requestScope
- sessionScope
- applicationScope
頭資訊相關物件
- header
- headerValues
引數資訊相關物件
- param
- paramValues
- cookie
全域性初始化引數
- initParam
JSTL
全稱 : JSP Standard Tag Library jsp標準標籤庫
簡化jsp的程式碼編寫。 替換 <%%> 寫法。 一般與EL表示式配合
使用
-
匯入jar檔案到工程的WebContent/Web-Inf/lib jstl.jar standard.jar
-
在jsp頁面上,使用taglib 指令,來引入標籤庫
-
注意: 如果想支援 EL表示式,那麼引入的標籤庫必須選擇1.1的版本,1.0的版本不支援EL表示式。
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> uri: 標籤庫路徑,一般引入core核心1.1版本的 prefix : 標籤庫的別名,起個方便的名字就可以了
常用標籤
<c:set></c:set> <c:if test=""></c:if> <c:forEach></c:forEach>
* c:set
<!-- 宣告一個物件或者變數name, 物件的值 zhangsan , 儲存到作用域pageContext中(預設) , 用scope可以指定儲存到session -->
<c:set var="name" value="zhangsan" scope="session"></c:set>
<!--取值-->
${sessionScope.name }
* c:if
判斷test裡面的表示式是否滿足,如果滿足,就執行c:if標籤中的輸出 , c:if 是沒有else的。
<c:set var="age" value="18" ></c:set>
<c:if test="${ age > 26 }">
年齡大於了26歲...
</c:if>
<c:if test="${ age <= 26 }">
年齡小於了26歲...
</c:if>
------------------------------
定義一個變數名 flag 接收前面判斷表示式的值(true/false),然後存在session域中
<c:if test="${ age > 26 }" var="flag" scope="session">
年齡大於了26歲...
</c:if>
* c:forEach(用的比較多)
從1 開始遍歷到10 ,得到的結果 ,賦值給 i ,並且會儲存到page域中, step表示增幅為2,
<c:forEach begin="1" end="10" var="i" step="2">
${i }
</c:forEach>
-----------------------------------------------
<!-- items : 表示遍歷哪一個物件,注意,這裡必須寫EL表示式。
var: 遍歷出來的每一個元素用user 去接收。 -->
<c:forEach var="user" items="${list }">
${user.name } ----${user.age }
</c:forEach>
例子學生資訊管理系統
需求分析
這裡為了方便我只建立一個數據庫,裡面放一個使用者表,用於驗證登陸資訊,一個學生表用來顯示登陸成功後的學生資訊
1.建立一個登陸頁面
表單提交到LoginServlet中
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>學生登陸入口</h3>
<form action="LoginServlet" method="post">
請輸入使用者名稱:<input type="text" name="username"> 請輸入密碼:<input
type="password" name="password"> <input type="submit"
value="登陸">
</form>
</body>
</html>
2.建立資料庫和使用者表格及學生資訊表格
準備資料庫連線工作
url=jdbc:mysql://localhost:3306/user
username=root
password=321
driverClass=com.mysql.jdbc.Driver
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JDBCUtil {
static String driverClass =null;
static String url =null;
static String username =null;
static String password =null;
static {
try {
Properties prop=new Properties();
InputStream is=JDBCUtil.class.getClassLoader().getResourceAsStream("JDBC.properties");
prop.load(is);
driverClass = prop.getProperty("driverClass");
url = prop.getProperty("url");
username = prop.getProperty("username");
password = prop.getProperty("password");
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConn() {
Connection conn=null;
try {
//Class.forName(driverClass);
conn = DriverManager.getConnection(url,username,password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
public static void release(Connection conn,Statement st,ResultSet rs) {
closeConn(conn);
closeRs(rs);
closeSt(st);
}
public static void release(Connection conn,Statement st) {
closeConn(conn);
closeSt(st);
}
private static void closeConn(Connection conn) {
try {
if (conn!=null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
conn=null;
}
}
private static void closeSt(Statement st) {
try {
if (st!=null) {
st.close();
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
st=null;
}
}
private static void closeRs(ResultSet rs) {
try {
if (rs!=null) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
rs=null;
}
}
}
3.建立dao介面和實現類
定義登陸和查詢學生資訊的方法,注查詢學生方法需要返回值,直接返回泛型為學生物件的list(另外需定義一個Student類定義屬性和set、get方法)
import java.util.List;
public interface UserDao {
boolean login(String username,String password);
List<Student> findAllStu();
}
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import s20190719.jdbc.util.JDBCUtil;
import s20190719.userDao.Student;
import s20190719.userDao.UserDao;
public class UserDaoImpl implements UserDao {
@Override
public boolean login(String username, String password) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JDBCUtil.getConn();
String sql = "select * from m_user where username = ? and password = ?";
ps = conn.prepareStatement(sql);
ps.setString(1, username);
ps.setString(2, password);
rs = ps.executeQuery();
return rs.next();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.release(conn, ps, rs);
}
return false;
}
@Override
public List<Student> findAllStu() {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<Student> list = new ArrayList<Student>();
try {
conn = JDBCUtil.getConn();
String sql = "select * from m_stu";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()) {//將結果集中的資料賦值給student並且存在list中
Student student = new Student();
student.setName(rs.getString("name"));
student.setStuId(rs.getInt("stuId"));
student.setAge(rs.getInt("age"));
student.setGender(rs.getInt("gender"));
student.setAddress(rs.getString("name"));
list.add(student);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.release(conn, ps, rs);
}
return list;
}
}
4.建立LoginServlet處理登陸提交結果
先呼叫登陸方法驗證,成功則呼叫查詢學生資訊方法返回list,把list存在session,跳轉學生資訊介面
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import s20190719.userDao.Student;
import s20190719.userDao.UserDao;
import s20190719.userDao.impl.UserDaoImpl;
/**
* Servlet implementation class LoginServlet
*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
//獲取使用者登陸資訊進行驗證
String username= request.getParameter("username");
String password= request.getParameter("password");
UserDao user=new UserDaoImpl();
//判斷是否登陸成功
boolean isSuccess= user.login(username, password);
if (isSuccess) {
//驗證成功獲取學生列表存到session中
List<Student> list = user.findAllStu();
request.getSession().setAttribute("list", list);
request.getRequestDispatcher("login_success.jsp").forward(request, response);
}else {
//驗證不成功返回登陸介面
response.getWriter().write("<a href='login.jsp'>使用者名稱或者密碼錯誤,請重新登陸</a>");
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
5.顯示學生資訊的介面jsp
用標籤語句遍歷用el表示式獲取作用域session中的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>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<table border="1" width="700px">
<tr align="center">
<td>學號</td>
<td>姓名</td>
<td>年齡</td>
<td>性別</td>
<td>地址</td>
<td>操作</td>
</tr>
<!-- 登陸成功得到的學生列表,遍歷items中的list得到的結果用stu接收 -->
<c:forEach var="stu" items="${list}">
<tr align="center">
<td>${stu.stuId}</td>
<td>${stu.name}</td>
<td>${stu.age}</td>
<td>${stu.gender}</td>
<td>${stu.gender}</td>
<td><a href="#">更新</a> <a href="#">刪除</a></td>
</tr>
</c:forEach>
</table>
</body>
</html>
#總結:
-
JSP
三大指令
page include taglib
三個動作標籤 jsp:include jsp:forward jsp:param
九個內建物件
四個作用域 pageContext request session application out exception response page config
-
EL
${ 表示式 } 取4個作用域中的值 ${ name } 有11個內建物件。 pageContext pageScope requestScope sessionScope applicationScope header headerValues param paramValues cookie initParam
-
JSTL
使用1.1的版本, 支援EL表示式, 1.0不支援EL表示式
拷貝jar包, 通過taglib 去引入標籤庫
<c:set>
<c:if>
<c: