这几天学了一些java基础以及H5代码,写了一个简单的登陆注册功能,当然还附加了记住密码以及自动登录.下面是我数据库版本为Mysql8.0:
:
首先创建entity层,为实体类封装:
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@Data //包含 setter getter equals hashcode toString
public class User {
private Integer id;
private String username;
private String password;
private Date birthday;
private String sex;
private String address;
//除id的构造方法
public User(String username, String password, Date birthday, String sex, String address) {
super();
this.username = username;
this.password = password;
this.birthday = birthday;
this.sex = sex;
this.address = address;
}
}
然后写需要创建dao层,service层 entity层以及servlet层.分别用来对数据库操作,写业务,封装实体类.以及与前端交互.先上Dao层的接口代码:
import com.gem.entity.User;
public interface UserDao {
//登陆的方法
User selectByUsernameAndPassword(String username,String password);
//根据用户名查询用户
User selectByUsername(String username);
//添加用户
boolean insertUser(User user);
}
其次创建一个DaoImpl层,用来写与数据库交互的具体方法:
import java.util.List;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import com.gem.dao.UserDao;
import com.gem.entity.User;
import com.gem.util.JDBCUtil;
public class UserDaoImpl implements UserDao{
private JdbcTemplate jdbcTemplate=new JdbcTemplate(JDBCUtil.getDataSource());
@Override
public User selectByUsernameAndPassword(String username, String password) {
String sql="select * from user where username=? and password=?";
List<User> users=jdbcTemplate.query(sql,new BeanPropertyRowMapper<User>(User.class),username,password);
if(users!=null && users.size()!=0) {
return users.get(0);
}
return null;
}
@Override
public User selectByUsername(String username) {
String sql = "select * from user where username=?";
List<User> userList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<User>(User.class), username);
if (userList == null || userList.size() == 0) {
return null;//没有查到
}
return userList.get(0);
}
@Override
public boolean insertUser(User user) {
String sql = "insert into user values(null,?,?,now(),?,?) ";
//添加,删除,插入 update
int count = jdbcTemplate.update(sql, user.getUsername(), user.getPassword(),user.getSex(),user.getAddress());
return count > 0 ? true : false;
}
}
接下来要在service层写业务接口以及在serviceImpl层写业务实现的方法:
import com.gem.entity.User;
public interface UserService {
//登陆
User login(String username,String password);
//注册
boolean register(User user);
}
下面是serviceImpl层代码:
import com.gem.dao.UserDao;
import com.gem.dao.impl.UserDaoImpl;
import com.gem.entity.User;
import com.gem.service.UserService;
public class UserServiceImpl implements UserService {
private UserDao userDao=new UserDaoImpl();
@Override
public User login(String username, String password) {
return userDao.selectByUsernameAndPassword(username, password);
}
@Override
public boolean register(User user) {
if(userDao.selectByUsername(user.getUsername())!=null) {
System.out.println("用户名已存在");
return false;//用户名已存在
}
return userDao.insertUser(user);
}
}
以上便是登陆注册后端主要功能
因为为了安全,将jsp文件放在WEB-INF下面.而不是直接放在Content下
所以要写service层进行调用,下面是几个servlet层的代码其中包括了记住密码和登陆的功能.借助cookie来实现:
1.
import java.io.IOException;
import java.net.URLDecoder;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 跳转到登录页面
*/
@WebServlet("/ToLoginServlet")
public class ToLoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ToLoginServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//访问cookie,看是否存在用户名和密码
//Cookie 在浏览器中,所以request获得
Cookie[] cookies = request.getCookies();
// 有没有cookies user 用户名;密码
boolean flage = true;//默认cookie不存在,也就是不自动登录也不记住密码
if (cookies != null) {
//获得用户名和密码的cookie
for (Cookie cookie : cookies) {
if (cookie.getName().equals("auto")) {//自动登录
String user = URLDecoder.decode(cookie.getValue(), "utf-8");
String[] users = user.split(";");
//登录判断 ,用户名和密码还是要校验的
request.setAttribute("ausername", users[0]);
request.setAttribute("apassword", users[1]);
//跳转到首页 (jsp/servlet) 跳到servlet,查询数据库,渲染首页
request.getRequestDispatcher("/LoginServlet").forward(request, response);
flage = false;
} else if (cookie.getName().equals("user")) {//记住密码
//获得cookie值的时候需要解码 为了防止中文乱码 用户名;密码
String user = URLDecoder.decode(cookie.getValue(), "utf-8");
String[] users = user.split(";");
//存在,记住用户名和密码 ,将用户名和密码推送给jsp
request.setAttribute("username", users[0]);
request.setAttribute("password", users[1]);
// 跳转到登录页面
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
flage = false;
}
}
}
if (flage) {//既不自动登录也不记住密码,跳转到登录
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
}
}
//转发
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
2.
import java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.gem.entity.User;
import com.gem.service.UserService;
import com.gem.service.impl.UserServiceImpl;
/**
* 点击登录按钮,跳转到该页面,判断用户名和密码
*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public LoginServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//获取请求的参数,表单提交的参数 (form提交有请求参数)
String username = request.getParameter("username");
String password = request.getParameter("password");
//自动登录的时候,请求参数为空,request 中拿
if (username == null) { //域对象中存都是Object
//放置空指针
username = request.getAttribute("ausername") != null ? (String) request.getAttribute("ausername") : "";
}
if (password == null) {
password = request.getAttribute("apassword") != null ? (String) request.getAttribute("apassword") : "";
}
//自动登录getParameterValues checkbox 多选框,只是根据form来判断是否自动登录,以及记住了自动,没有form表单
String[] auto = request.getParameterValues("auto");
if (auto != null || request.getAttribute("ausername") != null) {//自动登录
String autoUser = URLEncoder.encode(username + ";" + password, "utf-8");
Cookie cookie = new Cookie("auto", autoUser);
cookie.setMaxAge(60 * 60 * 24); //存一天
//发送到浏览器,存在客户端
response.addCookie(cookie);
} else {
Cookie cookie = new Cookie("auto", "");
cookie.setMaxAge(0); //删除自动登录
//发送到浏览器,存在客户端
response.addCookie(cookie);
}
//是否记住密码
String[] remember = request.getParameterValues("remember");
if (remember != null) {
//勾选了记住记住密码,那么就将用户名和密码写到cookie中,保存1天
String unameAndPassword = URLEncoder.encode(username + ";" + password, "utf-8");
Cookie cookie = new Cookie("user", unameAndPassword);
cookie.setMaxAge(60 * 60 * 24);
//发送到浏览器,存在客户端
response.addCookie(cookie);
} else {
//不记住密码,只要key相同就能找到
Cookie cookie = new Cookie("user", "");
//清空cookie
cookie.setMaxAge(0);
//发送到浏览器,存在客户端
response.addCookie(cookie);
}
//Controllor 调用Model 业务层
UserService userService = new UserServiceImpl();
User user = userService.login(username, password);
if (user != null) {
//登录成功,跳转首页
} else {
//失败 request域中放个错误
request.setAttribute("error", "用户名或密码错误");
//重新跳转到登录页面
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
3.
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class ToRegisterServlet
*/
@WebServlet("/ToRegisterServlet")
public class ToRegisterServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ToRegisterServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/jsp/register.jsp").forward(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
4.
import java.io.IOException;
import java.util.Date;
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 com.gem.entity.User;
import com.gem.service.UserService;
import com.gem.service.impl.UserServiceImpl;
/**
* Servlet implementation class RegisterServlet
*/
@WebServlet("/RegisterServlet")
public class RegisterServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public RegisterServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//获取请求的参数,表单提交的参数
String username = request.getParameter("username");
String password = request.getParameter("password");
String sex=request.getParameter("sex");
String address=request.getParameter("address");
UserService userService=new UserServiceImpl();
Boolean flag=userService.register(new User(null,username,password,new Date(),sex,address));
if (flag) {
// response.getWriter().write("alert('注册成功')");
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
} else {
// response.getWriter().write("alert('注册失败')");
request.setAttribute("error", "用户名或密码错误");
request.getRequestDispatcher("/WEB-INF/jsp/register.jsp").forward(request, response);
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
接下来就是jsp代码,显示界面效果,(样式都是Bootstrap上面copy的):
1.login.jsp
<%@ page language="java" contentType="text/html; charset=utf8"
pageEncoding="utf8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>登录页面</title>
<!-- Bootstrap -->
<!-- 动态获得项目路径 http://localhost:8080/项目名/
application 最大的域 servletContext Servlet 在jsp中就是 application 项目上下文
获得项目访问的路径
-->
<link href="<%=application.getContextPath()%>/css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="<%=application.getContextPath()%>/js/bootstrap.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="<%=application.getContextPath()%>/js/JQuery3.5.1.js"></script>
<!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 -->
<!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 -->
<!--[if lt IE 9]>
<script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
<![endif]-->
<style type="text/css">
form{
border: 1px solid black;
margin-top: 100px;
padding-top: 40px;
padding-right: 100px;
border-radius: 5px;
}
</style>
</head>
<body>
<!-- 点击登录按钮,跳转的页面 servlet 判断用户名和密码是否正确-->
<form class="form-horizontal col-md-4 col-md-offset-4"
action="<%=application.getContextPath()%>/LoginServlet" method="post">
<div class="form-group">
<label for="username" class="col-sm-3 control-label">用户名:</label>
<div class="col-sm-9">
<!-- 从request中获取用户名 -->
<input type="text" class="form-control" id="username" value="${username}"
placeholder="请输入用户名" name="username" required="required">
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-3 control-label">密 码</label>
<div class="col-sm-9">
<!-- 不允许为空-->
<input type="password" class="form-control" id="password"
value="${password}" placeholder="请输入密码" name="password" required="required">
</div>
</div>
<div class="form-group">
<div class="col-md-offset-4 col-md-4">
<div class="checkbox">
<label>
<!-- 记住密码的勾选框 -->
<c:choose>
<c:when test="${not empty username}">
<input type="checkbox" name="remember" checked="checked">
</c:when>
<c:otherwise>
<input type="checkbox" name="remember">
</c:otherwise>
</c:choose>
记住密码
</label>
</div>
</div>
<div class=" col-md-4">
<div class="checkbox">
<label>
<input type="checkbox" name="auto"> 自动登录
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-6 col-sm-2">
<a href="ToRegisterServlet" class="btn btn-default">注册</a>
</div>
<div class="col-sm-offset-6 col-sm-2">
<button type="submit" class="btn btn-default">登录</button>
</div>
<div class=" col-sm-2">
<button type="reset" class="btn btn-default">重置</button>
</div>
</div>
</form>
<!-- 域对象获取错误 -->
<p style="color: red">${error}</p>
</body>
</html>
2.register.jsp
<%@ page language="java" contentType="text/html; charset=utf8"
pageEncoding="utf8"%>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>登录页面</title>
<!-- Bootstrap -->
<!-- 动态获得项目路径 http://localhost:8080/项目名/
application 最大的域 servletContext Servlet 在jsp中就是 application 项目上下文
获得项目访问的路径
-->
<link href="<%=application.getContextPath()%>/css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="<%=application.getContextPath()%>/js/bootstrap.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="<%=application.getContextPath()%>/js/JQuery3.5.1.js"></script>
<!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 -->
<!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 -->
<!--[if lt IE 9]>
<script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
<![endif]-->
<style type="text/css">
form{
border: 1px solid black;
margin-top: 100px;
padding-top: 40px;
padding-right: 100px;
border-radius: 5px;
}
</style>
</head>
<body>
<!-- 点击登录按钮,跳转的页面 servlet 判断用户名和密码是否正确-->
<form class="form-horizontal col-md-4 col-md-offset-4"
action="<%=application.getContextPath()%>/RegisterServlet" method="post">
<div class="form-group">
<label for="username" class="col-sm-3 control-label">用户名:</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="username" placeholder="请输入用户名" name="username" >
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-3 control-label">密 码</label>
<div class="col-sm-9">
<!-- 不允许为空-->
<input type="password" class="form-control" id="password" placeholder="请输入密码" name="password" required="required">
</div>
</div>
<div class="form-group">
<label for="repassword" class="col-sm-3 control-label">确认密码</label>
<div class="col-sm-9">
<!-- 不允许为空-->
<input type="password" class="form-control" id="repassword" placeholder="请确认密码" name="repassword" required="required">
</div>
</div>
<div class="form-group">
<label for="sex" class="col-sm-3 control-label">性 别</label>
<input type="radio" id="sex" name="sex" value="男">男
<input type="radio" id="sex" name="sex" value="女">女
</div>
<div class="form-group">
<label for="address" class="col-sm-3 control-label">输入地址</label>
<div class="col-sm-9">
<!-- 不允许为空-->
<input type="text" class="form-control" id="address" placeholder="地址" name="address" required="required">
</div>
</div>
<div class="form-group">
</div>
<div class="form-group">
<div class="col-sm-offset-6 col-sm-2">
<button type="submit" class="btn btn-default">注册</button>
</div>
<div class=" col-sm-2">
<button type="reset" class="btn btn-default">重置</button>
</div>
</div>
</form>
<!-- 域对象获取错误 -->
<p style="color: red">${error}</p>
</body>
</html>