1. 程式人生 > >Java第三十二天(JSP & EL & JSTL)

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表示式配合

使用

  1. 匯入jar檔案到工程的WebContent/Web-Inf/lib jstl.jar standard.jar

  2. 在jsp頁面上,使用taglib 指令,來引入標籤庫

  3. 注意: 如果想支援 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: