Web容器处理JSP请求有三个阶段:转译(translate)——>编译(compile)——>解释(interpret)
客户端发出请求
Web容器将JSP转译成Servlet源代码
Web容器将产生的源代码进行编译
Web容器加载编译后的代码并执行
把执行结果响应至客户端
第一次请求之后,Web容器可以重用已经编译好的字节码文件。
注意:如果对JSP文件进行了修改,Web容器会重新对JSP文件进行翻译和编译。
创建Web项目JSPElementsDemo:
在web目录创建demo01.html页面:
在web目录里创建demo02.jsp页面:
demo02.jsp页面代码:
<%-- 页面指令 --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 标签库指令 --%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
demo02
<%-- 包含指令 --%>
<%@include file="demo01.html"%>
<%-- 脚本元素 --%>
<%
String msg1 = "Welcome to JSP World!";
%>
<%-- 表达式元素 --%>
<%= msg1 %>
<%-- 采用标签库和表达式语言(EL:Expression Language)--%>
欢迎访问本网站~
本网站不欢迎你~
欢迎访问本网站~
本网站不欢迎你~
<%-- 计算1+2+3+...+100的值 --%>
<%-- (1)脚本方法 --%>
<%
int num=0;
for(int i=1;i<=100;i++){
num+=i;
}
%>
<%= num %>
<%-- (2)标签方法 --%>
1+2+3...+100=${sum}
1+2+3...+100=
启动服务器访问http://localhost:8080/JSPElementsDemo/demo02.jsp:
包含动作元素jsp:include演示:
启动服务器,访问http://localhost:8080/JSPElementsDemo/demo03.jsp:
转发动作元素jsp:forward演示:
在src里创建net.hw.bean包,在里面创建User实体类:
User实体代码:
package net.xsp.bean;
/**
* 功能:用户实体类
* 日期:2019年9月12日
*/
public class User {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
任务:不用useBean动作元素,用脚本元素与表达式元素来完成上述任务。
<%@ page import="net.xsp.bean.User" %>
<%--
Created by IntelliJ IDEA.
User: Stranger
Date: 2019/9/12
Time: 10:19
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
demo07
<%-- 创建用户实体对象 --%>
<%-- 设置实体属性 --%>
<%-- 获取实体属性值 --%>
id:
username:
passord:
<%-- 输出用户实体对象 --%>
<%= user %>
<%-- java脚本形式 --%>
<%
User u = new User();
u.setId(2);
u.setUsername("root");
u.setPassword("654321");
%>
id: <%= u.getId() %>
username: <%= u.getUsername() %>
password: <%= u.getPassword() %>
课后作业:编写JSP页面,计算2000~2019年期间有几个闰年。使用表达式输出结果。
JSP隐含对象是 Web 容器创建的一组对象
JSP隐含对象的名称是JSP 的保留字
JSP隐含对象是可以直接在JSP页面使用的对象,无需使用“new”获取实例
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
注册
用户注册
2.在web目录里创建处理注册页面do_register.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
显示注册信息
<%
// 设置请求对象字符编码格式
request.setCharacterEncoding("utf-8");
// 读取用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
// 读取渠道复选框的值
String[] channels = request.getParameterValues("channel");
StringBuffer buffer = new StringBuffer();
if (channels != null) {
for (String channel: channels) {
buffer.append(channel + " ");
}
}
%>
用户注册信息
用户名: <%= username %>
密 码: <%= password %>
渠 道: <%= buffer.toString() %>
课堂练习:给用户注册页面添加表单校验,要求用户名与密码非空。
其实,我们可以将表单校验脚本提取出来创建一个js文件,然后导入页面来使用。
删除register.jsp页面里的脚本元素
导入check.js脚本
课后作业:注册页面信息的获取。给出了register.jsp,要求编写do_register.jsp,获取注册信息并显示。
1.在web目录里创建登录页面login.jsp
2.在web目录里创建登录处理页面do_login.jsp
3.在web目录里创建登录成功页面success.jsp
4.在web目录里创建登录失败页面failure.jsp
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 将会失效
void setAttribute():设置session对象的属性
void getAtrribute():获取session对象的属性
package net.xsp.bean;
/**
* 功能:用户实体类
* 作者:
* 日期:2019年10月10日
*/
public class User {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
UserDao
package net.xsp.dao;
import net.xsp.bean.User;
/**
* 功能:用户数据访问接口
* 作者:
* 日期:2019年10月10日
*/
public interface UserDao {
/**
* 登录方法
*
* @param username
* @param password
* @return true - 登录成功;false - 登录失败
*/
boolean login(String username, String password);
/**
* 插入方法
*
* @param user
* @return 插入记录数
*/
int insert(User user);
}
UserDaoImpl
package net.xsp.dao.impl;
import net.xsp.bean.User;
import net.xsp.dao.UserDao;
import net.xsp.dbutil.ConnectionManager;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 功能:用户数据访问接口实现类
* 作者:
* 日期:2019年10月10日
*/
public class UserDaoImpl implements UserDao {
/**
* 登录方法
*
* @param username
* @param password
* @return true - 登录成功;false - 登录失败
*/
@Override
public boolean login(String username, String password) {
// 声明标志变量
boolean flag = false;
// 声明数据库连接
Connection conn = null;
try {
// 获取数据库连接
conn = ConnectionManager.getConnection();
// 定义SQL字符串
String strSQL = "select * from t_user where username = ? and password = ?";
// 创建预备语句对象
PreparedStatement pstmt = conn.prepareStatement(strSQL);
// 设置占位符的值
pstmt.setString(1, username);
pstmt.setString(2, password);
// 执行SQL查询,返回结果集
ResultSet rs = pstmt.executeQuery();
// 判断结果集里是否有记录
if (rs.next()) {
flag = true;
} else {
flag = false;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭数据库连接
ConnectionManager.closeConn(conn);
}
// 返回标志变量
return flag;
}
/**
* 插入方法
*
* @param user
* @return 插入记录数
*/
@Override
public int insert(User user) {
// 声明插入记录数变量
int count = 0;
// 声明数据库连接
Connection conn = null;
try {
// 获取数据库连接
conn = ConnectionManager.getConnection();
// 定义SQL字符串
String strSQL = "insert into t_user (username, password) values (?, ?)";
// 创建预备语句对象
PreparedStatement pstmt = conn.prepareStatement(strSQL);
// 设置占位符的值
pstmt.setString(1, user.getPassword());
pstmt.setString(2, user.getPassword());
// 执行SQL更新,返回更新记录数
count = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭数据库连接
ConnectionManager.closeConn(conn);
}
// 返回插入记录数
return count;
}
}
ConnectionManager
package net.xsp.dbutil;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* 功能:数据库链接管理类
* 作者:
* 日期:2019年10月10日
*/
public class ConnectionManager {
// 定义连接数据库的参数值
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/xspdb";
private static final String USER = "root";
private static final String PASSWORD = "1";
/**
* 私有化构造方法,拒绝实例化
*/
private ConnectionManager() {
}
/**
* 获取数据库连接静态方法
*
* @return 数据库连接
*/
public static Connection getConnection() {
// 声明数据库连接
Connection conn = null;
try {
// 安装数据库驱动程序
Class.forName(DRIVER);
// 获取数据库连接
conn = DriverManager.getConnection(URL, USER, PASSWORD);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
// 返回数据库连接
return conn;
}
/**
* 关闭数据库连接静态方法
*
* @param conn 数据库连接
*/
public static void closeConn(Connection conn) {
if (conn != null) {
try {
if (!conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
LoginServlet
package net.xsp.servlet;
import net.xsp.dao.UserDao;
import net.xsp.dao.impl.UserDaoImpl;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.URLEncoder;
@WebServlet(name = "LoginServlet", value = "/login")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 设置请求对象字符编码
request.setCharacterEncoding("utf-8");
// 获取表单提交的数据
String username = request.getParameter("username");
String password = request.getParameter("password");
// 创建用户数据访问对象
UserDao userDao = new UserDaoImpl();
//获取请求对应的会话
HttpSession session = request.getSession();
// 判断登录是否成功
if (userDao.login(username, password)) {
// 清除session里可能存在的errMsg属性
if (session.getAttribute("errMsg") != null) {
session.removeAttribute("errMsg");
}
// 采用从定向,跳转到登录成功页面
response.sendRedirect("success.jsp?username=" + URLEncoder.encode(username,"utf-8"));
} else {
// 设置session里的errMsg属性
session.setAttribute("errMsg", "用户名或密码错误,请重新登录");
// 采用从定向,跳转到登录页面
response.sendRedirect("login.jsp");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
}
login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
用户登录
用户登录
<%
String errMsg = (String) session.getAttribute("errMsg");
if (errMsg != null) {
out.println("" + new String(errMsg.getBytes("ISO-8859-1"), "utf-8") + "
");
}
%>
do_login.jsp
<%@ page import="java.sql.*" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page import="net.xsp.dbutil.ConnectionManager" %>
<%@ page import="net.xsp.dao.UserDao" %>
<%@ page import="net.xsp.dao.impl.UserDaoImpl" %>
<%
// 设置请求对象字符编码
request.setCharacterEncoding("utf-8");
// 获取表单提交的数据
String username = request.getParameter("username");
String password = request.getParameter("password");
// 创建用户数据访问对象
UserDao userDao = new UserDaoImpl();
// 判断登录是否成功
if (userDao.login(username, password)) {
// 清除session里可能存在的errMsg属性
if (session.getAttribute("errMsg") != null) {
session.removeAttribute("errMsg");
}
// 采用从定向,跳转到登录成功页面
response.sendRedirect("success.jsp?username=" + URLEncoder.encode(username, "utf-8"));
} else {
// 设置session里的errMsg属性
session.setAttribute("errMsg", "用户名或密码错误,请重新登录");
// 采用从定向,跳转到登录页面
response.sendRedirect("login.jsp");
}
/**
* 2
*/
// try {
// // 获取数据库连接
// Connection conn = ConnectionManager.getConnection();
// // 定义SQL字符串
// String strSQL = "select * from t_user where username = ? and password = ?";
// // 创建预备语句对象
// PreparedStatement pstmt = conn.prepareStatement(strSQL);
// // 设置占位符的值
// pstmt.setString(1, username);
// pstmt.setString(2, password);
// // 执行SQL查询,返回结果集
// ResultSet rs = pstmt.executeQuery();
// // 判断结果集里是否有记录
// if (rs.next()) {
// // 清除session里可能存在的errMsg属性
// if (session.getAttribute("errMsg") != null) {
// session.removeAttribute("errMsg");
// }
// // 采用从定向,跳转到登录成功页面
// response.sendRedirect("success.jsp?username=" + URLEncoder.encode(username, "utf-8"));
// } else {
// // 设置session里的errmsg属性
// session.setAttribute("errMsg", "用户名或密码错误,请重新登录");
// // 采用从定向,跳转到登录页面
// response.sendRedirect("login.jsp");
// }
// } catch (SQLException e) {
// e.printStackTrace();
// }
/**
* 1
*/
// 定义连接数据库的参数
// final String DRIVER = "com.mysql.jdbc.Driver";
// final String URL = "jdbc:mysql://localhost:3306/xspdb";
// final String USER = "root";
// final String PASSWORD = "1";
// try {
// // 安装数据库驱动程序
// Class.forName(DRIVER);
// // 获取数据库链接
// Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
// // 定义SQL字符串
// String strSQL = "select * from t_user where username = ? and password = ?";
// // 创建预备语句对象
// PreparedStatement pstmt = conn.prepareStatement(strSQL);
// // 设置占位符
// pstmt.setString(1, username);
// pstmt.setString(2, password);
// // 执行SQL查询,返回结果集
// ResultSet rs = pstmt.executeQuery();
// // 判断结果集是否有记录
// if (rs.next()) {
// // 移除session可能存在的errMsg属性
// session.removeAttribute("errMsg");
// // 采用从定向,跳转到登录页面
// response.sendRedirect("success.jsp?username=" + URLEncoder.encode(username, "utf-8"));
// } else {
// // 设置session里的errmsg属性
// session.setAttribute("errMsg", "用户名或密码错误,请重新登录");
// // 采用从定向,跳转到登录页面
// response.sendRedirect("login.jsp");
// }
// } catch (ClassNotFoundException e) {
// e.printStackTrace();
// } catch (SQLException e) {
// e.printStackTrace();
// }
%>
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
登录成功
<%= request.getParameter("username") %>, 登录成功!
会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
个性化设置(如用户自定义设置、主题等)
浏览器行为跟踪(如跟踪分析用户行为等)
<%--
Created by IntelliJ IDEA.
User: Stranger
Date: 2019/10/17
Time: 8:21
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
用户登录
用户登录
<%
String uname = "";
String upwd = "";
String saveuname = "";
String saveupwd = "";
Cookie[] cookies = request.getCookies();
for (Cookie cookie: cookies) {
if (cookie.getName().equals("uname")) {
uname = cookie.getValue();
}
if (cookie.getName().equals("upwd")) {
upwd = cookie.getValue();
}
if (cookie.getName().equals("saveuname")) {
saveuname = cookie.getValue();
}
if (cookie.getName().equals("saveupwd")) {
saveupwd = cookie.getValue();
}
}
String errMsg = (String) session.getAttribute("errMsg");
if (errMsg != null) {
errMsg = new String(errMsg.getBytes("iso-8859-1"), "utf-8");
out.print("");
}
%>
do_login.jsp页面
<%
// 获取表单提交的数据
String username = request.getParameter("username");
String password = request.getParameter("password");
String[] choie = request.getParameterValues("save");
// 判断用户是否登录成功
if (username.equals("root") && password.equals("12345")) {
// 创建Cookie对象
Cookie uname = new Cookie("uname", username);
Cookie upwd = new Cookie("upwd", password);
Cookie saveuname = new Cookie("saveuname", "no");
Cookie saveupwd = new Cookie("saveupwd", "no");
if (choie != null) {
if (choie.length == 2) {
saveuname.setValue("yes");
saveupwd.setValue("yes");
} else {
saveuname.setValue("yes");
}
}
// 创建Cookie对象写入客户端
response.addCookie(uname);
response.addCookie(upwd);
response.addCookie(saveuname);
response.addCookie(saveupwd);
session.removeAttribute("errMsg");
// 采用重定向,跳转到登录成功页面
response.sendRedirect("success.jsp");
} else {
Cookie saveuname = new Cookie("saveuname", "no");
Cookie saveupwd = new Cookie("saveupwd", "no");
response.addCookie(saveuname);
response.addCookie(saveupwd);
session.setAttribute("errMsg", "用户名或密码错误,请重新登录!");
// 采用重定向,跳转到登录页面
response.sendRedirect("login.jsp");
}
%>
success.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
登录成功
<%
String uname = "";
Cookie[] cookies = request.getCookies();
for (Cookie cookie: cookies) {
if (cookie.getName().equals("uname")) {
uname = cookie.getValue();
}
}
%>
<%= new String(uname.getBytes("iso-8859-1"), "utf-8") %>,登录成功!
package net.xsp.bean;
public class User {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
login.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
用户登录
<%
String errMsg = (String) session.getAttribute("errMsg");
if (errMsg != null) {
// errMsg = new String(errMsg.getBytes("ISO-8859-1"), "utf-8");
out.print("");
}
%>
do_login.jsp页面
<%@ page import="net.xsp.bean.User" %>
<%@ page contentType="text/html; charset=utf-8" %>
<%
// 设置请求对象字符编码
request.setCharacterEncoding("utf-8");
// 获取登录表单数据
String username = request.getParameter("username");
String password = request.getParameter("password");
// 判断登录是否成功
if (username.equals("root") && password.equals("12345")) {
// 创建用户对象
User user = new User();
// 设置用户对象属性
user.setUsername(username);
user.setPassword(password);
// 保存登录用户信息
session.setAttribute("LOGINED_USER", user);
// 清除session里的errMsg属性
if (session.getAttribute("errMsg") != null) {
session.removeAttribute("errMsg");
}
// 采用重定向,跳转到首页
response.sendRedirect("index.jsp");
} else {
// 在session里创建errMsg属性
session.setAttribute("errMsg", "用户名或密码错误,请重新登录!");
// 采用重定向,跳转到登录页面
response.sendRedirect("login.jsp");
}
%>
add_news.jsp页面
<%@ page import="net.xsp.bean.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
添加新闻
<%-- 利用session实现登录验证 --%>
<%
User user = (User) session.getAttribute("LOGINED_USER");
if (user == null) {
// 在session里面创建errMsg属性
session.setAttribute("errMsg", "要访问添加新闻页面,请先登录!");
// 从定向跳转
response.sendRedirect("login.jsp");
} else {
// 删除session里的errMsg属性
if (session.getAttribute("errMsg") != null) {
session.removeAttribute("errMsg");
}
}
%>
添加新闻
此页面还在建设中......
启动服务器,查看运行效果
在浏览器地址栏里输入添加新闻页面网址,然后敲回车确认:
重启服务器,直接访问http://localhost:8080/SessionDemo//add_news.jsp:
void setAttribute(String key, Object value):以键/值的方式,将一个对象的值存放到application中
Object getAttribute(String key):根据键去获取application中存放对象的值
package net.xsp.bean;
/**
* Created by xsping on 2019/10/17
*/
public class User {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
@Override
public boolean equals(Object obj) {
return username.equals(((User) obj).getUsername())
&& password.equals(((User) obj).getPassword());
}
}
UserDao接口
package net.xsp.dao;
/**
* 功能:用户数据访问接口
* 作者:
* 日期:2019年10月24日
*/
public interface UserDao {
/**
* 登录方法
*
* @param username
* @param password
* @return
*/
boolean login(String username, String password);
}
用户数据访问接口实现类UserDaoImpl
package net.xsp.dao.impl;
import net.xsp.dao.UserDao;
import net.xsp.dbutil.ConnectionManager;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 功能:用户数据访问接口实现类
* 作者:
* 日期:2019年10月24日
*/
public class UserDaoImpl implements UserDao {
@Override
public boolean login(String username, String password) {
// 定义标识变量
boolean flag = false;
// 获取数据库连接
Connection conn = ConnectionManager.getConnection();
// 定义SQL字符串
String strSQL = "select * from t_user where username = ? and password = ?";
try {
// 创建预备语句对象
PreparedStatement pstmt = conn.prepareStatement(strSQL);
// 设置占位符的值
pstmt.setString(1, username);
pstmt.setString(2, password);
// 执行SQL查询,返回结果集
ResultSet rs = pstmt.executeQuery();
// 判断结果集里是否有记录
if (rs.next()) {
flag = true;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭数据库连接
ConnectionManager.closeConn(conn);
}
// 返回标识变量
return flag;
}
}
数据库连接管理类
package net.xsp.dbutil;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* 功能:数据库连接管理类
* 作者:
* 日期:2019年10月24日
*/
public class ConnectionManager {
// 定义连接数据库的参数值
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/xspdb";
private static final String USER = "root";
private static final String PASSWORD = "1";
/**
* 私有化构造方法,拒绝实例化
*/
private ConnectionManager() {
}
/**
* 获取数据库连接静态方法
*
* @return 数据库连接
*/
public static Connection getConnection() {
// 声明数据库连接
Connection conn = null;
try {
// 安装数据库驱动程序
Class.forName(DRIVER);
// 获取数据库连接
conn = DriverManager.getConnection(URL, USER, PASSWORD);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
// 返回数据库连接
return conn;
}
/**
* 关闭数据库连接静态方法
*
* @param conn 数据库连接
*/
public static void closeConn(Connection conn) {
if (conn != null) {
try {
if (!conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
login.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
用户登录
用户登录
<%
String errMsg = (String) session.getAttribute("errMsg");
if (errMsg != null) {
out.println("");
//out.println("" + new String(errMsg.getBytes("ISO-8859-1"), "utf-8") + "
");
}
%>
do_login.jsp页面
<%@ page import="net.xsp.dao.UserDao" %>
<%@ page import="net.xsp.dao.impl.UserDaoImpl" %>
<%@ page import="net.xsp.bean.User" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
// 设置请求对象字符编码
request.setCharacterEncoding("utf-8");
// 获取登录表单提交的数据
String username = request.getParameter("username");
String password = request.getParameter("password");
// 创建用户数据访问对象
UserDao userDao = new UserDaoImpl();
// 判断用户是否登录成功
if (userDao.login(username, password)) {
// 创建登录用户对象
User loginedUser = new User();
// 设置用户对象属性
loginedUser.setUsername(username);
loginedUser.setPassword(password);
// 创建登录用户列表对象
List loginedUsers = new ArrayList<>();
// 判断application里是否有登录用户列表属性
if (application.getAttribute("LOGINED_USERS") == null) {
// 在application里添加登录用户列表属性
application.setAttribute("LOGINED_USERS", loginedUsers);
} else {
// 从application里获取登录用户列表
loginedUsers = (List) application.getAttribute("LOGINED_USERS");
}
// 将当前登录成功的用户添加到登录用户列表里
loginedUsers.add(loginedUser);
// 更新application里登录用户列表属性值
application.setAttribute("LOGINED_USERS", loginedUsers);
// 清除session里errMsg属性
if (session.getAttribute("errMsg") != null) {
session.removeAttribute("errMsg");
}
// 采用重定向,跳转到登录成功页面
response.sendRedirect("success.jsp?username=" + URLEncoder.encode(username, "utf-8"));
} else {
// 创建session属性errMsg
session.setAttribute("errMsg", "用户名或密码错误,请重新登录!");
// 采用重定向,跳转到登录页面
response.sendRedirect("login.jsp");
}
%>
success.jsp页面
<%@ page import="net.xsp.bean.User" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
登录成功
<%= request.getParameter("username") %>,登录成功!
<%
// 从application里获取登录列表
List loginedUsers = (List) application.getAttribute("LOGINED_USERS");
%>
目前,已有<%= loginedUsers.size() %>人访问过本网站。
JNDI(Java Naming and Directory Interface),Java命名与目录接口,是一组在Java应用中访问命名和目录服务的API。命名服务将名称和对象联系起来,使得我们可以用名称访问对象。目录服务是一种命名服务,在这种服务里,对象不但有名称,还有属性。
JNDI可以把Java应用程序访问数据库管理和配置交给存放Java应用的服务器,比如tomcat服务器。在没有JNDI之前,JDBC连接数据库,Java应用程序与MySQL提供的驱动程序关联,映射一个Driver的Class对象(com.mysql.jdbc.Driver),然后用Java提供的DriverMannager管理类调用getConnection(“jdbc:mysql://localhost:8080/数据库名字”, “用户名”, “密码”)方法获得一个Connection连接对象,让Java与指定数据库建立连接。缺点很明显:当所有程序调试完成后,所有Java源文件形成Jar包,如果数据库类型或用户名改变,就必须改源代码。有JNDI之后,把变化的地方交给服务器来设置一个数据源,需要JDBC建立连接时引用,交给服务器管理配置,Java应用程序需要就到数据库连接池里去拿一个。
数据库连接池技术是一种提升应用程序性能的技术,核心作用是管理是连接到数据库的多个连接的打开和释放,即形成连接池管理。应用程序需要连接时使用它,使用完毕后又将其放回连接池中。当应用程序需要连接时,就绪连接一直保持可用状态。池管管理数据库连接的生命周期,这样开发人员实际上不需要等待连接建立,或者手动关闭连接。连接池机制节省昂贵的操作及资源消耗,方便了应用程序运行时建立网络连接,并最终在后端初始化数据库会话。
创建Web项目DataSourceDemo
栏目实体类Topic
package net.xsp.bean;
/**
* 功能:栏目实体类
* 作者:
* 日期:2019年11月7日
*/
public class Topic {
private int tid;
private String tname;
public int getTid() {
return tid;
}
public void setTid(int tid) {
this.tid = tid;
}
public String getTname() {
return tname;
}
public void setTname(String tname) {
this.tname = tname;
}
@Override
public String toString() {
return "Topic{" +
"tid=" + tid +
", tname='" + tname + '\'' +
'}';
}
}
栏目数据访问类TopicDao
package net.xsp.dao;
import net.xsp.bean.Topic;
import net.xsp.dbutil.ConnectionManager;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
/**
* 功能:栏目数据访问类
* 作者:
* 日期:2019年11月7日
*/
public class TopicDao {
/**
* 查询全部栏目
*
* @return 全部栏目构成的列表
*/
public List findAllTopics() {
// 定义栏目列表
List topics = new ArrayList<>();
try {
// 获取数据库连接
Connection conn = ConnectionManager.getConnection();
// 定义SQL字符串
String strSQL = "select * from topic";
// 创建语句对象
Statement stmt =conn.createStatement();
// 执行SQL查询,返回结果集
ResultSet rs = stmt.executeQuery(strSQL);
// 遍历结果集
while (rs.next()) {
// 创建栏目实体
Topic topic =new Topic();
// 利用当前记录字段值设置栏目属性值
topic.setTid(rs.getInt("tid"));
topic.setTname(rs.getString("tname"));
// 将栏目实体添加到栏目列表
topics.add(topic);
}
} catch (Exception e) {
e.printStackTrace();
}
// 返回栏目列表
return topics;
}
}
数据库连接管理类ConnectionManager
package net.xsp.dbutil;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
/**
* 功能:数据库连接管理器
* 作者:
* 日期:2019年11月7日
*/
public class ConnectionManager {
/**
* 私有化构造方法,拒接实例化
*/
private ConnectionManager() {
}
/**
* 获取数据库连接静态方法
*
* @return 数据库连接
*/
public static Connection getConnection() {
// 定义数据库连接
Connection conn = null;
try {
// 初始化上下文
Context ctx = new InitialContext();
// 在数据库连接池查询获取数据源
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/news");
// 通过数据源获取数据库连接
conn = ds.getConnection();
} catch (NamingException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
// 返回数据库连接
return conn;
}
public static void main(String[] args) {
Connection conn = getConnection();
if (conn != null) {
System.out.println("恭喜,数据库连接成功!");
} else {
System.out.println("遗憾,数据库连接失败!");
}
}
}
context.xml
topic_list.jsp页面
<%@ page import="java.sql.Connection" %>
<%@ page import="net.xsp.dbutil.ConnectionManager" %>
<%@ page import="java.sql.Statement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
新闻栏目列表
<%
// 获取数据库连接
Connection conn = ConnectionManager.getConnection();
// 定义SQL字符串
String strSQL = "select * from topic";
// 创建语句对象
Statement stmt = conn.createStatement();
// 执行SQL查询,返回结果集
ResultSet rs = stmt.executeQuery(strSQL);
out.println("" +
"编号 栏目 ");
// 遍历结果集,分行显示在页面
while (rs.next()) {
out.println("" + rs.getInt("tid") + " " + rs.getString("tname") + " ");
}
out.println("
");
%>
topic_list_new.jsp页面
<%@ page import="net.xsp.dao.TopicDao" %>
<%@ page import="java.util.List" %>
<%@ page import="net.xsp.bean.Topic" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
新闻栏目列表
<%
// 创建栏目数据访问对象
TopicDao topicDao = new TopicDao();
// 获取全部栏目列表
List topics = topicDao.findAllTopics();
out.println("" +
"编号 栏目 ");
// 遍历栏目列表,分行显示在页面
for (Topic topic: topics) {
out.println("" + topic.getTid()
+ " " + topic.getTname() + " ");
}
out.println("
");
%>
1、组件化思想
组件化思想其实就是分而治之(最重要的架构思想),页面逻辑过于复杂,便将页面分为很多个业务组件模块分而治之,这样维护人员每次只需要改动对应的模块即可,以达到最大程度地降低开发难度与维护成本的效果,所以现在比较好的框架都会对组件化作一定程度的实现。
2、JavaBean的概念
JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性。众所周知,属性名称符合这种模式,其他Java 类可以通过自身机制发现和操作这些JavaBean 属性。 换句话说,JavaBean就是一个Java的类,只不过这个类你要按上面提到的一些规则来写,比如方法必须是公共的,无参构造等等,按这些规则写了之后,这个JavaBean可以在程序里被方便地重用,使开发效率提高。
3、采用JavaBean的优势
解决代码重复编写,减少代码冗余
功能区分明确,避免业务逻辑处理与页面显示处理集中在一起造成混乱
提高了代码的维护性
通过代码实现分页,将全部表记录以实体方式存放到ArrayList或Vector对象里,从ArrayList或Vector对象里去获取当前页要显示的实体集,此方法效率很低。
通过数据库实现分页。不同数据库分页方式不同。
package net.xsp.news.bean;
import java.sql.Timestamp;
/**
* 功能:新闻实体类
* 作者:
* 日期:2019年11月14日
*/
public class News {
private int nid;
private int ntid;
private String ntname;
private String ntitle;
private String nauthor;
private Timestamp ncreatedate;
private String npicpath;
private String ncontent;
private Timestamp nmodifydate;
private String nsummary;
public int getNid() {
return nid;
}
public void setNid(int nid) {
this.nid = nid;
}
public int getNtid() {
return ntid;
}
public void setNtid(int ntid) {
this.ntid = ntid;
}
public String getNtname() {
return ntname;
}
public void setNtname(String ntname) {
this.ntname = ntname;
}
public String getNtitle() {
return ntitle;
}
public void setNtitle(String ntitle) {
this.ntitle = ntitle;
}
public String getNauthor() {
return nauthor;
}
public void setNauthor(String nauthor) {
this.nauthor = nauthor;
}
public Timestamp getNcreatedate() {
return ncreatedate;
}
public void setNcreatedate(Timestamp ncreatedate) {
this.ncreatedate = ncreatedate;
}
public String getNpicpath() {
return npicpath;
}
public void setNpicpath(String npicpath) {
this.npicpath = npicpath;
}
public String getNcontent() {
return ncontent;
}
public void setNcontent(String ncontent) {
this.ncontent = ncontent;
}
public Timestamp getNmodifydate() {
return nmodifydate;
}
public void setNmodifydate(Timestamp nmodifydate) {
this.nmodifydate = nmodifydate;
}
public String getNsummary() {
return nsummary;
}
public void setNsummary(String nsummary) {
this.nsummary = nsummary;
}
@Override
public String toString() {
return "News{" +
"nid=" + nid +
", ntid=" + ntid +
", ntname='" + ntname + '\'' +
", ntitle='" + ntitle + '\'' +
", nauthor='" + nauthor + '\'' +
", ncreatedate=" + ncreatedate +
", npicpath='" + npicpath + '\'' +
", ncontent='" + ncontent + '\'' +
", nmodifydate=" + nmodifydate +
", nsummary='" + nsummary + '\'' +
'}';
}
}
NewsDao
package net.xsp.news.dao;
import net.xsp.news.bean.News;
import net.xsp.news.dbutil.ConnectionManager;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
/**
* 功能:新闻数据访问类
* 作者:
* 日期:2019年11月14日
*/
public class NewsDao {
/**
* 获取全部新闻列表
*
* @return 全部新闻列表
*/
public List findAllNews() {
// 定义新闻列表
List newsList = new ArrayList<>();
// 获取数据库连接
Connection conn = ConnectionManager.getConnection();
// 定义SQL字符串
String strSQL = "select * from news";
try {
// 创建语句对象
Statement stmt = conn.createStatement();
// 执行SQL查询,返回结果集
ResultSet rs = stmt.executeQuery(strSQL);
// 遍历结果集
while (rs.next()) {
// 创建新闻实体对象
News news = new News();
// 将当前记录字段值去设置新闻实体属性
news.setNid(rs.getInt("nid"));
news.setNtid(rs.getInt("ntid"));
news.setNtitle(rs.getString("ntitle"));
news.setNauthor(rs.getString("nauthor"));
news.setNcreatedate(rs.getTimestamp("ncreatedate"));
news.setNpicpath(rs.getString("npicpath"));
news.setNcontent(rs.getString("ncontent"));
news.setNmodifydate(rs.getTimestamp("nmodifydate"));
news.setNsummary(rs.getString("nsummary"));
// 将当前新闻实体添加到新闻列表
newsList.add(news);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭数据库连接
ConnectionManager.closeConn(conn);
}
// 返回新闻列表
return newsList;
}
/**
* 获取总记录数
*
* @return 总记录数
*/
public int getCount() {
// 返回总记录数
return findAllNews().size();
}
/**
* 获取总页数
*
* @param count 总记录数
* @param pageSize 每页记录数
* @return 总页数
*/
public int getTotalPages(int count, int pageSize) {
// 返回总页数
return count % pageSize == 0 ? count / pageSize : count /pageSize + 1;
}
/**
* 按页获取新闻列表
*
* @param pageIndex 当前页码
* @param pageSize 每页记录数
* @return 当前页新闻列表
*/
public List findNewsByPage(int pageIndex, int pageSize) {
// 定义新闻列表
List newsList = new ArrayList<>();
// 获取数据库连接
Connection conn = ConnectionManager.getConnection();
// 定义SQL字符串
String strSQL = "select * from news limit ?, ?";
try {
// 创建预备语句对象
PreparedStatement pstmt = conn.prepareStatement(strSQL);
// 设置占位符的值
pstmt.setInt(1, pageSize * (pageIndex - 1));
pstmt.setInt(2, pageSize);
// 执行SQL查询,返回结果集
ResultSet rs = pstmt.executeQuery();
// 遍历结果集
while (rs.next()) {
// 创建新闻实体对象
News news = new News();
// 将当前记录字段值去设置新闻实体属性
news.setNid(rs.getInt("nid"));
news.setNtid(rs.getInt("ntid"));
news.setNtitle(rs.getString("ntitle"));
news.setNauthor(rs.getString("nauthor"));
news.setNcreatedate(rs.getTimestamp("ncreatedate"));
news.setNpicpath(rs.getString("npicpath"));
news.setNcontent(rs.getString("ncontent"));
news.setNmodifydate(rs.getTimestamp("nmodifydate"));
news.setNsummary(rs.getString("nsummary"));
// 将当前新闻实体添加到新闻列表
newsList.add(news);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
ConnectionManager.closeConn(conn);
}
// 返回新闻列表
return newsList;
}
}
ConnectionManager
package net.xsp.news.dbutil;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
/**
* 功能:数据库连接管理类
* 作者:
* 日期:2019年11月14日
*/
public class ConnectionManager {
/**
* 私有化构造方法,拒绝实例化
*/
private ConnectionManager() {
}
/**
* 获取数据库连接静态方法
*
* @return 数据库连接
*/
public static Connection getConnection() {
Connection conn = null;
try {
// 创建初始化上下文
Context ctx = new InitialContext();
// 通过数据库连接池查询获取数据源
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/news");
// 通过数据源获取数据库连接
conn = ds.getConnection();
} catch (NamingException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
/**
* 关闭数据库连接静态方法
*
* @param conn 数据库连接
*/
public static void closeConn(Connection conn) {
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
context.xml
allnews.jsp
<%@ page import="net.xsp.news.dao.NewsDao" %>
<%@ page import="java.util.List" %>
<%@ page import="net.xsp.news.bean.News" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
不分页显示全部新闻列表
<%
// 创建新闻数据访问对象
NewsDao newsDao = new NewsDao();
// 获取全部新闻列表
List newsList = newsDao.findAllNews();
// 在页面上显示数据
out.print("");
out.print("编号 标题 创建时间 ");
// 遍历新闻列表
for (News news: newsList) {
out.print("" + news.getNid() + " ");
out.print("" + news.getNtitle() + " ");
out.print("" + news.getNcreatedate() + " ");
}
out.print("
");
%>
pagingnews.jsp
<%@ page import="net.xsp.news.dao.NewsDao" %>
<%@ page import="java.util.List" %>
<%@ page import="net.xsp.news.bean.News" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
分页显示全部新闻列表
<%
// 创建新闻数据访问对象
NewsDao newsDao = new NewsDao();
// 获取总记录数
int count = newsDao.getCount();
// 定义每页最大记录数
int pageSize = 5;
// 获取总页数
int totalPages = newsDao.getTotalPages(count, pageSize);
// 获取当前页码
String currentPage = request.getParameter("pageIndex");
// 首次进去页面,应该显示第一页内容
if (currentPage == null) {
currentPage = "1";
}
// 获取页索引
int pageIndex = Integer.parseInt(currentPage);
// 对首页与末页的页索引进行控制
if (pageIndex < 1) {
pageIndex = 1;
} else if (pageIndex > totalPages) {
pageIndex = totalPages;
}
// 获取当前页新闻列表
List newsList = newsDao.findNewsByPage(pageIndex, pageSize);
// 在页面上显示数据
out.print("");
out.print("编号 标题 创建时间 ");
// 遍历新闻列表
for (News news: newsList) {
out.print("" + news.getNid() + " ");
out.print("" + news.getNtitle() + " ");
out.print("" + news.getNcreatedate() + " ");
}
out.print("
");
%>
<%-- 实现分页操作【首页、上一页、下一页、末页】 --%>
softpagingnews.jsp
<%@ page import="net.xsp.news.dao.NewsDao" %>
<%@ page import="net.xsp.news.bean.News" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
软分页显示新闻列表
<%
// 获取总页数
NewsDao newsDao = new NewsDao();
int count = newsDao.getCount();
int pageSize = 5;
int totalPages = newsDao.getTotalPages(count, pageSize);
List allnews = newsDao.findAllNews();
// 获取当前页码
String currentPage = request.getParameter("pageIndex");
if (currentPage == null) {
currentPage = "1";
}
int pageIndex = Integer.parseInt(currentPage);
// 对首页与末页进行控制
if (pageIndex < 1) {
pageIndex = 1;
} else if (pageIndex > totalPages) {
pageIndex = totalPages;
}
// 生成当前页的新闻列表
List newsList = new ArrayList<>();
for (int i = (pageIndex - 1) * pageSize; i ");
out.print("编号 标题 创建时间 ");
for (News news : newsList) {
out.print("" + news.getNid() + " ");
out.print("" + news.getNtitle() + " ");
out.print("" + news.getNcreatedate() + " ");
}
out.print("");
%>
SmartUpload是专门用于实现文件上传及下载的免费组件。
使用简单,编写少量代码,完成上传下载功能
能够控制上传内容
能够控制上传文件的大小、类型
SmartUpload目前已停止更新服务。
创建Web项目SmartUploadDemo
upload.html
利用SmartUpload组件上传文件
do_upload.jsp
<%@ page import="com.jspsmart.upload.SmartUpload" %>
<%@ page import="com.jspsmart.upload.File" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
显示上传数据
<%!
// 声明文件名及扩展名 全局声明
String filename, ext;
%>
<%
// 实例化上传组件
SmartUpload su = new SmartUpload();
// 初始化上传,绑定页面
su.initialize(pageContext);
// 判断文件类型是否符合要求
try {
// 设置上传文件允许类型
su.setAllowedFilesList("jpg, gif, png, bmp");
// 上传文件
su.upload();
} catch (Exception e) {
// 弹出消息框告知用户,并且跳转到上传页面
out.print("");
}
// 获取第一个上传文件
File file = su.getFiles().getFile(0);
// 判断文件上传是否发生丢失现象
if (file.isMissing()) {
// 弹出消息框告知用户,并且跳转到上传页面
out.print("");
} else {
// 定义上传文件的最大尺寸(单位:字节)
long FILE_MAX_SIZE = 400000;
// 判断上传文件大小是否符合要求
if (file.getSize() <= FILE_MAX_SIZE) {
// 获取上传文件名(包含扩展名)
filename = file.getFileName();
// 获取上传文件的扩展名
ext = file.getFileExt();
// 去掉扩展名
filename = filename.substring(0, filename.lastIndexOf("."));
// 对文件名进行utf-8转码
filename = new String(filename.getBytes(), "utf-8");
// 利用时间戳与随机整数修改文件名
filename = filename + String.valueOf(System.currentTimeMillis()) +
String.valueOf((int) (Math.random() * 900) + 100);
// 获取应用程序的真实路径(物理路径)
String realPath = application.getRealPath("/");
// 创建上传文件的url
String url = realPath + "upload\\" + filename + "." + ext;
// 将上传文件保存到服务器指定位置
file.saveAs(url, SmartUpload.SAVE_PHYSICAL);
// 提示用户上传成功
out.print("文件上传成功!
");
out.print("保存位置:" + url + "
");
} else {
// 弹出消息框告知用户,并且跳转到上传页面
out.print("");
}
}
// 获取表单提交的姓名数据
String name = su.getRequest().getParameter("name");
// 对姓名数据进行utf-8转码
name = new String(name.getBytes(), "utf-8");
%>
姓名:<%= name %>
照片:
download.html
下载文件
单击下载文件:scenery.jpg
do_download.jsp
<%@ page import="com.jspsmart.upload.SmartUpload" %>
<%
// 获取下载文件名
String filename = request.getParameter("filename");
// 创建SmartUpload实例
SmartUpload su = new SmartUpload();
// 让SmartUpload实例初始化
su.initialize(pageContext);
// 禁止浏览器自动打开文件
su.setContentDisposition(null);
// 利用SmartUpload组件下载文件
su.downloadFile("/upload/" + filename);
%>
上传的文件要求包括一个根据RFC 1867(在HTML中基于表单的文件)编码的选项列表清单。组件FileUpload可以解析这个请求,并给你的应用程序提供一份独立上传的项目清单。无论每个项目背后如何执行都实现了FileItem接口。
这里将描述组件FileUpload库的普通API,这些API比较简单。不过,对于最终的实现,你可以参考最新的API流。
每一个文件项目都有一些属性,这些可能在你的应用程序中应用到。比如:每一个项目有一个名称name和内容类型content type,并提供了一个 InputStream访问其数据。另一方面,你处理项目的方法可能有所不同,这个依赖于是否这个项目是一个规则的表单域,即这个数据是来自普通的表单文本,还是普通的HTML域或是一个上传文件。在FileItem接口中提供了处理这些问题的方法,可以更加方便的去访问这些数据。
组件FileUpload使用FileItemFactory工厂创建新的文件项目。这个给了组件FileUpload很大的灵活性。这个工厂拥有怎样创建项目的最终控制权。工厂执行过程中上传项目文件的临时数据可以存储在内存中或硬盘上。这个依赖于上传项目的大小(即:数据的字节)。不过这种行为可以在你的应用程序中适当的自定制。
读取客户端(浏览器)发送的显式的数据。这包括网页上的 HTML 表单,或者也可以是来自 applet 或自定义的 HTTP 客户端程序的表单。
读取客户端(浏览器)发送的隐式的 HTTP 请求数据。这包括 cookies、媒体类型和浏览器能理解的压缩格式等等。
处理数据并生成结果。这个过程可能需要访问数据库,执行 RMI 或 CORBA 调用,调用 Web 服务,或者直接计算得出对应的响应。
发送显式的数据(即文档)到客户端(浏览器)。该文档的格式可以是多种多样的,包括文本文件(HTML 或 XML)、二进制文件(GIF 图像)、Excel 等。
发送隐式的 HTTP 响应到客户端(浏览器)。这包括告诉浏览器或其他客户端被返回的文档类型(例如 HTML),设置 cookies 和缓存参数,以及其他类似的任务。
ServeltConfig接口:在Servlet初始化过程中获取配置信息,一个Servlet只有一个ServletConfig对象
ServeltContext接口:获取Servlet上下文
GenericServlet抽象类:提供了Servlet与ServletConfig接口的默认实现方法
HttpServlet继承于GenericServlet
处理HTTP协议的请求和响应,使用doXxx()接收用户请求
doGet():用户使用get方式提交请求时调用
doPost():用户使用post方式提交请求时调用
从Servlet3.0开始,配置Servlet支持注解方式,但还是保留了配置web.xml方式。
web.xml文件中配置
HelloServletWorld
net.xsp.servlet.HelloServletWorld
username
xsping
1
HelloServletWorld
/hello
基于Servlet模板创建HelloServletWorld类
package net.xsp.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
@WebServlet(name = "HelloServletWorld",
value = "/hello",
initParams = {
@WebInitParam(name = "username", value = "xsping")
},
loadOnStartup = 1)
public class HelloServletWorld extends HttpServlet {
@Override
public void init() throws ServletException {
super.init();
System.out.println("初始化Servlet。。。");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 设置响应对象字符编码格式
response.setCharacterEncoding("utf-8");
// 获取初始化参数值
String username = getInitParameter("username");
// 获取打印输入流
PrintWriter out = response.getWriter();
// 创建简单日期格式对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
out.print("" +
"" +
"" +
"亲切的问候 " +
"" +
"" +
"亲爱的" + username + ", 欢迎访问Servlet世界~
" +
"当前时间:" + sdf.format(new Date()) + "
" +
"" +
"/html>"
);
}
@Override
public void destroy() {
super.destroy();
System.out.println("销毁Servlet。。。");
}
}
上述注解符@WebServlet的配置,相当于在web.xml里做了如下配置:
启动服务器,访问http://localhost:8080/HelloServletWorld/hello
在src里创建包net.hw.servlet,在里面创建登录处理程序LoginServlet
package net.xsp.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
@WebServlet(name = "LoginServlet", value = "/login")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 设置请求对象字符编码格斯
request.setCharacterEncoding("utf-8");
// 获取登录表单数据
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println(username);
// 判断登录是否成功
if (username.equals("张三丰") && password.equals("12345")) {
// 采用从定向,跳转到登录成功页面
response.sendRedirect("success.jsp?username=" + URLEncoder.encode(username, "utf-8"));
} else {
// 采用从定向,跳转到登录失败页面
response.sendRedirect("success.jsp?username=" + URLEncoder.encode(username, "utf-8"));
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
}
拷贝其他项目的登录、登陆成功、登录失败页面
启动服务器,查看运行效果
${ EL exprission }
${ bean.name } 或 b e a n [ ′ n a m e ′ ] , { bean['name'] }, bean[′name′],{bean.name}实质是调用bean的getName()方法
[ ]或 . 运算符获取对象属性、获取对象集合中的数据
例如,在Session中保存了一个(list)集合users,${sessionScope.user[1]}
自动转换类型
EL得到某个数据时可以自动转换类型
对于类型的限制更加宽松
使用简单
相比较在JSP中嵌入Java代码,EL应用更简单
<%--
Created by IntelliJ IDEA.
User: Stranger
Date: 2019/12/30
Time: 19:32
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
EL演示01
<%
String username = "李元霸";
pageContext.setAttribute("username", "张三丰");
request.setAttribute("username", "李世民");
session.setAttribute("username", "郑晓雯");
application.setAttribute("username", "唐雨涵");
%>
利用JSP表达式输出变量值:
姓名:<%= username %>
姓名:<%= pageContext.getAttribute("username")%>
姓名:<%= request.getAttribute("username")%>
姓名:<%= session.getAttribute("username")%>
姓名:<%= application.getAttribute("username")%>
利用EL表达式输出变量值:
姓名:${username}
姓名:${pageScope.username}
姓名:${requestScope.username}
姓名:${sessionScope.username}
姓名:${applicationScope['username']}
启动服务器,访问http://localhost:8080/JSTLELDemo/demo01.jsp:
${username} 不能访问在JSP脚本里定义的变量username,而是与${pageScope.username}一样的作用,访问pageContext里的属性值。
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %><%--
Created by IntelliJ IDEA.
User: Stranger
Date: 2019/12/30
Time: 19:46
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
EL演示02
<%
Map names = new HashMap<>();
names.put("one", "李玉文");
names.put("two", "钟发奎");
names.put("three", "周晓雯");
session.setAttribute("names", names);
%>
第一个学生:<%= names.get("one") %> : ${sessionScope.names.one} : ${names['one']}
第二个学生:<%= names.get("two") %> : ${sessionScope.names.two} : ${names['two']}
第三个学生:<%= names.get("three") %> : ${sessionScope.names.three} : ${names['three']}
启动服务器,访问http://localhost:8080/JSTLELDemo/demo02.jsp:
在WEB-INF目录里创建lib子目录,添加标准标签库jar包
在web目录里创建演示页面demo03.jsp
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Random" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
EL演示03
<%
String y = String.valueOf(1 + 2 + 3);
session.setAttribute("y", y);
%>
x:
y:
y: ${sessionScope.y}
if标签用法示例(单分支结构)
x的结果是6。
条件判断的结果为:${result}
choose、when、otherwise标签用法示例(多分支结构)
<%
Random rnd = new Random();
Integer luck = new Integer(rnd.nextInt(10));
request.setAttribute("luck", luck);
%>
恭喜你中了一等奖!
恭喜你中了二等奖!
恭喜你中了三等奖!
谢谢参与,欢迎再来!
forEach标签用法示例(循环结构)
<%
List users = new ArrayList();
users.add("admin");
users.add("howard");
users.add("smith");
users.add("green");
request.setAttribute("users", users);
%>
启动服务器,访问http://localhost:8080/JSTLELDemo/demo03.jsp:
在web目录里创建演示页面demo04.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
formateDate标签应用示例
formateDate标签应用示例
序号
样式
日期
时间
1
default
${date}
${time}
2
short
${date}
${time}
3
medium
${date}
${time}
4
long
${date}
${time}
5
full
${date}
${time}
自定义显示当前时间:${result}
启动服务器,访问http://localhost:8080/JSTLELDemo/demo04.jsp:
1、在页面头部引入ckeditor核心文件ckeditor.js
2、在使用编辑器的地方插入文本区控件
注意在控件中加上 class=“ckeditor” 。
3、将相应的控件替换成编辑器代码
4、配置ckeditor编辑器
ckeditor的配置都集中在 ckeditor/config.js 文件中,下面是一些常用的配置参数:
CKEDITOR.editorConfig = function( config )
{
config.language = 'zh-cn'; // 配置语言
config.uiColor = '#FFF'; // 背景颜色
config.width = 'auto'; // 宽度
config.height = '300px'; // 高度
config.skin = 'office2003'; // 界面v2,kama,office2003
config.toolbar = 'Full'; // 工具栏风格Full,Basic
config.font_names='宋体/宋体;黑体/黑体;仿宋/仿宋_GB2312;楷体/楷体_GB2312;隶书/隶书;幼圆/幼圆;'+ config.font_names; // 将中文字体加入到字体列表
};
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
在创建一个XMLHttpRequest的对象之前,必须首先确定用户当前使用的浏览器类型,之后根据浏览器类型创建合适的XMLHttpRequest对象,如果为普通的FireFox,则直接使用new XMLHttpRequest()的方式创建;而如果IE浏览器,则通过new ActiveXObject()的方式进行创建。
XMLHttpRequest对象的属性
readyState一共有5种取值:
0:请求没有发出(在调用open()函数之前)
1:请求已经建立但还没有发出(在调用send()函数之前)
2:请求已经发出正在处理之中(这里通常可以从响应得到内容头部)
3:请求已经处理,正在接收服务器的信息,响应中通常有部分数据可用,但是服务器还没有完成响应。
4:响应已完成,可以访问服务器响应并使用它。
XMLHttpRequest对象的方法
XMLHttpRequest对象的open()和send()方法在回调函数中出现较多,一般都会用open()方法设置一个提交的路径,并通过地址重写的方式设置一些请求的参数,而真正的发出请求操作可以通过send()方法完成。异步验证时要执行用JavaScript操作。在XMLHttpRequest对象中可以使用responseXML()方法接收一组返回的XML数据,这些返回的XML数据可以动态生成(利用JDOM工具将数据库中的数据变为XML文件),也可以直接读取一个XML文件,当客户端接收读取的XML文件之后,可以通过DOM解析的方式对数据进行操作。
修改Web项目首页文件index.jsp
在web目录创建子目录data,在里面创建userlist.txt文件
在web目录创建getUserList.html页面
获取用户列表
用户列表
启动服务器,查看运行效果
在web目录里创建login.html页面
用户登录
用户登录
用户名
密 码
启动服务器,查看运行效果:
在src里创建net.hw.servlet包,在里面创建LoginServlet
package net.xsp.servlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* 功能:登录处理程度
* 作者:向仕平
* 日期:2019年11月19日
*/
@WebServlet(name = "LoginServlet", value = "/login")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 设置请求对象字符编码
request.setCharacterEncoding("utf-8");
// 获取登录表单提交的数据
String username = request.getParameter("username");
String password = request.getParameter("password");
// 判断是否登录成功,返回不同的数据
PrintWriter out = response.getWriter();
if (username.equals("root") && password.equals("123456")) {
out.print("success");
} else {
out.print("failure");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
}
创建登录成功页面success.html
创建登录失败页面failure.html
启动服务器,查看运行效果
在web目录里创建getJSONData.html页面
从后台获取JSON数据
从后台获取JSON数据
在net.hw.servlet包里创建GetJsonServlet类
package net.xsp.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* 功能:获取JSON数据控制程序
* 作者:向仕平
* 日期:2019年11月28日
*/
@WebServlet(name = "GetJsonServlet", value = "/getJson")
public class GetJsonServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 定义打印输出流对象
PrintWriter out = response.getWriter();
// 定义JSON字符串
String strJson = "{\"username\": \"howard\", \"password\": \"903213\"}";
// 向客户端返回JSON字符串
out.write(strJson);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
}
在web目录创建js子目录,添加jQuery脚本库文件
在web目录创建获取json数据页面getJsonData02.html
获取JSON数据
从后台获取JSON数据
启动服务器,查看运行效果
在web目录里创建登录页面login02.html
用户登录
用户登录
用户名
密 码
Jsp和Servlet的本质是一样的。Jsp页面由两部分组成:
静态部分:标准的HTMl标签,静态的页面内容,与HTML页面相同
动态部分:受Java代码控制的内容,这些内容由java脚本动态生成
Jsp注释:
<%-- 注释内容 --%>
HTML注释:
Jsp声明:
<%! 声明部分 %>
Jsp输出表达式:
<%= 表达式 %>
page:该指令是针对当前页面的指令
include:用于指定包含另一个页面
taglib:用于定义和访问自定义标签
语法:<%@ 编译指令名 属性名=“属性值” %>
page指令:
language:声明脚本语言类型,一般是java,只能是java
extends:指定jsp页面编译之后所产生的java类所继承的父类或者接口
import:用来导入包
session:jsp页面是否需要HttpSession
buffer:指定jsp页面的缓冲区的大小,默认值为8kb
autoFlush:缓冲区溢出时,是否强制输出缓冲区的内容
info:设置该jsp程序的信息
errorPage:指定错误处理界面
isErrorPage:设置本jsp程序是否为错误处理程序
pageEncoding:设置生成网页的字符集编码
include指令:
把一个外部文件嵌入当前的jsp页面中,同时解析这个页面的Jsp语句,这是静态include语句,他会把目标页面的其他编译指令也包含进来如果两个页面的编译指令冲突,页面就会出错,但是动态的include则不会。
语法<%@ include file=“文件路径/文件名”%>
编译指令是通知Servlet引擎处理消息
动作指令知识运行时的动作
jsp:forward:执行页面转向,将请求的处理转发到下一个页面
jsp:param:传递参数,必须和其他支持参数的标签一起使用
jsp:include:动态的引入一个jsp页面
jsp:plugin:下载javaBean和Applet到客户端执行
jsp:useBean:创建一个useBean的实例
jsp:setProperty:设置javaBean实例的属性值
jsp:getProperty:输出javaBean实例的属性值
forward指令:
将页面的请求转发到一个新的页面,可以是静态的HTML页面,也可以是动态的jsp页面,或者转发到容器中的Servlet
语法:
对于jsp1.0:
对于jsp1.1:(用于转发时增加额外的请求参数)
include指令:
他是一种动态的include指令,用于包含某个页面,他不会导入被include页面的编译指令,只导入页面的body内容插入本页面。
语法:
其中flush属性:指定输出缓存是否转移到被导入的文件中,如果为true,则包含在被导入的文件中,如果为false,则包含在原文件中。
静态导入和动态导入的三个区别:
1、静态导入是将被导入页面的代码完全融合,两个页面融合成一个整体的Servlet;动态导入则在Servlet中使用include方法来引入被导入的页面的容。
2、静态导入时,被导入的页面的编译指令会产生作用;动态导入时被导入的编译指令则会失去作用,只是插入被导入页面的body内容
3、动态导入还可以增加额外的参数
forward动作指令和include动作指令的区别:
执行forward时,被forward的页面将完全代替原有页面,执行include时,被include的页面知识插入原有的页面。
forward拿目标页面代替原有页面,include则拿目标页面插入原有的页面。
useBean指令:
id属性就是Javabean的实例名,class属性确定了JavaBean的实现类
scope属性指定javaBean市里的作用范围:
page:该javaBean实例只在该页面有效
request:在本次请求内有效
session:在本次session内有效
application:在本应用内一直有效
setProperty指令:
name属性确定了javaBean的实例名;property属性确定需要设置的属性名;value属性则确定需要设置的属性值
getPeoperty指令:
name属性确定了需要输出的javaBean的实例名;property属性确定需要输出的属性名。
param指令:
用于设置参数值,本身不能单独使用,没有什么意义, 一般都结合下面的三个指令使用:
1、jsp:include
param指令把参数传入被导入的页面
2、jsp:forward
param指令把参数传向被转入的页面
3、jsp:plugin
param指令把参数传入页面中的javabean或者Applet
转眼间一学期就快过去了,在学校的这几个月来,关于JavaWeb的学习过程中,自己从中得到的收获依旧是巨大的,加之最后的西蒙购物网项目开发,使得自己在这方面进一步提高。综合一学期的学习我给自己打分90分。