Expression Language: 表达式语言, jsp2.0之后内置在jsp里面
目的:为了使JSP写起来更加简单, 取值(取的域对象里面存的值)更加简单。(代替脚本 <% %>)
${el表达式}
1.获取数据. 获取的是域(request,session,ServletContext)对象中存储的数据
2.EL执行运算
语法:${requestScope|sessionScope|applicationScope.属性名};
快捷写法:${属性名}, 属性名就是存在域对象里面的key
<%--
Created by IntelliJ IDEA.
User: Fanyi Xiao
Date: 2020/7/15
Time: 8:52
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
使用EL表达式获取域对象中的简单类型的数据
<%
//往域对象存值
application.setAttribute("msg","applicationValue");
//session.setAttribute("msg","sessionValue");
//request.setAttribute("msg","requestValue");
//在我们开发过程中,是否会往多个域对象中存放同一个key??? 这是不会的
//所以我们用el表达式获取域对象里面的数据,还可以简化成${key} 获取范围最小的域对象中的这个key对应的值
%>
获取的application域对象中的msg=${applicationScope.msg}
获取session域对象中的msg=${sessionScope.msg}
获取request域对象中的msg=${requestScope.msg}
获取存放在域对象中的msg=${msg}
语法: ${key[下标]} key就是域对象里面存的key
语法:${list属性名[index]}或者${list属性名.get(index)};list属性名就是存入域对象里面的key
语法:${map属性名.键}或者${map属性名.get("键")},map属性名就是存入域对象里面的key
语法:${key.javabean属性}
依赖getxxx()方法; eg: getPassword()—去掉get–>Password()----首字母小写—>password
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.Map" %>
<%@ page import="com.itheima.pojo.User" %><%--
Created by IntelliJ IDEA.
User: Fanyi Xiao
Date: 2020/7/15
Time: 9:05
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
使用EL表达式获取存储在域对象中的复杂类型的数据
<%
//往域对象中存放数组类型的数据
String[] arr = {"张三","李四","王五","赵六","田七","狗娃"};
request.setAttribute("arr", arr);
//往域对象中存放一个集合
List list = new ArrayList();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("赵六");
list.add("田七");
request.setAttribute("list", list);
//往域对象中存放一个map
Map map = new HashMap();
map.put("name", "张三");
map.put("password", "123456");
map.put("nickname", "张三丰");
request.setAttribute("map", map);
//往域对象中存放一个pojo对象
User user = new User(1, "jay", "台湾省");
request.setAttribute("user",user);
%>
获取存放在request域对象中的数组中的第三个元素:${arr[2]}
<%--
在el表达式中,只要是根据下标获取元素,都可以写[index]
--%>
获取存放在request域对象中的集合中的第四个元素:${list[3]}
<%--
在el表达式中,只要是根据对应的属性的get方法去获取数据,都可以写成".属性名" 或者 ["属性名"]
--%>
获取存储在request域对象中的map中的nickname:${map.nickname}
获取存放在request域对象中的user的address属性的值:${user.address}
${key}
${key[下标]}
${key.get(index)} 或者${key[index]}
${key.get(键)} 或者${key.键} key是存到域对象里面的key
${key.javaBean属性}
+,-,*,/
< >= <= != ==
&& || !
empty,1. 判断一个对象是否为null, 2. 判断集合长度是否为0, 3. 判断一个字符串是否为空字符串
not empty
语法: ${empyt 属性名};属性名 就是域对象里面的key值
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page import="com.itheima.pojo.User" %><%--
Created by IntelliJ IDEA.
User: Fanyi Xiao
Date: 2020/7/15
Time: 9:35
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
empty 运算符的介绍
<%
//el表达式中的empty可以判断一个字符串是否为空字符串,一个对象是否为null,一个集合的长度是否为0
List list = new ArrayList();
list.add("张三丰");
request.setAttribute("list", list);
request.setAttribute("msg","requestValue");
User user = new User();
request.setAttribute("u",user);
%>
判断域对象中的list集合的长度是否为0: ${empty list}
判断域对象中的msg字符串是否为空字符串: ${empty msg}
判断域对象中的user是否为null : ${empty u}
注意的地方: +只能做加法运算,不能拼接字符串
empty【重点】
语法:${cookie.cookie的name.value}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
使用el表达式获取存储在cookie中的数据
<%--
jsp里面是内置session对象,有了session对象,那么浏览器就会携带一个名为"JSESSIONID"的cookie
我们的目标就是获取"JSESSIONID"的值
--%>
<%
Cookie[] cookies = request.getCookies();
String cookieValue = null;
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("JSESSIONID")) {
cookieValue = cookie.getValue();
}
}
}
%>
使用原始方式获取的JSESSIONID的值为: <%=cookieValue%>
<%--
${cookie}表示获取这次请求中的所有cookie对象
${cookie.JSESSIONID}表示获取名为"JSESSIONID"的cookie对象
${cookie.JSESSIONID.value}表示获取名为"JSESSIONID"的cookie对象的value
--%>
使用EL表达式获取JSESSIONID的值为: ${cookie.JSESSIONID.value}
JSTL(JSP Standard Tag Library,JSP标准标签库)是一个不断完善的开放源代码的JSP标签库,是由apache的jakarta小组来维护的。这个JSTL标签库没有集成到JSP的, 要使用的话, 需要导jar包.
为了简化在jsp页面上操作数据; eg: 遍历数据 判断数据等
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: Fanyi Xiao
Date: 2020/8/27
Time: 10:10
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
使用jstl中的if标签进行判断
<%
//往域对象中存储一个age
request.setAttribute("age",17);
//目标:判断age的值,如果大于等于18,则在浏览器页面上输出"已成年",否则输出"未成年"
//jstl的使用步骤:1. 导入jar包 2. 在jsp页面通过taglib指令引入核心标签库 3. 使用标签
%>
<%--
if标签有一个属性叫做test,它表示判断表达式,需要结合el一起使用
如果要表示相反的判断,则再添加一个if标签,然后写相反的条件就行
if标签还有一个属性叫做var,表示将判断结果存储进域对象时候的key(了解)
if标签的第三个属性叫做scope,表示将判断结果存储进哪个域对象(了解)
--%>
已成年
未成年
${flag}
小结
<%--
Created by IntelliJ IDEA.
User: Fanyi Xiao
Date: 2020/7/15
Time: 9:59
To change this template use File | Settings | File Templates.
--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
jstl中的choose标签的使用介绍
<%
request.setAttribute("course","PHP");
%>
<%--
一个when标签表示一个条件
--%>
学习Java
学习Android
学习C++
学习,学个屁!!!
<%--
jstl中的forEach标签是用来代替for循环语句
目标1: 在浏览器上显示0-9的数字
begin属性: 从哪个下标开始遍历, 如果不写默认是从0开始
end属性: 到哪个下标结束遍历,如果不写默认是遍历到集合/数组的最后一个元素
step属性: 表示遍历时候的步长,默认步长是1
var属性: 表示将遍历的结果存放进域对象时候的key
--%>
${i}
复杂的使用遍历集合:
<%
//往域对象存储一个集合
List list = new ArrayList();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("赵六");
list.add("田七");
request.setAttribute("list", list);
%>
${i}
<%--
通过items属性指定遍历域对象里面的list
通过var属性指定遍历出来的每个数据存储到域对象时候的key
--%>
${username}
c:forEach中的varStatus属性。
指向一个字符串,该字符串引用一个对象。 map.put("vs",一个对象);
这个对象记录着当前遍历的元素的一些信息:
index:返回索引。从0开始
count:返回计数。从1开始
last:是否是最后一个元素
first:是否是第一个元素
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %><%--
Created by IntelliJ IDEA.
User: Fanyi Xiao
Date: 2020/7/15
Time: 10:15
To change this template use File | Settings | File Templates.
--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
forEach 标签的varStatus属性的介绍
<%
//往域对象存储一个集合
List list = new ArrayList();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("赵六");
list.add("田七");
request.setAttribute("list", list);
%>
<%--
forEach标签的varStatus属性:指定将遍历出来的每一个元素的状态存储进域对象时候的key
遍历出来的每一个元素都有一些状态(属性),比如:
下标 index:
计数 count:
当前元素的值 current:
是否是第一个元素:
是否是最后一个元素
--%>
下标
计数
姓名
是否是第一个元素
是否是最后一个元素
${vst.index}
${vst.count}
${vst.current}
${vst.first}
${vst.last}
//每遍历一次 foreach里面就执行一次
//每遍历一次 foreach里面就执行一次
数据库的准备
create database day29;
use day29;
create table account(
id int primary key auto_increment,
name varchar(20),
money double
);
insert into account values (null,'jay',1000);
insert into account values (null,'aobama',1000);
insert into account values (null,'ww',1000);
页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Insert title here
jar包
工具类
配置文件
package com.itheima.web.servlet;
import com.itheima.utils.DruidUtil;
import org.apache.commons.dbutils.QueryRunner;
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;
/**
* 包名:${PACKAGE_NAME}
*
* @author Leevi
* 日期2020-07-15 10:55
*/
@WebServlet("/account")
public class AccountServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//1. 获取请求参数
String fromName = request.getParameter("from");
String toName = request.getParameter("to");
Double money = Double.valueOf(request.getParameter("money"));
//2. 执行转账的SQL语句
//2.1 转出账户扣款
QueryRunner queryRunner = new QueryRunner(DruidUtil.getDataSource());
String sql1 = "update account set money=money-? where name=?";
try {
queryRunner.update(sql1,money,fromName);
//2.2 转入账户收款
String sql2 = "update account set money=money+? where name=?";
queryRunner.update(sql2,money,toName);
//3. 转账成功
response.getWriter().write("转账成功!!!");
} catch (Exception e) {
e.printStackTrace();
//转账失败
response.getWriter().write("转账失败!!!");
}
}
}
javaBean:实体类。特点:私有化的属性、公共的getter setter方法、无参的构造。
JSP + Servlet + JavaBean 称为MVC的开发模式.
MVC:开发模式
M:model 模型 (javaBean:封装数据)
V:View 视图 (JSP:展示数据)
C:controller 控制器 (Servlet:处理逻辑代码,做为控制器)
分层 | 包名(公司域名倒写) |
---|---|
表现层(web层) | com.itheima.web |
业务层(service层) | com.itheima.service |
持久层(数据库访问层) | com.itheima.dao |
JavaBean | com.itheima.bean |
工具类 | com.itheima.utils |
模式一: JSP+JavaBean【了解】
模式二: MVC
三层架构
package com.itheima.web.servlet;
import com.itheima.service.AccountService;
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;
/**
* 包名:${PACKAGE_NAME}
*
* @author Leevi
* 日期2020-07-15 10:55
*/
@WebServlet("/account")
public class AccountServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//1. 获取请求参数
String fromName = request.getParameter("from");
String toName = request.getParameter("to");
Double money = Double.valueOf(request.getParameter("money"));
try {
//2. 调用业务层的AccountService的方法处理请求执行转账
AccountService accountService = new AccountService();
accountService.transfer(fromName,toName,money);
//3. 转账成功
response.getWriter().write("转账成功!!!");
} catch (Exception e) {
e.printStackTrace();
//转账失败
response.getWriter().write("转账失败!!!");
}
}
}
package com.itheima.service;
import com.itheima.dao.AccountDao;
import java.sql.SQLException;
/**
* 包名:com.itheima.service
*
* @author Leevi
* 日期2020-07-15 11:19
*/
public class AccountService {
private AccountDao accountDao = new AccountDao();
public void transfer(String fromName,String toName,Double money) throws SQLException {
//2.1 调用AccountDao的方法进行转出账户扣款
accountDao.updateAccount(fromName,-money);
//2.2 调用AccountDao的方法进行转入账户收款
accountDao.updateAccount(toName,money);
}
}
package com.itheima.dao;
import com.itheima.utils.DruidUtil;
import org.apache.commons.dbutils.QueryRunner;
import java.sql.SQLException;
/**
* 包名:com.itheima.dao
*
* @author Leevi
* 日期2020-07-15 11:19
*/
public class AccountDao {
private QueryRunner queryRunner = new QueryRunner(DruidUtil.getDataSource());
/**
* 修改账户信息
*/
public void updateAccount(String name,Double money) throws SQLException {
String sql = "update account set money=money+? where name=?";
queryRunner.update(sql,money,name);
}
}
API | 说明 |
---|---|
QueryRunner() | 创建QueryRunner对象. 手动提交事务时使用 |
query(connection,String sql, Object[] params, ResultSetHandler rsh) | 查询(需要传入Connection) |
update(connection,String sql, Object… params) | 更新 |
package com.itheima.service;
import com.itheima.dao.AccountDao;
import com.itheima.utils.DruidUtil;
import java.sql.Connection;
import java.sql.SQLException;
/**
* 包名:com.itheima.service
*
* @author Leevi
* 日期2020-07-15 11:19
*/
public class AccountService {
private AccountDao accountDao = new AccountDao();
public void transfer(String fromName,String toName,Double money) {
Connection conn = null;
try {
//逻辑操作开始之前开启事务: connection.setAutoCommit(false)
conn = DruidUtil.getDataSource().getConnection();
conn.setAutoCommit(false);
//2.1 调用AccountDao的方法进行转出账户扣款
accountDao.updateAccount(conn,fromName, -money);
//模拟转账过程中出现异常
int num = 10 / 0;
//2.2 调用AccountDao的方法进行转入账户收款
accountDao.updateAccount(conn,toName, money);
//逻辑操作执行完毕没有异常,提交事务: connection.commit()
conn.commit();
} catch (Exception e) {
e.printStackTrace();
//逻辑操作执行过程中遇到异常,则在catch里面回滚事务: connection.rollback()
try {
conn.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
throw new RuntimeException("转账失败");
}
}
}
package com.itheima.dao;
import com.itheima.utils.DruidUtil;
import org.apache.commons.dbutils.QueryRunner;
import java.sql.Connection;
import java.sql.SQLException;
/**
* 包名:com.itheima.dao
*
* @author Leevi
* 日期2020-07-15 11:19
*/
public class AccountDao {
private QueryRunner queryRunner = new QueryRunner(DruidUtil.getDataSource());
/**
* 修改账户信息
* 指定使用某个连接Connection执行SQL语句
*/
public void updateAccount(Connection connection,String name, Double money) throws SQLException {
String sql = "update account set money=money+? where name=?";
queryRunner.update(connection,sql,money,name);
}
}
在catch里面抛运行时异常
思想2: 如果在service和dao共享一个Connection对象
通过调用方法的时候将connection作为参数传递给Dao
技术点1 : 怎么开启、提交、回滚事务
connection.setAutoCommit(false)开启事务
connection.commit()提交事务
connection.rollback()回滚事务
注意: 开启事务的连接和执行SQL语句的连接要是同一个
技术点2 : 在使用DBUtils执行SQL语句的时候,怎么才能指定使用哪个连接呢?
调用queryRunner对象的update或者query方法的时候,可以传入connection
在“事务传递参数版”中,我们必须修改方法的参数个数,传递链接,才可以完成整个事务操作。如果不传递参数,是否可以完成?在JDK中给我们提供了一个工具类:ThreadLocal,此类可以在一个线程中共享数据。
java.lang.ThreadLocal,该类提供了线程局部 (thread-local) 变量,用于在当前线程中共享数据。ThreadLocal工具类底层就是一个Map,key存放的当前线程,value存放需要共享的数据
package com.itheima;
/**
* 包名:com.itheima
*
* @author Leevi
* 日期2020-07-15 14:58
* ThreadLocal是线程本地变量,它的作用是用于在保证同一个线程中的对象使用的是同一份数据
*/
public class TestMain {
public static void main(String[] args) {
//ThreadLocal的使用
ThreadLocal<String> threadLocal = new ThreadLocal<>();
//在主线程中往ThreadLocal对象中存储一个字符串"jay"
threadLocal.set("jay");
//在主线称重往ThreadLocal中存入一个字符串"aobama"
threadLocal.set("aobama");
//新线程
new Thread(new Runnable() {
@Override
public void run() {
//在新线程中,往ThreadLocal中存入"jay"
threadLocal.set("jay");
//在新线程中获取ThreadLocal中的值
String s = threadLocal.get();
System.out.println("在新线程中获取ThreadLocal中的值为:" + s);
}
}).start();
//在主线程中取出ThreadLocal中的值
String str = threadLocal.get();
System.out.println("在主线程中获取ThreadLocal对象中的值:" + str);
}
}
package com.itheima.utils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/**
* 包名:com.itheima.utils
*
* @author Leevi
* 日期2020-07-06 11:45
*/
public class DruidUtil {
private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
private static DataSource dataSource;
static {
try {
//1. 创建Properties对象
Properties properties = new Properties();
//2. 将配置文件转换成字节输入流
InputStream is = DruidUtil.class.getClassLoader().getResourceAsStream("druid.properties");
//3. 使用properties对象加载is
properties.load(is);
//druid底层是使用的工厂设计模式,去加载配置文件,创建DruidDataSource对象
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static DataSource getDataSource(){
return dataSource;
}
/**
* 让该方法获取的连接对象是同一个对象
* @return
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
Connection connection = threadLocal.get();
if (connection == null) {
//说明threadLocal中还没有存储连接
connection = dataSource.getConnection();
//将连接存储到threadLocal中
threadLocal.set(connection);
}
return connection;
}
public static void clear() throws SQLException {
//先将conn的autoCommit属性设置回true
threadLocal.get().setAutoCommit(true);
threadLocal.get().close();
//将conn从ThreadLocal中移除
threadLocal.remove();
}
}
package com.itheima.service;
import com.itheima.dao.AccountDao;
import com.itheima.utils.DruidUtil;
import java.sql.Connection;
import java.sql.SQLException;
/**
* 包名:com.itheima.service
* @author Leevi
* 日期2020-08-27 11:50
* 业务层的类:处理请求(执行具体的业务逻辑)
* 如果在处理请求的过程中,需要执行SQL语句,则调用dao层的方法执行SQL语句
*
* service层为什么要try异常: 为了在catch里面进行回滚操作
* service层又要把异常抛给servlet
*
* 怎么添加事务:
* 1. 开启事务: 业务逻辑开始之前,connection.setAutoCommit(false);
* 2. 提交事务: 业务逻辑执行完毕,没有出现异常,connection.commit()
* 3. 回滚事务: 业务逻辑执行过程中出现异常,connection.rollback()
*
* 注意点: 执行事务的connection对象和执行SQL语句的connection对象必须是同一个connection
*
* 进一步优化
* 1.使用ThreadLocal存储连接,实现业务层和持久层使用的是相同连接对象
* 2.
*/
public class AccountService {
private AccountDao accountDao = new AccountDao();
public void transfer(String fromName,String toName, Double money){
Connection conn = null;
try {
//开启事务
conn = DruidUtil.getConnection();
conn.setAutoCommit(false);
//1. 调用dao层的方法,执行付款方扣款
accountDao.updateAccount(fromName, -money);
//出现异常
int num = 10 / 0;
//2. 调用dao层的方法,执行收款方收款
accountDao.updateAccount(toName, money);
//提交事务
conn.commit();
} catch (Exception e) {
e.printStackTrace();
try {
//回滚事务
conn.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
throw new RuntimeException(e.getMessage());
}finally {
try {
//1. 设置连接的autoCommit为true 2. 将连接对象归还到连接池 3. 清除ThreadLocal中的连接对象
DruidUtil.clear();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
package com.itheima.dao;
import com.itheima.utils.DruidUtil;
import org.apache.commons.dbutils.QueryRunner;
import java.sql.SQLException;
/**
* 包名:com.itheima.dao
* @author Leevi
* 日期2020-08-27 11:51
* 数据访问层的类:执行数据库的增删改查的SQL语句
*/
public class AccountDao {
private QueryRunner queryRunner = new QueryRunner(DruidUtil.getDataSource());
/**
* 根据账户的name,更新账户的money
* @param name
* @param money
* @throws SQLException
*/
public void updateAccount(String name, Double money) throws SQLException {
String sql = "update account set money=money+? where name=?";
queryRunner.update(DruidUtil.getConnection(),sql,money,name);
}
}
在list.jsp页面中显示user表中的所有用户的信息
index.jsp代码
<%--
Created by IntelliJ IDEA.
User: Fanyi Xiao
Date: 2020/7/15
Time: 12:08
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
首页
查看所有用户信息
ShowAllServlet代码
package com.itheima.web.servlet;
import com.itheima.pojo.User;
import com.itheima.service.UserService;
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.util.List;
/**
* 包名:${PACKAGE_NAME}
*
* @author Leevi
* 日期2020-07-15 12:08
*/
@WebServlet("/showAll")
public class ShowAllServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//1. 调用业务层的方法,处理查询所有用户的请求
UserService userService = new UserService();
List<User> userList = userService.findAll();
//2. 将user的集合存储到request域对象中
request.setAttribute("list",userList);
//3. 跳转到list.jsp页面
request.getRequestDispatcher("/list.jsp").forward(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
UserService代码
package com.itheima.service;
import com.itheima.dao.UserDao;
import com.itheima.pojo.User;
import java.sql.SQLException;
import java.util.List;
/**
* 包名:com.itheima.service
*
* @author Leevi
* 日期2020-07-15 12:09
*/
public class UserService {
private UserDao userDao = new UserDao();
public List<User> findAll() throws SQLException {
//调用dao对象的findAll()方法查询所有用户信息
List<User> userList = userDao.findAll();
return userList;
}
}
UserDao代码
package com.itheima.dao;
import com.itheima.pojo.User;
import com.itheima.utils.DruidUtil;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import java.sql.SQLException;
import java.util.List;
/**
* 包名:com.itheima.dao
*
* @author Leevi
* 日期2020-07-15 12:09
*/
public class UserDao {
private QueryRunner queryRunner = new QueryRunner(DruidUtil.getDataSource());
public List<User> findAll() throws SQLException {
String sql = "select * from user";
List<User> userList = queryRunner.query(sql, new BeanListHandler<>(User.class));
return userList;
}
}
list.jsp代码
<%--
Created by IntelliJ IDEA.
User: Fanyi Xiao
Date: 2020/7/15
Time: 12:08
To change this template use File | Settings | File Templates.
--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
展示页面
序号
用户名
密码
地址
昵称
性别
邮箱
<%--
遍历出域对象里面的list中的每一个user
--%>
${vst.count}
${user.username}
${user.password}
${user.address}
${user.nickname}
${user.gender}
${user.email}
RegisterServlet代码
package com.itheima.web.servlet;
import com.itheima.bean.User;
import com.itheima.service.UserService;
import org.apache.commons.beanutils.BeanUtils;
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.util.Map;
/**
* @author Leevi
* 日期2020-08-24 16:13
* 处理注册的Servlet
*/
@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
private UserService userService = new UserService();
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//0. 解决请求参数的中文乱码问题
request.setCharacterEncoding("UTF-8");
//0. 解决响应的中文乱码问题
response.setContentType("text/html;charset=utf-8");
//1. 获取所有请求参数
Map<String, String[]> map = request.getParameterMap();
//2. 将所有请求参数封装到user对象中
User user = new User();
try {
BeanUtils.populate(user,map);
//设置激活状态为0
user.setStatus("0");
//3. 调用业务层的方法,处理注册请求
userService.register(user);
//如果在这个过程中没有出现异常,则注册成功
//跳转到登录页面---->重定向跳转
response.sendRedirect("login.html");
} catch (Exception e) {
e.printStackTrace();
//如果在这个过程中出现了异常,则注册失败
response.getWriter().write("注册失败");
}
}
}
LoginServlet代码
package com.itheima.web.servlet;
import com.itheima.bean.User;
import com.itheima.service.UserService;
import com.itheima.utils.CookieUtil;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
/**
* @author Leevi
* 日期2020-08-24 16:24
*/
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
private UserService userService = new UserService();
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//0. 解决乱码
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//1. 获取客户端提交的用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
// 获取客户端输入的验证码
String checkCode = request.getParameter("checkCode");
// 获取服务器生成的验证码
//从session中获取服务器端生成的验证码
HttpSession session = request.getSession();
String code = (String) session.getAttribute("code");
//获取是否记住用户名
String remember = request.getParameter("remember");
//校验验证码
if (code.equalsIgnoreCase(checkCode)) {
//验证码正确,当验证码正确了,才进行用户名和密码的校验
try {
//调用业务层的方法,校验登录(校验用户名和密码)
User user = userService.login(username, password);
if (user != null) {
//登录成功
//判断是否需要记住用户名
if (remember != null) {
//需要记住用户名: 将用户名存储到cookie中,并且传到浏览器保存
Cookie cookie = CookieUtil.createAndSetCookie("username", username, 7 * 24 * 60 * 60, request.getContextPath());
response.addCookie(cookie);
}else {
//说明不需要记住用户: 需要将之前保存在cookie中的用户名删除
//往浏览器存储一个同名、同路径但是maxAge为0 的cookie
Cookie cookie = CookieUtil.createAndSetCookie("username", username, 0, request.getContextPath());
response.addCookie(cookie);
}
//保存登录状态: 目的是在这次会话中访问任何页面都是已登录状态
//其实就是保存当前登录的user,保存在session域对象中
session.setAttribute("user",user);
//跳转到success.jsp页面: 重定向
response.sendRedirect("success.jsp");
}else {
//登录失败:用户名或密码错误
String errorMsg = "用户名或密码错误";
//将errorMsg字符串存储到哪个域对象??? request
request.setAttribute("errorMsg",errorMsg);
//优化登录:跳转回到登录页面,并且进行错误信息的提示
//跳转方式有两种:1. 重定向 2. 请求转发
request.getRequestDispatcher("login.jsp").forward(request, response);
}
} catch (Exception e) {
e.printStackTrace();
//登录失败: 登录失败
//登录失败:验证码错误
String errorMsg = "登录失败";
//将errorMsg存储到request域对象
request.setAttribute("errorMsg",errorMsg);
//跳转到login.jsp
request.getRequestDispatcher("login.jsp").forward(request, response);
}
}else {
//登录失败:验证码错误
String errorMsg = "验证码错误";
//将errorMsg存储到request域对象
request.setAttribute("errorMsg",errorMsg);
//跳转到login.jsp
request.getRequestDispatcher("login.jsp").forward(request, response);
}
}
}
UserService代码
package com.itheima.service;
import com.itheima.bean.User;
import com.itheima.dao.UserDao;
/**
* 包名:com.itheima.service
* @author Leevi
* 日期2020-08-27 12:09
*/
public class UserService {
private UserDao userDao = new UserDao();
public void register(User user) throws Exception {
//调用dao层的方法,将用户信息存储到数据库
userDao.saveUser(user);
}
public User login(String username,String password) throws Exception {
//调用dao层的方法校验用户名和密码
return userDao.findUser(username,password);
}
}
UserDao代码
package com.itheima.dao;
import com.itheima.bean.User;
import com.itheima.utils.DruidUtil;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import java.sql.SQLException;
/**
* 包名:com.itheima.dao
* @author Leevi
* 日期2020-08-27 12:09
*/
public class UserDao {
/**
* 执行添加用户的SQL语句的方法
* @param user
* @throws SQLException
*/
public void saveUser(User user) throws Exception {
QueryRunner queryRunner = new QueryRunner(DruidUtil.getDataSource());
String sql = "insert into user values (null,?,?,?,?,?,?,?)";
queryRunner.update(sql,user.getUsername(),user.getPassword(),user.getAddress(),user.getNickname(),user.getGender(),user.getEmail(),user.getStatus());
}
/**
* 根据username和password执行查询用户信息
* @param username
* @param password
* @return
* @throws SQLException
*/
public User findUser(String username,String password) throws Exception {
QueryRunner queryRunner = new QueryRunner(DruidUtil.getDataSource());
String sql = "select * from user where username=? and password=?";
User user = queryRunner.query(sql, new BeanHandler<>(User.class), username, password);
return user;
}
}