一. 创建数据库和表
创建一个数据库ssm,在该数据库下创建一个user表
CREATE TABLE `ssm`.`user` (
`id` INT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(45) UNIQUE,
`password` VARCHAR(45),
`email` VARCHAR(45),
PRIMARY KEY (`id`));
二. 编写JavaBean对象
package com.server.pojo;
public class User {
private Integer id;
private String username;
private String password;
private String email;
public User() {
}
public User(Integer id, String username, String password, String email) {
this.id = id;
this.username = username;
this.password = password;
this.email = email;
}
public Integer getId() {
return id;
}
public void setId(Integer 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;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
'}';
}
}
三. Dao层
1. 创建Mapper接口
package com.server.mapper;
import com.server.pojo.User;
import org.apache.ibatis.annotations.Param;
public interface UserMapper {
//添加用户信息
void insertUser(User user);
//根据用户名查询用户信息
User queryUserByName(@Param("username") String username);
//根据用户名和密码查询用户信息
User queryUserByNameAndPassword(@Param("username") String username, @Param("password") String password);
}
2. 创建Mapper接口的映射文件
映射文件与mapper接口、接口中的方法对应,并在映射文件中编写sql语句(相当于实现了Mapper接口中的方法)。
注:一个表 对应 一个实体类 对应 一个mapper接口 对应 一个映射文件
①在resources目录下创建一个mapper目录(该目录名需要与存放Mapper接口的包名一致,其用于存放每个Mapper接口所对应的映射文件),这里是com/server/mapper
②在resources目录下的mapper目录下创建一个映射文件:UserMapper.xml(映射文件的名字需要与Mapper接口同名)
③映射文件里的namespace要和Mapper接口的全类名保持一致,这里为: com.server.mapper.UserMapper
④映射文件里的SQL语句的id要和mapper接口中的方法名一致
⑤映射文件里查询功能的返回值类型是数据库表对应的JavaBean对象
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.server.mapper.UserMapper"> <!--为mapper接口的全类名-->
<insert id="insertUser">
insert into user values(#{id},#{username},#{password},#{email})
</insert>
<select id="queryUserByName" resultType="User">
select * from user where username=#{username} <!-- {}中使用@Param注解内的值-->
</select>
<select id="queryUserByNameAndPassword" resultType="User">
select * from user where username=#{username} and password=#{password} <!-- {}中使用@Param注解内的值-->
</select>
</mapper>
四. Service层
1. 在service包下编写UserService接口
package com.server.service;
import com.server.pojo.User;
public interface UserService {
//用户注册,如果用户名已存在,则需要重新注册一个新的用户名(用户名不可以重复)
public void register(User user);
//用户登录,如果登录失败会返回null
public User login(String username, String password);
//判断用户名是否存在,返回true表示用户名已存在,返回false表示用户名可用
public User queryUsername(String username);
}
2. 在service.impl包下编写UserServiceImpl类来实现UserService接口
package com.server.service.impl;
import com.server.mapper.UserMapper;
import com.server.pojo.User;
import com.server.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public void register(User user) {
userMapper.insertUser(user);
}
@Override
public User login(String username, String password) {
return userMapper.queryUserByNameAndPassword(username, password);
}
@Override
public User queryUsername(String username) {
return userMapper.queryUserByName(username);
}
}
五. Web层 —— 编写控制器方法
package com.server.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class IndexController {
@RequestMapping("/")
public String index(){
return "index";
}
}
package com.server.controller;
import com.server.common.Constants;
import com.server.common.ReturnObject;
import com.server.pojo.User;
import com.server.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/loginPage")
public String goToLoginPage(){
return "user/login";
}
@RequestMapping("/registerPage")
public String goToRegisterPage(){
return "user/register";
}
@RequestMapping("/login")
@ResponseBody //添加@ResponseBody注解将返回的数据自动转化为json
public Object loginUser(String username, String password, String isRemPwd, HttpSession session, HttpServletResponse response){ //形参名和请求的参数名需要相同
User user = userService.login(username, password); //查询用户
ReturnObject returnObject = new ReturnObject(); //根据查询结果生成响应信息
if(user == null){
//登录失败
returnObject.setCode(Constants.RETURN_OBJECT_CODE_FAIL);
returnObject.setMessage("用户名或密码错误");
}else {
//登录成功
returnObject.setCode(Constants.RETURN_OBJECT_CODE_SUCCESS);
session.setAttribute(Constants.SESSION_USER, user);
//如果需要记住密码,则添加cookie
if("true".equals(isRemPwd)){
Cookie cookieUsername = new Cookie("username", username);
cookieUsername.setMaxAge(7*24*60*60); //cookie保存7天
response.addCookie(cookieUsername);
Cookie cookiePassword = new Cookie("password", password);
cookieUsername.setMaxAge(7*24*60*60); //cookie保存7天
response.addCookie(cookiePassword);
}else{
//如果不需要记住密码,则将以前创建的cookie删掉
Cookie cookieUsername = new Cookie("username", null);
cookieUsername.setMaxAge(0); //删除cookie
response.addCookie(cookieUsername);
Cookie cookiePassword = new Cookie("password", null);
cookieUsername.setMaxAge(0); //删除cookie
response.addCookie(cookiePassword);
}
}
return returnObject;
}
@RequestMapping("/register")
@ResponseBody
public Object registerUser(String username, String password, String email, HttpSession session ){
User user = new User(null, username, password, email);
ReturnObject returnObject = new ReturnObject(); //根据查询结果生成响应信息
if(userService.queryUsername(username) != null){
//用户名已存在,不能注册
returnObject.setCode(Constants.RETURN_OBJECT_CODE_FAIL);
returnObject.setMessage("用户名已存在");
}else {
//可以注册
userService.register(user); //注册
returnObject.setCode(Constants.RETURN_OBJECT_CODE_SUCCESS);
session.setAttribute(Constants.SESSION_USER, user);
}
return returnObject;
}
@RequestMapping("/logout")
public String logout(HttpServletResponse response, HttpSession session){
//清空cookie
Cookie cookieUsername = new Cookie("username", null);
cookieUsername.setMaxAge(0); //删除cookie
response.addCookie(cookieUsername);
Cookie cookiePassword = new Cookie("password", null);
cookieUsername.setMaxAge(0); //删除cookie
response.addCookie(cookiePassword);
//销毁session
session.invalidate();
return "redirect:/"; //重定向到首页
}
}
上面需要用到自定义common包下的Constants类(常数类)和ReturnObject类(响应对象类)
package com.server.common;
public class Constants {
public static final String RETURN_OBJECT_CODE_SUCCESS = "1"; //成功
public static final String RETURN_OBJECT_CODE_FAIL = "0"; //失败
public static final String SESSION_USER = "sessionUser";
}
package com.server.common;
public class ReturnObject {
private String code;
private String message;
public ReturnObject() {
}
public ReturnObject(String code, String message) {
this.code = code;
this.message = message;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
return "ReturnObject{" +
"code='" + code + '\'' +
", message='" + message + '\'' +
'}';
}
}
六. 编写页面
1.在WEB-INF目录下创建一个pages目录,在pages目录下编写index.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>首页</title>
<% //获取当前工程的路径
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
%>
<base href="<%=basePath%>">
</head>
<body>
<%-- 如果用户还没有登录,显示登录和注册菜单--%>
<c:if test="${empty sessionScope.sessionUser}">
<a href="loginPage"><input type="button" value="登录"/></a>
<a href="registerPage"><input type="button" value="注册"/></a>
</c:if>
<%-- 如果用户已经登录,显示欢迎用户和注销--%>
<c:if test="${not empty sessionScope.sessionUser}">
欢迎${sessionScope.sessionUser.username}
<a href="logout"><input type="button" value="退出"/></a>
</c:if>
</body>
</html>
2.在pages目录创建一个user目录,在user目录下创建login.jsp和register.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>用户登录</title>
<% //获取当前工程的路径
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
%>
<base href="<%=basePath%>">
<script type="text/javascript" src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> <!--引入jquery -->
<script type="text/javascript">
$(function(){
//给浏览器窗口添加键盘按下事件
$(window).keydown(function (e){
//如果按的是回车键,则提交登录请求
if(e.keyCode == 13){
$("#loginBtn").click();
}
});
//添加单击事件
$("#loginBtn").click(function(){
//获取请求参数
var loginUsername = $.trim($("#loginUsername").val()); //(将用户不小心输入的空格去掉)
var loginPassword = $.trim($("#loginPassword").val());
var isRemPwd = $("#isRemPwd").prop("checked");
//表单验证
//验证用户名:必须由字母或数字或下划线组成,并且长度为1-12位
var usernamePatt = /^\w{1,12}$/;
if(!usernamePatt.test(loginUsername)){
$("#msg").text("用户名不合法");
return;
}
//验证用户密码:必须由字母或数字或下划线组成,并且长度为6-12位
var passwordPatt = /^\w{6,12}$/;
if(!passwordPatt.test(loginPassword)){
$("#msg").text("密码不合法");
return;
}
//发送请求
$.ajax({
url:'login',
data:{
username:loginUsername, //需要和Controller中方法的形参同名
password:loginPassword,
isRemPwd:isRemPwd
},
type:'post',
dataType:'json',
success:function (data){
if(data.code=="1"){
//登录成功,跳转到首页
window.location.href="";
}else{
//登录失败,不跳转(显示错误信息)
$("#msg").text(data.message);
}
}
});
});
});
</script>
</head>
<body>
<span id="msg"></span> <br/>
<form>
用户名:<input type="text" id="loginUsername" value="${cookie.username.value}"> <br/>
密码:<input type="password" id="loginPassword" value="${cookie.password.value}"> <br/>
<input type="checkbox" id="isRemPwd">记住密码<br/>
<button type="button" id="loginBtn">登录</button>
</form>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>用户注册</title>
<% //获取当前工程的路径
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
%>
<base href="<%=basePath%>">
<script type="text/javascript" src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> <!--引入jquery -->
<script type="text/javascript">
$(function(){
//给浏览器窗口添加键盘按下事件
$(window).keydown(function (e){
//如果按的是回车键,则提交登录请求
if(e.keyCode == 13){
$("#registerBtn").click();
}
});
//添加单击事件
$("#registerBtn").click(function(){
//获取请求参数
var registerUsername = $.trim($("#registerUsername").val()); //(将用户不小心输入的空格去掉)
var registerPassword = $.trim($("#registerPassword").val());
var confirmPassword = $.trim($("#confirmPassword").val());
var email = $.trim($("#email").val());
//表单验证
//验证用户名:必须由字母或数字或下划线组成,并且长度为1-12位
var usernamePatt = /^\w{1,12}$/;
if(!usernamePatt.test(registerUsername)){
$("#msg").text("用户名不合法");
return;
}
//验证用户密码:必须由字母或数字或下划线组成,并且长度为6-12位
var passwordPatt = /^\w{6,12}$/;
if(!passwordPatt.test(registerPassword)){
$("#msg").text("密码不合法");
return;
}
//验证确认密码:必须和密码相同
if(confirmPassword != registerPassword){
$("#msg").text("密码不一致");
return;
}
//发送请求
$.ajax({
url:'register',
data:{
username:registerUsername, //需要和Controller中方法的形参同名
password:registerPassword,
email:email
},
type:'post',
dataType:'json',
success:function (data){
if(data.code=="1"){
//注册成功,跳转到登录页面
window.location.href="loginPage";
}else{
//注册失败,不跳转(显示错误信息)
$("#msg").text(data.message);
}
}
});
});
});
</script>
</head>
<body>
<span id="msg"></span> <br/>
<form action="register" method="post">
用户名:<input type="text" id="registerUsername"> <br/>
用户密码:<input type="password" id="registerPassword"> <br/>
确认密码:<input type="password" id="confirmPassword"> <br/>
电子邮箱:<input type="text" id="email"> <br/>
<button type="button" id="registerBtn">注册</button>
</form>
</body>
</html>