一、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 '' 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 ('', '功夫', '19.9', '');
INSERT INTO `dvd` VALUES ('', '异形', '88.1', '');
INSERT INTO `dvd` VALUES ('', '形状', '99.1', '');
INSERT INTO `dvd` VALUES ('', '中国', '99.9', '');
INSERT INTO `dvd` VALUES ('', '有形', '34.6', '');
INSERT INTO `dvd` VALUES ('', '食神', '14.6', '');

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);

四、示例下载

136_1_展示示例

136_2_添加示例

五、面试题

1、请完成产品功能的添加与展示,产品Product(编号Id,名称Title,类型Type,状态1有货0缺货),数据库名Mall

2、实现在手机端访问

六、内测

考试题下载

JavaEE学习总结(十三)—JavaWeb、JSP、Servlet与DVD管理系统的更多相关文章

  1. 暑假学习计划:Day_1.JSP&Servlet&Tocat 环境搭建到基础的认识。

    1.了解JSP和Servlet(百度了解即可). 2.了解B/S和C/S.分别是  浏览器/服务器  和  客户端/服务器. 其中 B/S 被称为瘦模式(主流模式). 3.了解并下载Tomcat服务器 ...

  2. JSP+Servlet开发物流管理系统 源码

    开发环境: Windows操作系统开发工具:Myeclipse+Jdk+Tomcat+MYSQL数据库 运行效果图:

  3. (转)JavaWeb学习总结(十三)——使用Session防止表单重复提交

    如何防止表单重复提交 在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复 ...

  4. 新手学习JSP+Servlet笔记一

    作为一个新手,初次接触jsp,servlet,习惯了后台的开发,前台的知识一窍不通,利用闲暇时间,给自己补补,从MyEclipse开始. 安装好MyEclipse之后,没有安装程序的可以下载 http ...

  5. JSP学习笔记(5)——Servlet、监听器、过滤器、MVC模式介绍

    MVC模式 在讲解Servlet前,先介绍一下MVC模式. M:model 模型,相当于数据层,用于存放数据,如一个Java中的一个bean类 V:view 视图,相当于页面层,用于显示数据,如一个网 ...

  6. javaweb练手项目jsp+servlet简易购物车系统

    简易购物车项目 这是一个用intellij IDEA做的简易的javaweb项目,开发环境使用的jdk1.8和tomcat8以及mysql数据库. 1.项目开发准备: 创建github仓库 项目框架搭 ...

  7. JSP&Servlet学习手册

    JSP&Servlet学习手册 沙琪玛 书 目录 JSP 指令... 3 书写方式... 3 指令列表... 3 JSP 内置对象... 3 内置对象特点... 3 常用内置对象... 3 o ...

  8. 软件架构设计学习总结(18):MVC三层架构在各框架(jsp+servlet + Struts1+ Struts2+ springMVC)中的特征

    1.基于web开发中最原始的jsp+Servlet   图形化理解jsp+servlet结构: 1.从结构上分析jsp+servlet图解原理: 在基于mvc设计模式下的最原始的jsp+Servlet ...

  9. JavaWeb学习总结第四篇--Servlet开发

    Servlet开发 用户在浏览器中输入一个网址并回车,浏览器会向服务器发送一个HTTP请求.服务器端程序接受这个请求,并对请求进行处理,然后发送一个回应.浏览器收到回应,再把回应的内容显示出来.这种请 ...

随机推荐

  1. [福大软工] Z班——Alpha现场答辩情况汇总

    Alpha现场答辩 小组互评(文字版) 各组对于 麻瓜制造者 的评价与建议 队伍名 评价与建议 *** 界面较友好,安全性不足,功能基本完整.希望能留下卖家的联系方式而不是在APP上直接联系,APP上 ...

  2. Flask-论坛开发-3-数据库

    对Flask感兴趣的,可以看下这个视频教程:http://study.163.com/course/courseLearn.htm?courseId=1004091002 1. SQLAlchemy ...

  3. shell脚本--分支、条件判断

    在看选择判断结构之前,请务必先看一下数值比较与文件测试 if....else... #!/bin/bash #文件名:test.sh score=66 # //格式一 if [ $score -lt ...

  4. Smarty 变量修饰器

    为了更方便的实现 功能与显示分离,通常会用 smarty 将功能代码中的数据 assign 到页面中,在页面中合理使用 smarty 的修饰方法,会使页面显示更美观! 一个数据可同时使用多个修饰函数, ...

  5. 临时关闭Mysql ONLY_FULL_GROUP_BY

    /** * @author lcc807@ikoo8.com * * 临时关闭Mysql ONLY_FULL_GROUP_BY */ function closeSqlFullMode(){ DB:: ...

  6. 关于utf8mb4的学习了解笔记

    占位下班写 据说可以存储emoji ..妈蛋今天大神又秀我一脸 大概意思是,我们整个后端数据库,最近都升级了编码格式.从以前久的utf-8整个升级到了utf8mb4的格式 该格式支持emoji表情. ...

  7. Lodop强制分页LODOP.NewPage()和LODOP.NewPageA()

    使用Lodop打印控件打印时,有自动分页,有手动强制分页,也可以两者结合使用,在使用两者结合的时候注意LODOP.NewPage()和LODOP.NewPageA()的区别,如果前面打印项自动分页不止 ...

  8. [代码]--python爬虫联系--爬取成语

    闲来无事,玩了个成语接龙,于是就想用python爬取下成语网站上的成语,直接上代码: #coding=utf-8 import requests from bs4 import BeautifulSo ...

  9. Django实现websocket完成实时通讯,聊天室,在线客服等

    一 什么是Websocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在WebS ...

  10. Java8的flatMap如何处理有异常的函数

    Java8的flatMap函数,作用是:如果有值,为其执行mapping函数返回Optional类型返回值,否则返回空Optional. 见到的映射函数往往都只有一句话,连大括号都不需要加的,如下: ...