数据库设计
create table tbl_login (
log_id number primary key,
log_name varchar2(20) ,
log_pwd varchar2(30),
log_state number default 1
);
create sequence seq_log ;
insert into tbl_login values(seq_log.nextval,'admin','admin',1);
select * from tbl_login;
login实体类
package com.zt.entity;
import java.io.Serializable;
public class Login implements Serializable {
private static final long serialVersionUID = 1L;
private Integer logId;
private String logName;
private String logPwd;
private Integer logState;
public Login(Integer logId, String logName, String logPwd, Integer logState) {
super();
this.logId = logId;
this.logName = logName;
this.logPwd = logPwd;
this.logState = logState;
}
public Login() {
super();
}
public Integer getLogId() {
return logId;
}
public void setLogId(Integer logId) {
this.logId = logId;
}
public String getLogName() {
return logName;
}
public void setLogName(String logName) {
this.logName = logName;
}
public String getLogPwd() {
return logPwd;
}
public void setLogPwd(String logPwd) {
this.logPwd = logPwd;
}
public Integer getLogState() {
return logState;
}
public void setLogState(Integer logState) {
this.logState = logState;
}
@Override
public String toString() {
return "Login [logId=" + logId + ", logName=" + logName + ", logPwd="
+ logPwd + ", logState=" + logState + "]";
}
}
在实体类实现序列化接口的作用是序列化的作用
对象实例除了存在于内存,二级缓存还会将对象写进硬盘在需要的时候再读取出来使用,此时就必须提到一个概念:序列化。
程序在运行时实例化出对象,这些对象存在于内存中,随着程序运行停止而消失,但如果我们想把某些对象(一般都是各不相同的属性)保存下来或者传输给其他进程,在程序终止运行后这些对象仍然存在,可以在程序再次运行时读取这些对象的信息,或者在其他程序中利用这些保存下来的对象信息恢复成实例对象。这种情况下就要用到对象的序列化和反序列化。
序列化就是对实例对象的状态(State 对象属性而不包括对象方法)进行通用编码(如格式化的字节码)并保存,以保证对象的完整性和可传递性。
简而言之:序列化,就是为了在不同时间或不同平台的JVM之间共享实例对象
LoginDAO
package com.zt.dao;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import com.zt.entity.Login;
import com.zt.handler.LoginObjectHandler;
import com.zt.util.JDBCUtil;
public class LoginDAO {
QueryRunner qr = new QueryRunner();
//登陆
public Login userLogin(Login user) throws SQLException{
String sql = "select log_id,log_name,log_pwd,log_state from tbl_login where log_name =? and log_pwd=? and log_state=1 ";
return qr.query(JDBCUtil.getConnection(), sql, new LoginObjectHandler(),user.getLogName(),user.getLogPwd());
}
}
QueryRunner qr = new QueryRunner();实例化queryrunner,进行查询
String sql = "select log_id,log_name,log_pwd,log_state from tbl_login where log_name =? and log_pwd=? and log_state=1 ";
调用queryrunner可以直接准备SQL语句
要注意这里创建了一个用户状态的字段,所以SQL语句还得加上这个字段,保证登陆的用户是合法用户
return qr.query(JDBCUtil.getConnection(), sql, new LoginObjectHandler(),user.getLogName(),user.getLogPwd());
这里的结果集用handler类来实现遍历,相当于另外写一个类来实现结果集resultset的遍历,
这里的参数直接写在后面就行了,这里query的方法是动态参数,无论什么类型,多少个参数可以直接写在后面就行了,所以这就是利用queryrunner执行查询的优点
由于dao里面传入的参数是一个login对象,所以这里直接通过对象拿到名字和密码
处理结果集的LoginObjectHandler
package com.zt.handler;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.commons.dbutils.ResultSetHandler;
import com.zt.entity.Login;
public class LoginObjectHandler implements ResultSetHandler<Login>{
@Override
public Login handle(ResultSet rs) throws SQLException {
//只负责处理结果集
Login user = null;
while(rs.next()){
user =new Login(rs.getInt("log_id"), rs.getString("log_name"), rs.getString("log_pwd"), rs.getInt("log_state"));
}
return user;
}
}
public class LoginObjectHandler implements ResultSetHandler<Login>{
这里的类需要实现resultsethandler<T>的接口
才能处理结果集
将鼠标移到这里LoginObjectHandler自动重写handle(ResultSet rs)方法,遍历结果集的方法和之前的一摸一样
login.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>My JSP 'login.jsp' starting page</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">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<form action="loginServlet.do" method="post">
用户名:<input type="text" name="name"/></br></br>
密 码:<input type="password" name="pwd"/></br></br>
<input type="submit" value="提交"/>
<input type="reset" value="重置"/>
</form>
</body>
</html>
loginservlet.java
package com.zt.servlet;
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.zt.dao.LoginDAO;
import com.zt.entity.Login;
import com.zt.util.SystemUtil;
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
//重写dopost方法
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//设置编码
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//获取参数
String name = req.getParameter("name");
String pwd = req.getParameter("pwd");
//调用DAO方法
LoginDAO ld = new LoginDAO();
Login login = new Login();
login.setLogName(name);
login.setLogPwd(pwd);
try {
Login user = ld.userLogin(login);
//登陆成功重定向到index.jsp,否则到login.jsp
//对查询的结果进行判断
HttpSession session = req.getSession();
if(user==null){
//<%=request.getContextPath()%>
//是为了解决相对路径的问题,可返回站点的根路径。
session.setAttribute("msg", "您的输入有误!!!");
resp.sendRedirect(req.getContextPath()+"/login.jsp");
}else{
session.setAttribute("user", user);
resp.sendRedirect(req.getContextPath()+"/page/index.jsp");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//重写dopost方法
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
因为表单form里面是post请求,所以这里重写dopost方法处理页面的请求
user = ld.userLogin(login);由于logindao里面需要传递 的参数是一个login对象
所以这里需要对页面传递进来的参数进行一个封装,封装成为一个login对象
这里可以通过login.set方法进行每一个属性的value值的设定
Login login = new Login();
login.setLogName(name);
login.setLogPwd(pwd);
先new一个对象,然后需要哪些值就设置进去这是一个很好的方法
req.getContextPath()通过request是为了解决相对路径的问题,可返回站点的根路径。
/login.jsp是相对路径,/表示相对项目
/page/index.jsp也是相对路径
HttpSession session = req.getSession();
如果想要再servlet里面将参数或者结果传递到其他的页面,就需要靠session来进行传递,所以需要先拿到请求的session,然后在session里面进行相应参数的名字和值的设定
名字可以自己随便设定,
if(user==null){
//<%=request.getContextPath()%>
//是为了解决相对路径的问题,可返回站点的根路径。
session.setAttribute("msg", "您的输入有误!!!");
resp.sendRedirect(req.getContextPath()+"/login.jsp");
}else{
session.setAttribute("user", user);
//这里将查出的结果通过session继续传递到index.jsp页面
resp.sendRedirect(req.getContextPath()+"/page/index.jsp");
}
<c:remove>
标签有如下属性:
属性 描述 是否必要 默认值
var 要移除的变量名称 是 无
scope 变量所属的作用域 否 所有作用域
session.setAttribute("msg", "您的输入有误!!!");对于servlet里面的变量通过session传到前端jsp页面
前端页面直接通过${msg}来获取到对应的变量的值
然后刷新就会失效,然后就移除
所以这里采用jsp里面的c标签<c:/>来进行移除
包括变量名var 以及作用范围scope这里的msg的作用范围是session,一旦页面刷新,就会失效,
<font color="red">${msg }</font>
<c:remove var="msg" scope="session"/>
再使用jsp里面的session时需要引入c标签的头文件
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core""%>