一、JSP基礎知識
1.0、創建數據庫與表
/* Navicat MySQL Data Transfer Source Server : 127.0.0.1 Source Server Version : 50506 Source Host : localhost:3306 Source Database : dvdshop Target Server Type : MYSQL Target Server Version : 50506 File Encoding : 65001 Date: 2017-07-06 08:53:40 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `dvd` -- ---------------------------- DROP TABLE IF EXISTS `dvd`; CREATE TABLE `dvd` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '編號', `name` varchar(256) NOT NULL COMMENT '名稱', `price` double unsigned DEFAULT '0' COMMENT '價格', `state` int(11) DEFAULT NULL COMMENT '狀態', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of dvd -- ---------------------------- INSERT INTO `dvd` VALUES ('1', '功夫', '19.9', '0'); INSERT INTO `dvd` VALUES ('2', '異形', '88.1', '1'); INSERT INTO `dvd` VALUES ('6', '形狀', '99.1', '0'); INSERT INTO `dvd` VALUES ('8', '中國', '99.9', '0'); INSERT INTO `dvd` VALUES ('9', '有形', '34.6', '0'); INSERT INTO `dvd` VALUES ('10', '食神', '14.6', '0');
1.1、創建DVDShop動態Web項目
創建方法比較簡單,只是需要選擇生成web.xml文件
創建完成的項目
1.2、創建模型層(實體層)Bean
package com.dvdshop.bean; /*** * DVD bean 豆子 */ public class Dvd { /**編號*/ private int id; /**名稱*/ private String name; /**價格*/ private double price; /**狀態*/ private int state; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public int getState() { return state; } public void setState(int state) { this.state = state; } }
1.3、創建服務層(數據訪問)DAO
1.3.1、通用工具類JDBCUtil

package com.dvdshop.dao; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class JDBCUtils { public static String DRIVER="com.mysql.jdbc.Driver"; public static String URL="jdbc:mysql://127.0.0.1:3306/dvdshop?useUnicode=true&characterEncoding=UTF-8"; public static String USER_NAME="root"; public static String PASSWORD="uchr@123"; //加載驅動 static { try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { e.printStackTrace(); } } private JDBCUtils() { } /** * 獲得連接 * * @return */ public static Connection getconnnection() { Connection con = null; try { con = DriverManager.getConnection(URL, USER_NAME, PASSWORD); } catch (SQLException e) { e.printStackTrace(); } return con; } /** * 關閉連接 * * @param rs * @param st * @param con */ public static void close(ResultSet rs, Statement st, Connection con) { try { try { if (rs != null) { rs.close(); } } finally { try { if (st != null) { st.close(); } } finally { if (con != null) con.close(); } } } catch (SQLException e) { e.printStackTrace(); } } /** * 關閉連接 * * @param rs */ public static void close(ResultSet rs) { Statement st = null; Connection con = null; try { try { if (rs != null) { st = rs.getStatement(); rs.close(); } } finally { try { if (st != null) { con = st.getConnection(); st.close(); } } finally { if (con != null) { con.close(); } } } } catch (SQLException e) { e.printStackTrace(); } } /** * 關閉連接 * * @param st * @param con */ public static void close(Statement st, Connection con) { try { try { if (st != null) { st.close(); } } finally { if (con != null) con.close(); } } catch (SQLException e) { e.printStackTrace(); } } /** * insert/update/delete * 增加/更新/刪除 * * @param sql 數據庫語句 * @param args 可變參數(可以不帶參數,可以帶0-n個參數) * @return */ public static int update(String sql, Object... args) { int result = 0; Connection con = getconnnection(); PreparedStatement ps = null; try { ps = con.prepareStatement(sql); if (args != null) { for (int i = 0; i < args.length; i++) { ps.setObject((i + 1), args[i]); } } result = ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { close(ps, con); } return result; } /** * query, because need to manually close the resource, so not recommended * for use it * * @param sql * @param args * @return ResultSet */ @Deprecated //注解 public static ResultSet query(String sql, Object... args) { ResultSet result = null; Connection con = getconnnection(); PreparedStatement ps = null; try { ps = con.prepareStatement(sql); if (args != null) { for (int i = 0; i < args.length; i++) { ps.setObject((i + 1), args[i]); } } result = ps.executeQuery(); } catch (SQLException e) { e.printStackTrace(); } return result; } /** * Query a single record * 查詢單個記錄 * @param sql * @param args * @return Map<String,Object> */ public static Map<String, Object> queryForMap(String sql, Object... args) { Map<String, Object> result = new HashMap<String, Object>(); List<Map<String, Object>> list = queryForList(sql, args); if (list.size() > 0) { result = list.get(0); } return result; } /** * Query a single record * 查詢單個記錄返回強類型對象 * @param sql * @param args * @return <T> //泛型 */ public static <T> T queryForObject(String sql, Class<T> clz, Object... args) { T result = null; List<T> list = queryForList(sql, clz, args); if (list.size() > 0) { result = list.get(0); } return result; } /** * Query a single record * * @param sql * @param args * @return List<Map<String,Object>> */ public static List<Map<String, Object>> queryForList(String sql, Object... args) { List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(); Connection con = null; ResultSet rs = null; PreparedStatement ps = null; try { con = getconnnection(); ps = con.prepareStatement(sql); if (args != null) { for (int i = 0; i < args.length; i++) { ps.setObject((i + 1), args[i]); } } rs = ps.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); while (rs.next()) { Map<String, Object> map = new HashMap<String, Object>(); for (int i = 1; i <= columnCount; i++) { map.put(rsmd.getColumnLabel(i), rs.getObject(i)); } result.add(map); } } catch (SQLException e) { e.printStackTrace(); } finally { close(rs, ps, con); } return result; } /** * Query records * 查詢多個對象,返回強類型集合 * @param sql * @param args * @return List<T> */ public static <T> List<T> queryForList(String sql, Class<T> clz, Object... args) { List<T> result = new ArrayList<T>(); Connection con = null; PreparedStatement ps = null; ResultSet rs = null; try { con = getconnnection(); ps = con.prepareStatement(sql); if (args != null) { for (int i = 0; i < args.length; i++) { ps.setObject((i + 1), args[i]); } } rs = ps.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); while (rs.next()) { T obj = clz.newInstance(); for (int i = 1; i <= columnCount; i++) { String columnName = rsmd.getColumnName(i); String methodName = "set" + columnName.substring(0, 1).toUpperCase() + columnName.substring(1, columnName.length()); Method method[] = clz.getMethods(); for (Method meth : method) { if (methodName.equals(meth.getName())) { meth.invoke(obj, rs.getObject(i)); } } } result.add(obj); } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } finally { close(rs, ps, con); } return result; } }
1.3.2、實現DVD數據訪問類DVDDao
package com.dvdshop.dao; import java.util.List; import javax.swing.JButton; import com.dvdshop.bean.Dvd; /** * 數據訪問對象 data access object * 實現對dvd數據的存取 * */ public class DvdDao { //獲得所有的Dvd數據 public List<Dvd> getAll(){ return JDBCUtils.queryForList("select id,name,price,state from dvd;", Dvd.class); } //增加 public int add(String name, double price, int state) { return JDBCUtils.update("insert into dvd(name,price,state) values(?,?,?);", name,price,state); } //刪除 public int del(int id) { return JDBCUtils.update("delete from dvd where id=?;",id); } //模糊查詢通過名稱 public List<Dvd> search(String name) { return JDBCUtils.queryForList("select id,name,price,state from dvd where name like ?;", Dvd.class,"%"+name+"%"); } //根據id獲得dvd對象 public Dvd getById(int id) { return JDBCUtils.queryForObject("select id,name,price,state from dvd where id=?;",Dvd.class, id); } //修改 public int update(Dvd dvd) { return JDBCUtils.update("update dvd set name=?,price=?,state=? where id=?;",dvd.getName(),dvd.getPrice(),dvd.getState(),dvd.getId()); } //修改狀態 public int updateState(int id, int state) { return JDBCUtils.update("update dvd set state=? where id=?;",state,id); } }
1.4、添加數據庫驅動
將數據庫驅動包復制到WebRoot(WebContent)目錄下的Web-INF/Lib目錄下。
控制台測試OK!連接數據庫成功!
1.5、展示所有的DVD信息到JSP頁面
index.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@page import="com.dvdshop.dao.*"%> <%@page import="com.dvdshop.bean.*"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; // 數據訪問對象 DvdDao dao = new DvdDao(); //所有dvd集合 List<Dvd> dvds = dao.getAll(); %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>DVD商店</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> </head> <body> <h2>DVD商店</h2> <p> dvd總數:<%=dvds.size() %> </p> <%for (Dvd dvd : dvds) { %> <%=dvd.getId() %> <%=dvd.getName() %> <%=dvd.getPrice()%> <%=dvd.getState()==0?"未借出":"已借出" %> <br/> <hr/> <%} %> <table width="80%" border="1" > <tr> <th>編號</th> <th>名稱</th> <th>價格</th> <th>狀態</th> </tr> <%for (Dvd dvd : dvds) { %> <tr> <td> <%=dvd.getId() %></td> <td><%=dvd.getName() %></td> <td><%=dvd.getPrice()%> </td> <td><%=dvd.getState()==0?"未借出":"已借出" %></td> </tr> <%} %> </table> </body> </html>
運行結果:
1.6、新增DVD
1.6.1、新增加add.jsp頁面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>DVD商店 - 新增</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> </head> <body> <h2>DVD商店 - 新增</h2> <form action="Add" method="post"> <p> 名稱:<input name="name" /> </p> <p> 價格:<input name="price" /> </p> <p> 狀態:<input type="radio" name="state" value="0">未借出 <input type="radio" name="state" value="1">已借出 </p> <p> <input type="submit" value="提交"/> </p> </form> <p> <a href="index.jsp">列表</a> </p> </body> </html>
1.6.2、添加Servlet處理添加請求
package com.dvdshop.action; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.dvdshop.dao.DvdDao; public class Add extends HttpServlet { /** * Constructor of the object. */ public Add() { super(); } /** * Destruction of the servlet. <br> */ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } /** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } /** * The doPost method of the servlet. <br> * * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //設置請求編碼 request.setCharacterEncoding("utf-8"); //設置響應編碼 response.setCharacterEncoding("utf-8"); // 數據訪問對象 DvdDao dao = new DvdDao(); //獲得從客戶端發送的數據 String name=request.getParameter("name"); double price=Double.parseDouble(request.getParameter("price")); int state=Integer.parseInt(request.getParameter("state")); //執行添加 dao.add(name, price, state); //重定向 response.sendRedirect("index.jsp"); } /** * Initialization of the servlet. <br> * * @throws ServletException if an error occurs */ public void init() throws ServletException { // Put your code here } }
1.6.3、運行結果
二、JSP基本用法
1>JSP指令
JSP指令(Directive)作用是與JSP引擎進行溝通,為JSP頁面設置全局變量,聲
明類以及JSP要實現的方法和輸出內容的類型等
JSP指令在整個頁面范圍內有效,且不在客戶端產生任何輸出
格式:<%@ directivename attribute="value"%>
<%@ directivename attribute1="value1"......attributeN="valueN"%>
2>page指令
用來定義JSP頁面的全局屬性和相關功能,並由該指令和JSP引擎進行通信
格式:<%@ page attribute1="value1",........%>
可用屬性:language import contentType session buffer autoFlush
isThreadSafe info errorPage isErrorPage extends.
一個JSP頁面可以包含多個Page指令
除了import屬性外,每個屬性只能定義一次,否則出錯
language屬性:language="腳本語言"聲明JSP頁面中使用的腳本語言的種類
extends="ClassName"定義JSP頁面所產生的Servlet所繼承的類,將限制JSP引
擎提供的超類
import="importList"和java的import的意思一樣,導入包文件
session="true|false"指定JSP頁是否參與一個Http會話
buffer="none|sizeKB"指定客戶端輸出流的緩沖模式,none表示不緩沖
false"當緩沖區滿時將自動刷新,如果為false,緩沖區滿了
就會出現溢出異常
isThreadSafe="true|false"可以使用多線程
info="info_text"定義一個任意的字符串,用來說明JSP說明的信息,將直接加
入翻譯的頁面
errorPage="error_url"設置處理異常事件的JSP文件
isErrorPage="true|false"設置此頁是否為異常頁面"
contentType="type;charset=CHARSET"定義了JSP頁面相應MIME類型以及JSP頁
面的字符編碼(可以只寫type部分)
pageEncoding="peinfo"處理中文字符通常charset=GB2312
isELIgnored="true|false"用來設置EL表達式是否被忽略
3>include指令
用來指定JSP被編譯時所需要插入的資源,可以是文本,代碼,HTML文件或JSP
文件
格式:<%@ include file="URL">一旦編譯完成,資源內容就不可改變
用include指令可以將一個復雜的JSP頁面分為若干部分,如:head.jsp
body.jsp tail.jsp然后在同一網站的不同JSP頁面用include指令調用
4>taglib指令
用來自定義標簽,可以把一些需要反復顯示的內容定義成為一個標簽,從而增
加代碼的重用度,並使頁面便於維護
步驟1定義一個標簽處理類,用來實現標簽的功能
步驟2定義標簽庫描述文件,.tld后最 對標記相關信息進行說明
步驟3最后配置文件web.xml
格式:<%@ taglib uri="tagligURL prefilx="tagPrefix"%>
5>Scriptlet腳本元素
聲明用來定義變量方法 <%! int i,a,b=0;%>聲明每個語句以;結束
聲明方法<%! String getDate(){}%> (一個聲明只能在一個JSP頁面有效)
表達式格式:<%=表達式%>(表達式不能以;結尾)
<%=1+2+3%>輸出6
<%=new java.util.Date().toString()%>輸出日期
Scriptlet:以<%%>括起來的java代碼
JSP提供了很多種動作元素:
<jsp:useBean><jsp:setProperty><jsp:getProperty><jsp:fallback>
<jsp:param><jsp:include><jsp:forward><jsp:plugin>
<jsp:params><jsp:root><jsp:expression_r_r><jsp:text>
<jsp:output><jsp:declaration><jsp:scriptlet>.....20多種
<jsp:param>傳遞一個或多個參數到指定動態文件,需要和
<jsp:include><jsp:forward><jsp:plugin>一起來使用
<jsp:param name="paramName"value="paramValue"/>
<jsp:include page="HelloWorld.html"/>
<jsp:forward>允許將當前的請求轉發至另一個靜態文件或JSP頁面或含有與當
前頁面相同內容的Servlet
<jsp:forward page="confirm.jsp">
<jsp:param name="user" value="aaa"/>
<jsp:param name="password" value="12345"/>
</jsp:forward>轉向confirm.jsp頁面並傳遞兩個參數user和password
<jsp:plugin>用來在客戶端瀏覽器中播放或顯示一個對象,通常為Applet或
Bean,最終根據瀏覽器版本替換為<object>或<embed>
格式:
<jsp:plugin type="bean|applet" code="objectCode"
codebase="objectCodebase" archive="archiveList"
name="componentName"align="alignment"
vspace="vspace"hspace="hspace"
height="height"width="width"
nspluginurl="url"iepluginurl="url"
jreversion="jreversion"myscript="true|false"/>
<jsp:params name="paramName"value="paramValue">
<jsp:fallback>artibute text</jsp:fallback>(當顯示Bean|Applet失敗時顯
示此字符串
6>JSP的內建對象
JSP提供了一些由容器實現和管理的內建對象,在JSP頁面中可以直接使用,不
需要實例化,通過存取這些內建對象實現與JSP頁面的Servlet環境的互相訪問
JSP一共提供了9個內建對象:out request repnse session pageContext
application config page exception
JSP是構建在Servlet上的,JSP的每個內建對象都是與JavaServletAPI包中的類
相對象,在服務器運行時自動生成
JSP提供給開發人員一項傳遞數據的機制,那就是利用setAttribute()和
getAttribute()方法
JSP有四種范圍:分別為Page Request Session Application
Page范圍指的是單單一頁JSP Page的范圍 離開頁面就失效
PageContext.setAttribute("Name","abc");設置屬性Name的值為abc,該值只
在本頁范圍內有效,在本頁調用(String)PageContext.getAttribute("Name")將
返回"abc"
Request范圍是指在一JSP頁面發出請求到另一個JSP網頁之間(include指
令,forward指令等..),隨后范圍就失效
Request.setAttribute()和Request.getAttribute()
Session范圍為一段用戶持續和服務器所連接的時間,但與服務器斷線后,屬性
就失效
Application的作用范圍在服務器運行一開始執行服務就生效,直到服務器關閉
為止
以上四種內建對象可以使用的存儲和取得屬性的方法:
void setAttribute(String name,Object value) 設定name屬性的值為value
Enumeration getAttributeNamesInscope(int scope)取得所有scope范圍屬性
Object getAttribute(String name) 取得name屬性的值
void removeAttribute(String name) 移除name屬性的值
備注:pageContext並無getAttributeNames()方法。
out對象被封裝在javax.servlet.jsp.JspWriter接口,可以通過out對象對緩沖
區進行操作
通常通過pageContext.getOut()方法獲得out對象
常用方法:public abstract void print()
public abstract void println()
public abstract void newLine()//輸出一個換行符
public abstract void close()//關閉輸出流
public abstract void clearBuffer()//清除緩沖區內容,並將數據
發送至客戶端
public abstract void clear()//清除緩沖區內容,不將數據發送至
客戶端
public int getBufferSize()//獲取緩沖區的大小
public abstract int getRemaining()//獲得緩沖區剩余空間的大小
public abstract void flush()//輸出緩沖區的數據
public boolean is AutoFlush()//獲取AutoFlush的取值
request對象封裝了用戶所提交的信息,被封裝在
javax.servlet.http.HttpServletRequest接口
方法有四大類:
1.存取屬性的方法:
Object getAttribute(String)
Enumeration getAttributeNames(int)
void setAttribute(String,Object)
2.取得Request本身參數的方法:
String getParameter(String)取得指定參數名稱
Enumeration getParameterNames()取得所有參數名稱
String[]getParameterNames(String name)取得所有name的參數值
Map getParameterMap()取得一個要求參數的Map
3.能夠取得請求HTTP標頭的方法:
String getHeader(String name) 取得name的標頭
Enumeration getHeaderNames() 取得所有的標頭名稱
Enumeration getHeaders(String name) 取得所有name的標頭
int getIntHeader(String name) 取得整數類型name的標頭
long getDateHeader(String name)取得日期類型name的標頭
Cookie[] getCookies()取得與請求有關的cookies
4.其他方法:
String getContextPath()取得Context路徑
String getMethod()取得Http方法(Get|Post)
String getServletPath()獲取接受客戶提交信息的頁面
String getProtocol()取得使用的協議(Http/1.1 Http/1.0)
String getQueryString() 取得請求的參數字符串(Http方法必須為GET)
String getRequestedSessionId()取得用戶端的Session ID
String getRequestURI() 取得請求URL,不包括請求的參數字符串
String getRemoteAddr() 取得用戶的IP地址
String getRemoteHost()取得用戶的主機名稱
int getRemotePort()取得用戶的主機端口
String getRemoteUser()取得用戶的名稱
void setCharacterEncoding(String encoding)設定編碼格式,用來解決窗體傳遞
中文的問題
response對象:是封裝JSP處理數據后產生的結果,封裝在
javax.servlet.http.HttpServletResponse接口
void addCookie(Cookie cookie)新增cookie
void addDateHeader(String name,long date)新增long類型的值到name標頭
void addHeader(String name,String value)新增String類型的值到name標頭
void addIntHeader(String name,int value)新增int類型的值到name標頭
void setDateHeader(String name,long date)指定long類型的值到name標頭
void setHeader(String name,String value)指定String類型的值到name標頭
void setIntHeader(String name,int value)指定String類型的值到name標頭
void sendError(int sc)傳遞狀態碼
void sendError(int sc,String msg)傳遞狀態碼和錯誤信息
void setStatus(int sc)設定狀態碼
String encodeRedirectURL(String url)使用sendRedirect()方法的URL予以編
碼
response.setContentType("text/htmlcharset=Big5")改語句同<%@ page
contentType="text/html;charset="Big5"%>等價
cookie技術:
Cookie使站點跟蹤特定訪問者的訪問次數,最后訪問時間,訪問者進入站點的路
徑
Cookie告訴在線廣告商廣告被點擊的次數
Cookie能幫助站點統計用戶個人資料以實現各種各樣的個性化服務
創建Cookie
Cookie demoCookie=new Cookie("CookieName","Cookiue")
Cookie中的get方法:
String getComment()返回cookie中的注釋
String getDomain()返回cookie中Cookie的域名,域名以點開始(.yesky.com)
int getMaxAge()返回Cookie過期之前的最大時間,以秒計算
String getName()返回Cookie的名字
String getPath()返回Cookie適用的路徑,如果不指定,Cookie將返回給當前頁
面所在目錄及其子目錄下的所有頁面
boolean getSecure()如果瀏覽器通過安全協議發送cookies將返回true,使用標
准協議將返回false
String getValue()返回Cookie的值
int getVersion()返回Cookie的協議版本
Cookie中的set方法:
void setComment(String purpose)
void setDomain(String pattern)
void setMaxAge(int expiry)
void setPath(String uri)
void setSecure(boolean flag)
void setValue(String newValue)
void setVersion(int v)
Cookie示例代碼:
1
2
3
4
5
6
7
|
String sessionID=makeUniqueString();
HashMap sessionInfo=
new
HashMap();
HashMap globaTable=findTableStoringSessions();
globeTable.put(sessionID,sessionInfo);
Cookie sessionCookie=
new
Cookie(
"JSESSION"
,sessionID);
cookie setMaxAge(
30
*
60
);
//存活時間為30分鍾
response.addCookie(cookie);
//寫入客戶硬盤
|
session和cookie的區別:
session存放在服務器端的內存里
session隨用戶的登陸而生成,用戶下線后消失
session存放在服務器里,用戶不能修改,安全性好
session是一個動作狀態的持續,是一個會話
session對象,記錄每個客戶端的訪問狀態以便跟蹤每個客戶端的操作狀態,被封
裝為javax.servlet.http.HttpSession接口,可以通過pageContext.getSession()
方法獲取一個session對象
session對象中的方法:
long getCreationTime()獲得session產生的時間
String getId()獲得session的ID
long getLastAccessedTime()取得用戶最后通過這個session送出請求的時間,
單位:毫秒
long getMaxInactiveInterval()取得最大session不活動的時間,若超過這個時
間,session將會失效 單位:秒
void invalidate()取消session對象
boolean isNew()判斷session是否為新的
void setMaxInactiveInterval(int interval)設定最大session不活動的時間,
若超過這時間,session將回失效 單位:秒
application對象,負責提供應用程序在服務器中運行時的一些全局信息,直到服
務器關閉,被封裝在javax.servlet.SertletContext接口
int getMarorVersion()取得Container主要的Servlet API版本
ing getMinorVersion()獲得container次要的Servlet API版本
String getServerInfo()取得Container的名稱和版本
String getMimeType(String file)取得指定文件的MIME類型
ServletContext getContext(String uripath)取得指定LOcalURL的
ApplicationContext
String getRealPath(String path)取得本地端Path絕對路徑
void log(String message)將信息寫入log文件中
void log(String message,Throwable throwable)將stacktrace所產生的異常
信息寫入log文件中
pageContent對象一般用於設置,獲取當前JSP頁面的一些屬性,也能夠存取頁面
的其他隱含對象(out,request,response,session,application等)及其所有屬性,
被封裝在javax.servlet.jsp.PageContext接口
javax.servlet.jsp.PageContext類所提供的四種范圍參數:PAGE_SCOPE
REQUEST_SCOPE SESSION_SCOPE APPLICATION_SCOPE
Exception getException()回傳目前網頁的異常,不過此網頁要為error page
JspWriter getOut()回傳目前網頁的輸出流,如out
Object getPage()回傳目前網頁的Servlet實體
ServletRequest getRequest()回傳目前網頁的請求
ServletResponse getResponse()回傳目前網頁的響應
ServletConfig getServletConfig()回傳目前網頁的ServletConfig對象
ServletContext getServletContext()回傳此網頁的執行環境
HttpSession getSession()回傳目前和網頁有聯系的會話
config對象,主要作用是取得服務器的配置信息,被封裝在
javax.servlet.servletConfig接口,痛多pageContext.getServletConfig()方法
可以獲取一個config對象,提供存取servlet類初始化參數以及有關服務器環境信
息的ServletContext對象
config對象的常用方法:
public String getInitParatemer(String name) 獲取服務器指定name參數的
初始值
public Enumeration getInitParameterNames() 獲取服務器所有初始參數的名
字
public ServletContext getServletContext()獲取Servlet的上下文
public String getServletName()獲取Servlet的服務器名
page對象,代表JSP文件被編譯后的Servlet類對象,實質就是Object的一個實例
exception對象,主要作用是顯示吟唱信息,代表了JSP文件運行時所產生的例外
對象,是java.lang.Throwable類的一個實例,只有在包含<%@ page
isErrorPage="true"%>的頁面才可以被使用,在一般的JSP頁面中使用該對象無法
編譯JSP文件
三、JSP總結
day1
JSP 定義:
1)Java Server Page, Java EE 組件,本質上是 Servlet。
2)運行在 Web Container.接收 Http Request,生成 Http Response(默認協議是 Http 請求和響應)
3)JSP 使得我們能夠分離頁面的靜態 HTML 和動態部分——我們需要的技術。
4)使頁面可以混和html代碼、Java代碼以及JSP標簽;允許訪問組件
Servlet的缺陷(JSP出現的原因):
1)寫靜態頁面必須部署后才能看到效果,很難控制頁面的外觀。
2)從技術角度來說Servlet是Java代碼和HTML靜態代碼的混合代碼。
3)從市場競爭角度來說,微軟推出了ASP產品。
JSP的改進:
1)JSP是標簽式的文本文件(區Servlet是Java文件)
2)JSP不需要編譯(其實是由服務器監測JSP文件的變化,再將其翻譯成 Servlet 代碼)
服務器對其進行編譯並在第一次請求時創建一個Servlet實例。所以,第一次訪問JSP頁面時會后延遲
3)JSP不用寫配置文件
4)JSP以靜態代碼為主,Java代碼為輔。Servlet反之。
5)是J2EE藍圖的一部分(Servlet、JSP以及EJB是J2EE的三大組件)
JSP從本質上來說內核還是Servlet,但與Servlet不是替代關系而是一種互補的關系。
JSP適合於寫顯示層的動態頁面,而Servlet則適合寫控制層的業務控制(頁面轉發)。
JSP往純標簽方向發展,Servlet往純代碼方向發展,他們以Servlet內核(請求響應式的工作方式)往兩個方向發展。
基本語法
一、JSP的聲明(statement)
用來定義在產生的類文件中的類的屬性和方法(成員變量)。可聲明類(即是內部類)。
由於servlet是工作在多線程環境下,所以盡量不要在service方法體外聲明成員變量。
<%!.....%>
//聲明時要加"!",屬於類成員,最先加載,可寫於任何位置;不加則是腳本的局部變量,必須調用前寫。
如: <%!String hello=
"Hello, World!"
;%>
//變量的聲明
<%=hello%>
//變量的調用
<%!
private
int
counter=0;
public
int
count(){
return
++counter;} %>
//函數的聲明
<h1><%=count()%></h1>
//函數的調用
聲明規則:
1) JSP中聲明的變量和方法對應於Servlet中的實例方法和實例變量。這些將被同時請求該頁面的所有用戶所共享;
2) 在使用變量或方法前須先定義(不是說聲明變量的位置在頁面中要處於使用變量的前面,而是指變量不聲明不能使用);
3) 聲明的變量或方法的作用域為當前頁面或包含的頁面;
4) 語句間以分號分隔。
二、JSP代碼段(Scriptlet)
<% java代碼 %>
是一段可以在處理請求時間執行的Java代碼。可以產生輸出,也可以是一些流程控制語句。
在代碼段中定義的變量為service方法中的局部變量。
1._jspService()中的局部代碼:
<% System.
out
.println(
"Hi,I like JSP."
); %>
//在控制台打印出,網頁上沒顯示
<%
out
.println(
"Hi,I like JSP."
); %>
//打印在網頁上
<% Connection conn=DriverManager.getConnection(); Statement st=conn.createStatement();
String sql=
"select * from users"
; ResultSet rs=st.executeQuery(sql);
//……
%>
問:能否在JSP腳本里定義方法?
答:不能!
//腳本相當於方法,不能在方法里定義方法
<%!
public
void
helloworld(){}%>
//可以聲明方法
<%
public
void
helloworld(){}%>
//編譯出錯;腳本不能定義方法
2.比較:
<%!
int
i=100;%>
//成員變量
<%
int
i=101;%>
//_jspService()方法中的局部變量
<%=i%>
//同一文件里,局部變量優先
3.腳本小程序規則:
1) 你使用的腳本語言決定了腳本小程序的規則;
2) 語句間以分號分隔;
3) 可以使用默認的對象、import進的類、declaration聲明的方法和對象以及useBean tag中聲明的對象。
三、JSP表達式(expression)
<%=……%>
// "="號
在JSP請求處理階段計算他的值,表達式生成的代碼是Service方法中的一個代碼片斷。
JSP對於聲明的處理:1、計算表達式的值
2、將值轉換成String
3、用
out
.println發送標簽;把數據輸出至頁面的當前位置
<%=
"Hello,JSP world!"
%>
//out.println("Hello,JSP world");
<%=name%>
//<%!String name="GiGi";%> out.println(name);
<%=
new
java.util.Date()%>
//out.println(new java.util.Date());
表達式規則:
1) 你使用的腳本語言決定了腳本小程序的規則;
2) 執行的順序為從左到右;
3) 分號不能用於表達式。
四、JSP指令(direction)
指令用於從JSP發送信息到容器上。用來設置全局變量,聲明類,要實現的方法和輸出內容等。
指令在JSP整個文件內有效。它為翻譯階段提供了全局信息。
<%@......%>
// "@"符號
指令包括:page、include、taglib
1.page指令
import、session、errorPage、isThreadSafe
頁面的語言、內容類型、字符集、頁面編碼
<%@page language=
"java"
contentType=
"text/html; charset=gbk"
pageEncoding=
"gbk"
%>
language:java唯一值,表示腳本中使用的編程語言
contentType:設置了內容的類型和靜態頁面的編碼 (告訴瀏覽器以什么編碼顯示)
pageEncoding:頁面本身的編碼格式 (寫頁面時用的編碼格式)
上面的代碼等價於servlet里: response.setContentType(
"text/html; charset=gbk"
);
import:導入其他的包和類; 其中,JSP默認導入的包是java.lang.*
<%@page import=
"java.util.Date"
%>
//具體的包和類
<%@page import=
"java.sql.*"
%>
//包下的所有類
<%@page import=
"java.util.*, java.io.*, java.net.*"
%>
//連寫,逗號分隔
Session:指示當前的jsp是否參與會話 (默認為
true
; 參與會話)
通過指令使當前頁面與session不可會話: <%@page session=
"false"
%>
session=
"true"
時,可用內建對象session直接訪問會話,例如:
<% session.setAttribute(
"username"
,
"maxwell"
);
String name = (String)session.getAttribute(
"username"
); %>
<%=name%>
errorPage:
isErrorPage:Jsp頁面中出現異常的處理方式
對於有可能出現異常的頁面:
<%@page errorPage=
"error.jsp"
%>
//異常時會跳轉到處理異常的頁面;這頁面自己寫
在有可能異常的地方打印原因:
throw
new
Exception(
"數據庫連接出錯"
);
對於處理異常的頁面(error.jsp)里:
<%@page isErrorPage=
"true"
%>,其中使用<%=exception.getMessage() %>把異常信息打印出來
isThreadSafe——此屬性已經不再使用(已廢棄)
當前Jsp頁面是否線程安全
default
--->
true
<%@page isThreadSafe=
"true"
%>
//普通的Servlet,可以並發處理用戶請求
<%@page isThreadSafe=
"false"
%>
//相當於Servlet實現了SingleThreadModel
2.include指令
把目標頁面的內容包含到當前頁面,產生頁面疊加以后的輸出效果
//相當於將兩個頁面合並;編譯時就包含進來
<%@include file=
"foot.jsp"
%>
//可插入任意位置
3.taglib指令
留在JSTL里講解。
五、JSP中的注釋
1.java格式注釋
編譯器會忽略掉此類注釋中的內容(客戶端的源碼看不見)
<%-- JSP注釋;可多行 --%>
<%
// java 單行注釋 %>
<%
/* java multi lines comments */
%>
<%
/**java 特有的注釋*/
%>
2.html風格注釋
編譯器會執行此類注釋中的代碼(客戶端的源碼看得見)
<!-- html風格注釋 --> 等價於
out
.println(
"<!-- html風格注釋 -->"
)
這種注釋方式不好的地方就是當頁面注釋信息太多的時候會增大服務器的負荷。
還有注釋信息需要在網絡上傳輸,從而降低效率;內部程序員的測試數據一般不能寫在這種注釋中,以免泄露。
六、動作(Action)
<jsp:actionName attributeName=attributeValue/>
JSP的動作包括:
forward、include、useBean、setProperty、getProperty
1.forward動作
形式:<jsp:forward page=
"another.jsp"
/>
等價於 Servlet中通過RequestDispatcher.forward();
可以傳參數
<jsp:forward page=
"another.jsp"
>
<jsp:param name=
"name"
value=
"maxwell"
/>
<jsp:param name=
"age"
value=
"20"
/>
</jsp:forward>
2.Include動作
形式:<jsp:include page=
"another.jsp"
/>
等價於 Servlet中通過RequestDispatcher.include();
Include動作也可以傳參數
<jsp:include page=
"b.jsp"
flush=
"true"
>
<jsp:param name=
"name"
value=
"narci"
/>
</jsp:include>
與<%@include file=
""
%>比較:
include動作在運行期處理(include指令編譯期),jsp:include包含的是所包含URI的響應,而不是URI本身。
這意味着:jsp:include 對所指出的 URI 進行解釋,因而包含的是生成的響應。
對於頁面是靜態內容,這沒有太大的關系。但如果是動態內容,include動作可傳參數。
flush 屬性
flush 指示在讀入包含內容之前是否清空任何現有的緩沖區。
JSP 1.1 中需要 flush 屬性,因此,如果代碼中不用它,會得到一個錯誤。
但是,在 JSP 1.2 中, flush 屬性缺省為
false
。
建議:由於清空大多數時候不是一個重要的問題,因此,對於 JSP 1.1,將 flush 設置為
true
;
而對於 JSP 1.2 及更高版本,將其設置為
false
或不設置(用默認值)。
JSP的生命周期
1) 每一個JSP都會對應有一個servlet生成
2) 在 %tomcat%/work/Catalina/localhost/工程名/org/apache/jsp 目錄下可找到對應生成的 Servlet 文件
3) 一般而言,每一個JSP對應的servlet都有如下的生命周期方法:
一、 _jspInit()方法
JSP容器第一次裝載jsp文件時調用一次
public
void
_jspInit(){……}
二、 _jspService()方法
每當服務器接收到對該jsp的請求,都需要調用一次該方法一次。
public
void
_jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException { ……}
三、 _jspDestroy()方法
jsp文件被修改時,JSP容器會銷毀舊的jsp文件對應的對象,重新裝載一次更新后的jsp文件的內容(只調用一次)。
public
void
_jspDestroy(){……}
JSP處理過程:JSP源文件處理分成二個階段:
1) JSP頁面轉換階段:
頁面被編譯成一個Java類,所有的HTML標記和JSP標記都被轉換創建一個Servlet。這時,腳本和表達式還沒有被執行;
2) 請求處理階段:發生在服務器,將一個客戶端請求指向JSP頁面。
一個請求對象創建、解析以及提交給編譯好的JSP對應的servlet。
當這個servlet處理請求的時候它執行先前在JSP中定義的處理腳本小程序和表達式。
使用腳本代碼的缺點和指導方針
1) 缺點:
a. 過度使用腳本代碼使用JSP頁面混亂和難以維護;
b. 腳本代碼降低JSP二個主要的優點:軟件重用和代碼分開
2) 指導方針:只在組件功能無能為力或需要有限的腳本時使用。
day2
POJO: Plain Old Java Object --> 簡單傳統的Java對象
Java Bean: 組件、構件的規范(屬性,提供
get
/
set
方法;還可包含其他方法)
JSP調用JavaBean
通過引入JavaBean,JSP才能較好的把頁面展示與業務邏輯分離。
其中,業務邏輯放到后台的Java Bean中,減少JSP中的腳本代碼,有利於程序的可維護性與可重用性。
一、Java Bean
a.無參構造器(也是默認的構造方法)
b.標准的getter、setter方法
c.如要進行網絡傳輸(支持RMI),需實現Serializable接口
二、如何在JSP中使用JavaBean?
1.定義Java Bean
形式:<jsp:useBean id =
"BeanName"
class
=
"className"
sope=
"范圍域"
>
id ——聲明bean對象的標識符,方便其他地方使用
class
——bean對象的類型,注意要使用完全限定名
scope——java bean對象的共享范圍(page、request、session、application)
page:當前頁面范圍(范圍最小,生命周期最短)
request:同一個請求范圍 (forward,include)
session:同一個會話(30分鍾不使用,會自動結束)
application:同一個應用(范圍最大,生命周期最長) ServletContext
例如: SuperGirl <jsp:useBean id=
"girl"
class
=
"com.tarena.vo.SuperGirl"
scope=
"session"
/>
等價於:<% SuperGirl girl=(SuperGirl)session.getAttribute(
"girl"
);
if
(girl==
null
){
girl =
new
SuperGirl();
//對應 id 和 class
session.setAttribute(
"girl"
,girl);
//對應 scope 的值
} %>
可以用表達式獲得bean的值: <%=girl.getName();%>
2.對JavaBean的屬性賦值
形式:<jsp:setProperty name=
"JavaBean對象名"
property=
"JavaBean屬性名"
value=
"屬性值"
/>
例子: <jsp:setProperty name=
"girl"
property=
"name"
value=
"Lily"
/>
等價於: <% girl.setName(
"Lily"
);%>
可以嵌套JSP表達式:
<jsp:setProperty name=
"girl"
property=
"name"
value=
'<%=request.getParameter("name")%>'
/>
Java Bean中的屬性名與form中輸入域的名字保持一致的話,可以使用通配符*,一次設置所有字段的值。
<jsp:setProperty name=
""
property=
"*"
/>
3.獲取JavaBean的屬性值
形式:<jsp:getProperty name=
""
property=
""
/>
name:標識具體的Bean對象,這與<jsp:useBean>標准動作中的id值相匹配
property:標識屬性中的標識符。
JSP中的異常處理
一、
try
/
catch
/
finally
/throws/
throw
// 在局部代碼里處理異常。
二、errorPage, isErrorPage
// 在整個頁面處理異常。
1.errorPage
形如: <%@page errorPage=
"error.jsp"
%>
表示:需要錯誤處理的頁面
2.isErrorPage
形如: <%@page isErrorPage=
"true"
%>
指示:錯誤頁面。其中,有一個隱式對象exception可用: <%=exception%>
產生(隱含)內建對象exception,可通過它獲得異常信息
<%=exception.getMessage() %>
//把異常信息打印出來
三、聲明的方式處理異常
// 在整個應用處理異常。(范圍比前兩種更大)
1.配置: 在web.xml進行配置異常處理
…… <error-page>
<exception-type>java.lang.ArithmeticException</exception-type>
<location>/MathError.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page> ……
2.復習:Java中的異常——有2種
受查異常(Checked Exception)
非受查異常(Unchecked Exception) Java中的RuntimeException及其子類是不需要處理的(
try
/
catch
)
因為所有的RuntimeException總是可以通過優化代碼來避免,因此,這種異常被稱為
"Unchecked Exception"
。
3.思考:
三種異常處理方式同時啟動用,那個優先級高? 作用域越小,優先級越高。
注意:要使得頁面自動跳轉到錯誤頁面,必須關閉瀏覽器的
"顯示友好HTTP錯誤信息"
選項。
public
void
_jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException {
/*只處理這兩種兼容的異常*/
…… }
安全的系統(企業級應用):
1.身份認證(合法用戶) --登錄
2.授權(靜態) --定義權限
3.訪問控制(動態) --比較
4.安全審計(日志) --修復bug (只有敏感的部門需要)
JAAS實現安全
JAAS——Java Authentication and Authorization Service
(Java認證(Authentication)與授權(Authorization)服務)
是Java EE規范之一,實現Java EE應用程序安全性的一個重要途徑
(要求:會使用,不必深入理解)
一、網絡安全的4大要素
認證——抵御假冒者(用戶身份的合法性)
授權——合法用戶擁有的權限
機密性——防止關鍵數據落入其他人手中
數據完整性——抵御竊聽者(篡改私有數據)
二、對於Http應用是如何進行認證的(Web端的認證方法)?
四種安全認證: (http協議)basic, form, digest, certificate(證書) + ssl
HttpMonitor監控受限資源的訪問
三、容器是如何完成認證與授權的呢?
圖示(容器做了些什么事情)
(容器的角度)
四、聲明式安全以及分工
Servlet的開發者
應用的管理員
部署人員
五、實戰
1.定義新用戶與角色
在Tomcat服務器中定義: %TOMCAT_HOME%/conf/tomcat-user.xml
<?xml version=
'1.0'
encoding=
'utf-8'
?>
<tomcat-users>
<role rolename=
"manager"
/>
<role rolename=
"admin"
/>
<user username=
"maxwell"
password=
"123"
roles=
"admin,manager"
/>
<user username=
"lily"
password=
"iloveyou"
roles=
"manager"
/>
</tomcat-users>
為什么tomcat可以使用tomcat-users.xml作為它保存用戶和角色信息的文件?原因是在server.xml中,有以下配置:
<Resource name=
"UserDatabase"
auth=
"Container"
type=
"org.apache.catalina.UserDatabase"
description=
"User database that can be updated and saved"
factory=
"org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname=
"conf/tomcat-users.xml"
/>
在DD中指定角色,則需在 web.xml 中配置:
<security-role>
<description />
<role-name>admin</role-name>
</security-role>
2.聲明安全性約束(指明受限資源)
在DD中加入<security-constraint>元素,其中包含了:
Web資源集合:<web-resource-collection>
其中包含了url資源以及http方法。
授權約束:<auth-constraint>
<security-constraint>
<display-name>Constraint-all</display-name>
<web-resource-collection>
<web-resource-name>all-resources</web-resource-name>
<description />
<url-pattern>/admin/*</url-pattern>
//被授權訪問的目錄和文件
<url-pattern>/security/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<description />
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
要注意的規則:
不要認為:資源本身受到約束;其實,是資源 + Http方法組合受到約束
如果配置中不指定<http-method>,說明所有的方法(Get,Post,Trace,Head,Delete,Put,Options等)都受約束;
當指定了具體的<http-method>,那么約束只針對該方法,其他的http方法都不在約束之內;
<auth-constraint>定義的是哪些角色可以做出受約束的請求;而不是定義訪問<web-resource-collection>
沒有<auth-constraint>:任何角色都能訪問; 空的<auth-constraint />任何角色都不能訪問;
對於不同的<security-constraint>,指定的url資源<url-pattern>在相同方法上定義了不同的<auth-constrain>,則存在合並規則。
問題:為什么要設置<auth-constraint />元素,使得任何角色的任何人都不能訪問受限資源呢?其意義何在?
為了保護資源,只允許內部跳轉去訪問
3.選擇認證方式
如果是BASIC認證:則無需指定Form表單的action。
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>UserDatabaseRealm</realm-name>
</login-config>
如果是FORM認證:
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/logon/loginForm.jsp</form-login-page>
<form-error-page>/logon/loginErrorForm.jsp</form-error-page>
</form-login-config>
</login-config>
對於Form表單認證
action的值,用戶名、密碼字段的名稱都是固定的(規范)
<form method=
"POST"
action=
"j_security_check"
>
<input type=
"text"
name=
"j_username"
>
<input type=
"password"
name=
"j_password"
>
<input type=
"submit"
value=
"Submit"
name=
"B1"
>
</form>
標准的表單提交(固定不變):
action:j_security_check
name:j_username
password:j_password
Day3
內容要點: 1.隱含對象 2.歡迎文件 3 MVC
********************************************************************************************
一、隱含對象
1.什么是隱含對象(9個)?
————JSP中的隱含對象:不用我們手工去創建的對象
類型 對象名 功能
---------------------------------------------------------------------
JspWriter
out
往瀏覽器寫內容
HttpServletRequest request Http請求對象.
HttpServletResponse response Http響應對象
PageContext pageContext JSP的頁面上下文
HttpSession session 會話對象
ServletContext application 應用上下文
ServletConfig config JSP的ServletConfig
Object page 頁面實現類的對象(例如:
this
)
Exception exception 含有指令<%@page isErrorPage=
"true"
%>
2.范圍對象
其中,有4個是范圍對象: pageContext,request,session,application
對應<jsp:useBean/>指令的scope分別是:page,reqeust,session,application
也就是說,指定不同scope的bean對象(Java Bean)會被綁定到不同的范圍對象中
// 選擇范圍對象的原則:作用域的范圍越小越好;因為作用域小的生命周期短,有利於性能提高。
例如:<jsp:useBean id=
"stu"
class
=
"vo.Student"
scope=
"page"
/>
表示stu對象被綁定到javax.servlet.jsp.PageContext對象(pageContext)中,其等價的代碼
<% Student stu = pageContext.getAttribute(
"stu"
);
if
(stu==
null
) {
stu=
new
Student();
pageContext.setAttribute(
"stu"
,stu);
}%>
1)pageContext對象:
每一個jsp頁面對應着一個pageContext。一般地,在實際應用中,主要是使用它來存取屬性。
另外,pageContext對象能夠存取其他隱含對象。
a.pageContext對象存取其他隱含對象屬性的方法,此時需要指定范圍的參數。
Object getAttribute(String name,
int
scope)
Enumeration getAttributeNamesInScope(
int
scope)
void
removeAttribute(String name,
int
scope)
void
setAttribute(String name, Object value,
int
scope)
其中,范圍參數有四個,分別代表四種范圍:
PAGE_SCOPE、REQUEST_SCOPE、SESSION_SCOPE、APPLICATION_SCOPE
b.PageContext對象取得其他隱含對象的方法
Exception getException() 回傳目前網頁的異常,不過此網頁要為error page,
JspWriter getOut() 回傳目前網頁的輸出流,例如:
out
Object getPage() 回傳目前網頁的Servlet 實體(instance),例如:page
ServletRequest getRequest() 回傳目前網頁的請求,例如:request
ServletResponse getResponse() 回傳目前網頁的響應,例如:response
ServletConfig getServletConfig() 回傳目前此網頁的ServletConfig 對象,例如:config
ServletContext getServletContext() 回傳目前此網頁的執行環境(context),例如:application
HttpSession getSession() 回傳和目前網頁有聯系的會話(session),例如:session
c.PageContext對象提供取得屬性的方法
Object getAttribute(String name,
int
scope) 回傳name 屬性(范圍為scope;類型為Object)
Enumeration getAttributeNamesInScope(
int
scope)
回傳所有屬性范圍為scope 的屬性名稱,回傳類型為Enumeration
int
getAttributesScope(String name)回傳屬性名稱為name 的屬性范圍
void
removeAttribute(String name) 移除屬性名稱為name 的屬性對象
void
removeAttribute(String name,
int
scope) 移除屬性名稱為name,范圍為scope 的屬性對象
void
setAttribute(String name, Object value,
int
scope)
指定屬性對象的名稱為name、值為value、范圍為scope
Object findAttribute(String name) 尋找在所有范圍中屬性名稱為name 的屬性對象
2)request 對象
request 對象包含所有請求的信息,
如:請求的來源、標頭、cookies和請求相關的參數值等等。
request 對象實現javax.servlet.http.HttpServletRequest接口的,
所提供的方法可以將它分為四大類:
(1)儲存和取得屬性方法;
void
setAttribute(String name, Object value) 設定name屬性的值為value
Enumeration getAttributeNamesInScope(
int
scope) 取得所有scope 范圍的屬性
Object getAttribute(String name) 取得name 屬性的值
void
removeAttribute(String name) 移除name 屬性的值
(2)取得請求參數的方法
String getParameter(String name) 取得name 的參數值
Enumeration getParameterNames() 取得所有的參數名稱
String [] getParameterValues(String name) 取得所有name 的參數值
Map getParameterMap() 取得一個要求參數的Map
(3)能夠取得請求HTTP 標頭的方法
String getHeader(String name) 取得name 的標頭
Enumeration getHeaderNames() 取得所有的標頭名稱
Enumeration getHeaders(String name) 取得所有name 的標頭
int
getIntHeader(String name) 取得整數類型name 的標頭
long
getDateHeader(String name) 取得日期類型name 的標頭
Cookie [] getCookies() 取得與請求有關的cookies
(4)其他的方法
String getContextPath() 取得Context 路徑(即站台名稱)
String getMethod() 取得HTTP 的方法(GET、POST)
String getProtocol() 取得使用的協議 (HTTP/1.1、HTTP/1.0 )
String getQueryString() 取得請求的參數字符串,不過,HTTP的方法必須為GET
String getRequestedSessionId() 取得用戶端的Session ID
String getRequestURI() 取得請求的URL,但是不包括請求的參數字符串
String getRemoteAddr() 取得用戶的IP 地址
String getRemoteHost() 取得用戶的主機名稱
int
getRemotePort() 取得用戶的主機端口
String getRemoteUser() 取得用戶的名稱
void
getCharacterEncoding(String encoding) 設定編碼格式,用來解決窗體傳遞中文的問題
3)session 對象
session對象表示目前個別用戶的會話(session)狀況。
session對象實現javax.servlet.http.HttpSession接口,HttpSession接口所提供的方法
long
getCreationTime() 取得session產生的時間,單位是毫秒
String getId() 取得session 的ID
long
getLastAccessedTime() 取得用戶最后通過這個session送出請求的時間
long
getMaxInactiveInterval() 取得最大session不活動的時間,若超過這時間,session 將會失效
void
invalidate() 取消session 對象,並將對象存放的內容完全拋棄
boolean isNew() 判斷session 是否為
"新"
的會話
void
setMaxInactiveInterval(
int
interval)
設定最大session不活動的時間,若超過這時間,session 將會失效
4)application對象
application對象最常被使用在存取環境的信息。
因為環境的信息通常都儲存在ServletContext中,所以常利用application對象來存取ServletContext中的信息。
application 對象實現javax.servlet.ServletContext 接口,ServletContext接口容器所提供的方法
int
getMajorVersion() 取得Container主要的Servlet API版本
int
getMinorVersion() 取得Container次要的Servlet API 版本
String getServerInfo() 取得Container的名稱和版本
String getMimeType(String file) 取得指定文件的MIME 類型
ServletContext getContext(String uripath) 取得指定Local URL的Application context
String getRealPath(String path) 取得本地端path的絕對路徑
void
log(String message) 將信息寫入log文件中
void
log(String message, Throwable throwable) 將stack trace 所產生的異常信息寫入log文件中
3.其他對象:
1)page 對象
page對象代表JSP本身,更准確地說page對象是當前頁面轉換后的Servlet類的實例。
從轉換后的Servlet類的代碼中,可以看到這種關系: Object page =
this
;
在JSP頁面中,很少使用page對象。
2)response 對象
response 對象主要將JSP 處理數據后的結果傳回到客戶端。
response 對象是實現javax.servlet.http.HttpServletResponse 接口。response對象所提供的方法。
a.設定表頭的方法
void
addCookie(Cookie cookie) 新增cookie
void
addDateHeader(String name,
long
date) 新增
long
類型的值到name標頭
void
addHeader(String name, String value) 新增String類型的值到name標頭
void
addIntHeader(String name,
int
value) 新增
int
類型的值到name標頭
void
setDateHeader(String name,
long
date) 指定
long
類型的值到name標頭
void
setHeader(String name, String value) 指定String類型的值到name標頭
void
setIntHeader(String name,
int
value) 指定
int
類型的值到name標頭
b.設定響應狀態碼的方法
void
sendError(
int
sc) 傳送狀態碼(status code)
void
sendError(
int
sc, String msg) 傳送狀態碼和錯誤信息
void
setStatus(
int
sc) 設定狀態碼
c.用來URL 重寫(rewriting)的方法
String encodeRedirectURL(String url) 對使用sendRedirect()方法的URL予以編碼
3)
out
對象
out
對象的類型是javax.servlet.jsp.JspWriter,該類從java.io.Writer類派生,以字符流的形式輸出數據。
out
對象實際上是PrintWriter對象的帶緩沖的版本(在
out
對象內部使用PrintWriter對象來輸出數據),
可以通過page指令的buffer屬性來調整緩沖區的大小,默認的緩沖區是8kb。
out
對象能把結果輸出到網頁上。
out
主要是用來控制管理輸出的緩沖區(buffer)和輸出流(output stream)。
void
clear( ) 清除輸出緩沖區的內容
void
clearBuffer( ) 清除輸出緩沖區的內容
void
close( ) 關閉輸出流,清除所有的內容
int
getBufferSize( ) 取得目前緩沖區的大小(KB)
int
getRemaining( ) 取得目前使用后還剩下的緩沖區大小(KB)
boolean isAutoFlush( ) 回傳
true
表示緩沖區滿時會自動清除;
false
表示不會自動清除並且產生異常處理
4)exception對象
若要使用exception 對象時,必須在page 指令中設定:<%@ page isErrorPage=
"true"
%>才能使用。
exception提供的三個方法:
getMessage()
getLocalizedMessage()
printStackTrace(
new
java.io.PrintWriter(
out
))
5)config 對象
config 對象里存放着一些Servlet 初始的數據結構。
config 對象實現於javax.servlet.ServletConfig 接口,它共有下列四種方法:
public
String getInitParameter(name)
public
java.util.Enumeration getInitParameterNames( )
public
ServletContext getServletContext()
public
Sring getServletName()
例子:
1.范圍對象比較
<% pageContext 或request 或session 或application.setAttribute(
"name"
,
"maxwell"
);
pageContext.setAttribute(
"sex"
,
"m"
);
%>
2.輸出對象
out
<%
out
.println(
"Hello JSP!"
);%>
<%System.
out
.println(
"Hello JSP!"
);%>
getBufferSize()
//tomcat default:12k
getRemaining()
flush()
clearBuffer()
3.request對象
request:
getProtocol()
getMethod()
getHeader(
"User-Agent"
)
getCookies()
getRequestURI()
getRequestURL()
getContextPath()
getServletPath()
getPathInfo()
getQueryString()
isRequestedSessionIdFromCookie()
isRequestedSessionIdFromURL()
isRequestedSessionIdValid()
getLocalPort(),getRemotePort()
getRequestDispatcher(),setCharacterEncoding(),getInputStream()
4.session對象
session:
getId()
isNew()
invalidate()
setMaxInactiveInterval(10)
5.響應對象
response:
sendRedirect(
"third.jsp"
)
sendError(404,
"400 Error!"
)
6.應用對象
application:
log(
"some body visit our website..."
);
getMajorVersion()
getMinorVersion()
getServerInfo()
getRequestDispatcher(),getResourceAsStream(),getInitParameter()
pageContext:
getAttribute(
"name"
)
config:
getInitParameter(
"classNo"
)
getServletName()
page:
getClass()
************************************************************************************************
二、歡迎文件
1.缺省情況下,一個Web App中的 index.html, index.htm, index.jsp 可作為默認的歡迎文件.
當用戶請求沒有指明要訪問的資源時,Web Container會用歡迎文件響應客戶端請求.
2.手工設置歡迎文件:
web.xml
找welcome.jsp,沒找到,繼續往下找
<welcome-file-list>
<welcome-file>/welcome.jsp</welcome-file>
<welcome-file>/welcome1.jsp</welcome-file>
<welcome-file>/welcome2.jsp</welcome-file>
</welcome-file-list>
三、MVC
MVC: Model-View-Controller (用戶交互過程:輸入、處理、輸出)
WEB應用的MVC;優化Web App的結構,使用MVC模式
Model 1: JSP + JavaBean(EJB)
Model 2: Servlet + JSP + JavaBean(EJB)------>MVC
體系結構
設計模式
具體問題提出具體的解決辦法
習慣用法
Day4
內容要點: 1 實現文件上傳 2 數據驗證 3 分頁實現
*****************************************************************************************
一、文件上傳
1.表單形式
<form action=
""
method=
"POST"
enctype=
"multipart/form-data"
>
file:<input type=
"file"
name=
"file"
/><br/>
<input type=
"submit"
/>
</form>
2.使用HttpMonitor工具:
查看文件上傳時,請求的內容。
3.服務器端對上傳文件的處理
例子
fileupload
處理步驟(待補充)
知識點:
1)通過HttpServletRequest來傳送文件內容
2)處理request頭,字符串的分析
3)java.io.File API的使用
*****************************************************************************************
二、數據驗證
如何完成Web App中的數據驗證工作
1)客戶端校驗:
輸入域不能為空,只能是數字,數據長度大於5等等
JavaScript客戶端完成(驗證框架,負責客戶端方面的驗證)
2)服務器端校驗:
例如:后台數據庫要求提交數據唯一性
Java服務器端完成(沒有現成的框架,因為不同的項目有不同的業務規則)
重點:
1)分清楚什么情況下使用客戶端校驗,什么情況下使用服務器端校驗
***************************************************************************************
三、數據分頁
查詢數據庫時,如果滿足條件的記錄很多,該如何返回給頁面?
1.客戶端分頁
同樣地,使用html/javascript等技術處理。甚至可以封裝成組件
2.服務器端分頁
非常重要的,在實際項目中非常需要————性能問題。
這需要結合JDBC/Hibernate/TopLink/EJB等技術實現。
查詢分頁
1)一次性從數據庫中查出所有信息,在內存中作分頁(緩存)
特點:速度非常快,消耗資源大(內存?)
2)分多次查詢數據庫,一次查詢的數據量就是一個頁面可以顯示的數據量
特點:消耗資源少,相對來說速度慢
3)折衷的方案(一次只取n頁,1<n<總頁數)(部分緩存)
特點:中庸之道(實現中,置換算法教難)
常見的分頁處理方法:定義如下幾個參數
rows:數據庫表中記錄總行數
select
count(*)
from
表名;
totalPage:總頁數 (導出屬性:可以由其他屬性計算而得)
int
totalPage = rows / size + 1;
size:每頁顯示的記錄數目 可定制,可寫死
curPageNo:當前頁 客戶端決定
startRowNo:當前頁在數據庫中的起始行號(導出屬性)
int
startRowNo = (curPageNo -1 ) * size;
練習:
重新改造Usermanager例子中的查詢所有的用戶的功能(使用分頁)
Day5
內容要點: 1 EL 2 JSTL
**************************************************************
一、EL(Expression Language----表達式語言)
為網頁美工而設,跟java語句相似;盡量減少java程序的依賴(不能要求美工使用java)
1.語法
表達式 vs. EL表達式語言(JSP2.0)
<%=name%> <=> ${name}
2.文字
在 EL 表達式中,數字、字符串、布爾值和
null
都可以被指定為文字值(常量)。
字符串可以用單引號或雙引號定界。布爾值被指定為
true
和
false
。
例子:
表達式 值
-----------------------------------------------------------------------
${-168.18} -168.18
${3.8e-18} 3.8e-18
//科學計數法
${3.14159265} 3.14159265
${
"Hello JSP EL!"
} Hello JSP EL! 等價於 <%=
"Hello JSP EL!"
%>
${
'Hello JSP EL...'
} Hello JSP EL...
${
true
}
//can be TRUE? true
${
false
}
//can be FALSE? false
${str==
null
}
true
//布爾值的表達式
3.EL 運算符
類別 運算符
-------------------------------------------------------------
算術運算符 +、 -、 *、 /(或 div)、 %(或 mod)
關系運算符 ==(或 eq)、 !=(或 ne)、 <(或 lt)
>(或 gt)、 <=(或 le)、 >=(或 ge)
邏輯運算符 &&(或 and)、 ||(或 or)、 !(或 not)
驗證運算符 empty
其中,empty 判斷一個變量是否為
null
或是否包含有效數據:
if
(name==
null
||name.equlas(
""
)) 等價於 ${empty name} ->
true
例子:
表達式 值
-------------------------------------------------------------
${3+5.1} 8.1
${
"Hello"
+
",Tarena!"
} 報錯!
// EL的"+"沒有字符串連接功能
${5*2} 10
${9.3/3} 3.1
${9.3 div 3} 3.1
${8 div 0} Infinity
// 表示無窮大
${9%2} 1
${9 mod 2} 1
${8*6>68?
"Yes"
:
"No"
} No
//三目表達式
<% String name=
""
;
request.setAttribute(
"name"
,name);
//如果沒有 setAttribute ,則必定是空
%>
${empty name}
true
//對范圍對象內的變量或對象進行判空
4.變量和JavaBean屬性數據輸出
表達式語言輸出變量,是到范圍對象(pageContext,request,session,application)中查找相應屬性。
而非直接在頁面中查找實例或局部變量。
表達式語言查找變量的順序是:
pageContext -> request -> session->application, 所有范圍都未找到時,賦值
null
5.存取器
[] ->輸出對象屬性值,輸出數組或集合中對應索引值
. ->輸出對象屬性值
例子:
<% SuperGirl girl =
new
SuperGirl(); girl.setName(
"Alice"
);
session.setAttribute(
"girl"
,girl); %>
//一定要有這句,設置成范圍對象
${girl[
"name"
]}
${girl[
'name'
]}
//拿屬性時,單引跟雙引等價
${girl.name}
//這種方法同樣可以
<% List aList =
new
ArrayList();
aList.add(
"China"
); aList.add(girl); aList.add(168.18);
session.setAttribute(
"aList"
, aList); %>
${aList[0]}
//使用下標來取值 "China"
${aList[1]}
//取得對象的引用地址 還可以嵌套:${aList[1]['name']}
${aList[3]}
//下標越界,不會報錯;只是取不出值
<% Map map =
new
HashMap();
map.put(
"name"
,
"Kitty"
); map.put(
"age"
,
"25"
); map.put(
"date"
,
new
Date());
map.put(
"aList"
, aList);
session.setAttribute(
"map"
, map); %>
${map.date} ${map[
"date"
]}
//這兩個等效
${map.aList[0]} ${map[
"aList"
][0]}
//這兩個也等效
${map.aList[1][name]}
//嵌套取值
6.隱含對象
el提供了自己的一套隱含對象,方便在頁面內對各種常用數據信息的訪問.
EL隱藏對象 JSP隱藏對象
--------------------------------------------------------------------------------
pageScope pageContext
requestScope request
sessionScope session
applicationScope appication
param: request.getParameter()
paramValues: 在提交表單里,有多個輸入域同名getParameterValues
header: request.getHeader() 按照key-value的形式取出;value:是一個String類型的值
headerValues 按照key-value的方式取出,但是headerValues里面的value是一個String類型的數組
cookie request.getCookies()
initParam context param
例子:
1)超女登記信息
enroll.html
<form action=
"index.jsp"
method=
"post"
>
<table border=
"1"
>
<tr><td>姓名:</td>
<td><input type=
"text"
name=
"name"
></td></tr>
<tr><td>年齡:</td>
<td><input type=
"text"
name=
"age"
></td></tr>
<tr><td>城市:</td>
<td><input type=
"text"
name=
"city"
></td> </tr>
<tr><td align=
"center"
colspan=
"2"
><input type=
"submit"
value=
"提交"
></td></tr>
</table>
</form>
index.jsp
<jsp:useBean id=
"SuperGirl"
class
=
"vo.SuperGirl"
scope=
"page"
></jsp:useBean>
<jsp:setProperty name=
"SuperGirl"
property=
"name"
value=
"${param.name}"
/>
<jsp:setProperty name=
"SuperGirl"
property=
"age"
value=
"${param.age}"
/>
<jsp:setProperty name=
"SuperGirl"
property=
"city"
value=
"${param.city}"
/>
<table border=
"1"
> <%
//把設置輸出出來 %>
<tr><td>姓名:</td>
<td>${SuperGirl.name}</td></tr>
<tr><td>年齡:</td>
<td>${SuperGirl.age}</td></tr>
<tr><td>城市:</td>
<td>${SuperGirl.city}</td></tr>
</table>
2)范圍對象
<% pageContext.setAttribute(
"name"
,
"page"
);
request.setAttribute(
"name"
,
"request"
);
session.setAttribute(
"name"
,
"session"
);
application.setAttribute(
"name"
,
"application"
); %>
${name}
// pageContext -> request -> session->application
${pageScope.name}
${requestScope.name}
${sessionScope.name}
${applicationScope.name}
3)paramValues
在enroll.html加入: 興趣
<table>
<input type=
"checkbox"
name=
"habit"
value=
"Reading"
/>讀書
<input type=
"checkbox"
name=
"habit"
value=
"Game"
/>游戲
<input type=
"checkbox"
name=
"habit"
value=
"Music"
/>音樂
</table>
//提交后,獲取輸入內容
${paramValues.habit[0]}
${paramValues.habit[1]}
${paramValues.habit[2]}
4)initParam
web.xml
...
<context-param>
<param-name>server</param-name>
<param-value>Tomcat5.5</param-value>
</context-param>
...
${initParam.server}
5)header
${header[
"host"
]}
${header[
"accept"
]}
${header[
"user-agent"
]}
7.可以自由設置是否支持表達式語言
<%@page isELIgnored=
"false"
%> :
default
:
false
可以使用EL,改成
true
之后,寫EL就會報錯
配置web.xml也可達到同樣的效果(同時存在,那種起作用?)
(禁用腳本和EL) 默認都是
false
...
<jsp-config>
<jsp-property-
group
>
<url-pattern>*.jsp</url-pattern>
<el-ignored>
true
</el-ignored>
//設置成所有jsp文件都禁用EL
<scripting-invalid>
true
</scripting-invalid>
//設置成禁用腳本
</jsp-property-
group
>
</jsp-config>
....
頁面的page指令設置isELIgnored屬性的優先級比web.xml中<el-ignored>設置的高(當然是范圍小的生效)
***************************************************************************************
二、JSTL(JSP Standard Tag Library )
減少java代碼,簡化頁面編寫;功能封裝,提高可重用性
1.如何使用JSTL
1)對於Java EE之前(即J2EE規范1.4及之前版本)
a、復制jstl的jar包(jstl.jar,standard.jar)到/WEB-INF/lib
b、在使用jstl功能的jsp頁面中增加指令
<%@taglib prefix=
"c"
uri=
"http://java.sun.com/jsp/jstl/core"
%> //核心標簽庫
<%@taglib prefix=
"x"
uri=
"http://java.sun.com/jsp/jstl/xml"
%>
<%@taglib prefix=
"fmt"
uri=
"http://java.sun.com/jsp/jstl/fmt"
%>
<%@taglib prefix=
"sql"
uri=
"http://java.sun.com/jsp/jstl/sql"
%> //數據庫標簽庫
<%@taglib prefix=
"fn"
uri=
"http://java.sun.com/jsp/jstl/functions"
%>
//prefix 表前綴(可改,但通常按這寫的用); uri 指向標簽庫的入口
2)Java EE規范把jstl作為規范的一部分
所以現在的jstl-1.2已經包含了原來的jstl.jar , standard.jar
2.core:核心標簽庫
一般用途
在JSTL中,一般用途的標簽主要是指具有輸出,設置變量,和錯誤處理等功能的標簽,他們在jsp中使用比較頻繁,它們有:
-----------
|a、<c:
set
>|
-----------
語法:<c:
set
value=
"value"
var
=
"varName"
[scope=
"{page|request|session|application}"
]/ >
<c:
set
value=
"value"
target=
"target"
property=
"propertyName"
/ >
這個標簽用於在某個范圍(page,request,session,application)里面設置特定的值
(默認為page),或者設置某個已經存在的javabean的屬性。
例子:
<c:
set
var
=
"counter"
value=
"200"
/>
${counter}
//輸出
<c:
set
var
=
"tarena"
>Tarena It Traning Ltd.</c:
set
>
${tarena}
可以指定范圍,默認是page
<c:
set
value=
"20"
var
=
"maxIdelTime"
scope=
"session"
/>
${maxIdelTime}
設置JavaBean的值
<jsp:useBean id=
"girl"
class
=
"vo.SuperGirl"
/>
<c:
set
value=
"Shirly"
target=
"${girl}"
property=
"name"
/>
<td>girl.name</td>
<td>${girl.name}</td>
--------------
|b、<c:remove>|
--------------
語法:
<c:remove
var
=
"varName"
[scope=
"{page|request|session|application}"
]/ >
它的作用是刪除某個變量或者屬性。
例子:
<c:
set
value=
"10000"
var
=
"maxUser"
scope=
"application"
/>
<c:
set
value=
"10"
var
=
"count"
scope=
"session"
/>
<c:
set
value=
"10"
var
=
"count"
/>
${maxUser}
${count}
<c:remove
var
=
"maxUser"
scope=
"application"
/>
<c:remove
var
=
"count"
scope=
"session"
/>
${maxUser}
${count}
-----------
|c、<c:
out
>|
-----------
語法:<c:
out
value=
"value"
[escapeXml]=
"{true|false}"
[
default
=
"defaultValue"
]/>
注意:escapeXml的作用是是否將代碼交給xml解析器解釋,
true
為交給xml解析器解釋(默認),
false
為交給瀏覽器解釋。
default
定義缺省值。
例子:
<c:
set
var
=
"sessionZhang3"
value=
"zhang3-s"
scope=
"session"
/>
<c:
set
var
=
"table"
value=
"<table><tr><td>sessionZhang</td></tr></table>"
scope=
"page"
/>
<c:
set
var
=
"requestZhang3"
value=
"zhang3-r"
scope=
"request"
/>
<c:
out
value=
"以下輸出前面設置的屬性<br>"
escapeXml=
"false"
/>
<td colspan=2>
<c:
out
value=
"${sessionZhang3}"
/><br>
<c:
out
value=
"${table}"
escapeXml=
"false"
/><br>
//輸出表格;escapeXml="true"時只顯示字符串
<c:
out
value=
"${requestZhang3}"
/><br>
<c:
out
value=
"${nodefined}"
default
=
"沒有nodefined這個變量"
/>
</td>
-------------
|d、<c:
catch
>|
-------------
它的作用是捕捉由嵌套在它里面的標簽所拋出來的異常。類似於<%
try
{}
catch
{}%>
語法:<c:
catch
[
var
=
"varName"
]>nested actions</c:
catch
>
例子:
<c:
catch
var
=
"error"
><% Integer.parseInt(
"abc"
); %></c:
catch
>
<%
try
{ Integer.parseInt(
"abc"
); }
catch
(Exception error) { } %>
//等價
<c:
out
value=
"${error}"
/>
<c:
out
value=
"${error.message}"
/>
<c:
out
value=
"${error.cause}"
/>
控制語句:
-----------
|a、 <c:
if
>|
-----------
語法:
<c:
if
test=
"testCondition"
var
=
"varName"
[scope=
"{page|request|session|application}"
]>
Body內容
</c:
if
>
// 注:沒有 else
例子:
<c:
set
var
=
"age"
value=
"16"
/>
<c:
if
test=
"${age<18}"
>
<h1 align=center>您尚未成年,不能進入游戲中心!</h1>
</c:
if
>
--------------
|b、<c:choose>|
--------------
例子:
<c:
set
var
=
"tax"
value=
"5000"
/>
<c:choose>
<c:when test=
"${tax <=0}"
>
您今年沒有納稅!
</c:when>
<c:when test=
"${tax<=1000&&tax>0}"
>
您今年繳納的稅款為${tax},加油!
</c:when>
<c:when test=
"${tax<=3000&&tax>1000}"
>
您今年繳納的稅款為${tax},再接再勵哦!
</c:when>
<c:otherwise>
您今年納稅超過了3000元,多謝您為國家的繁榮富強作出了貢獻!
</c:otherwise>
</c:choose>
---------------
|c、<c:forEach>| 循環
---------------
語法: <c:forEach [
var
=
"varName"
] items=
"collection"
[varStatus=
"varStatusName"
]
[begin=
"begin"
] [end=
"end"
] [step=
"step"
]>
Body 內容
</c:forEach>
items:需要迭代的集合;
var
:迭代時取集合里的值;
例子:
<% List aList=
new
ArrayList();
aList.add(
"You"
); aList.add(
"are"
); aList.add(
"a"
);
aList.add(
"beautiful"
); aList.add(
"girl"
);
request.setAttribute(
"aList"
,aList); %>
<center> <table border=1>
<c:forEach
var
=
"word"
items=
"${aList}"
>
<tr><td>${word }</td></tr>
</c:forEach>
</table> </center>
<c:forEach items=
'${header}'
var
=
'h'
>
<tr>
<td><li>Header name:<c:
out
value=
"${h.key}"
/></li></td>
<td><li>Header value:<c:
out
value=
"${h.value}"
/></li></td>
</tr>
</c:forEach>
另外一種用法: (類似
for
循環)
<c:forEach
var
=
"count"
begin=
"10"
end=
"100"
step=
"10"
>
<tr><td>
<c:
out
value=
"${count}"
/><br>
</td></tr>
</c:forEach>
URL
---------------
|a、<c:import> |
---------------
相當於<jsp:include>
<c:import url=
"footer.jsp"
charEncoding=
"GBK"
>
<c:param name=
"name"
value=
"Java"
/>
</c:import>
-----------
|b、<c:url>|
-----------
用於構造URL,主要的用途是URL的重寫。
<c:url
var
=
"footer1"
value=
"footer.jsp"
/>
<c:url
var
=
"footer2"
value=
"footer.jsp"
scope=
"page"
>
<c:param name=
"name"
value=
"Sofie"
/>
</c:url>
<c:
out
value=
"${footer1}"
/>
<c:
out
value=
"${footer2}"
/>
<c:url
var
=
"next"
value=
"next.jsp"
/>
<a href=
"${next}"
>next</a><br>
等價於
<a href=
"<c:url value='next.jsp'/>"
>next</a>
//在 Html 里可嵌套 JSTL
----------------
|c、<c:redirect>|
----------------
//等價於 <jsp:forward>
<c:redirect url=
"${footer2}"
/>
例如:
<c:url
var
=
"next"
value=
"next.jsp"
/>
<c:redirect url=
"${next}"
/>
3.SQL
<sql:setDataSource>
<sql:query>
<sql:update>
<sql:param>
<!-- 設置數據源 -->
<%@page contentType=
"text/html; charset=GBK"
%>
<%@taglib uri=
"http://java.sun.com/jsp/jstl/core"
prefix=
"c"
%>
<%@taglib uri=
"http://java.sun.com/jsp/jstl/sql"
prefix=
"sql"
%>
<sql:setDataSource
var
=
"ds"
driver=
"com.mysql.jdbc.Driver"
url=
"jdbc:mysql://localhost:3306/tarena"
user=
"root"
password=
"11111111"
/>
a、查詢
<sql:query
var
=
"rs"
dataSource=
"${ds}"
sql=
"select * from users"
></sql:query>
<c:forEach
var
=
"user"
items=
"${rs.rows}"
>
<tr>
<td>${user.userid}</td>
<td>${user.username}</td>
<td>${user.password}</td>
<td>${user.role}</td>
</tr>
</c:forEach>
b、插入記錄
<sql:update dataSource=
"${ds}"
sql=
"insert into users values(101,'maxwell','123','admin')"
var
=
"i"
></sql:update>
<hr>插入${i}條記錄.
c、更新記錄
<sql:update dataSource=
"${ds}"
sql=
"UPDATE users SET username='Gavin King' WHERE userid=101"
var
=
"i"
></sql:update>
<hr>更新${i}條記錄.
<sql:param>
作用:設置sql語句中
"?"
表示的占位符號的值。
<sql:update dataSource=
"${ds}"
sql=
"UPDATE users SET username=? WHERE userid=?"
var
=
"i"
>
<sql:param value=
"Rod Johnson"
/>
//設第一個問號
<sql:param value=
"100"
/>
//設第二個問號
</sql:update>
參數等價於
//pstmt.setString(1,"Rod Johnson");
//pstmt.setInt(2,100);
四、示例下載
五、面試題
1、請完成產品功能的添加與展示,產品Product(編號Id,名稱Title,類型Type,狀態1有貨0缺貨),數據庫名Mall
2、實現在手機端訪問
六、內測
考試題下載