随着技术的发展,显示层的框架也是层出不穷,本次使用easyui来实现精确提示的登录功能,实现思路:
会根据用户输入的账户名或者是手机号来判断用户是否存在,然后验证密码是否正确,以及验证码是否正确。其中账户名或手机号以及验证码的验证方式都是通过框架中的表单验证提供的异步验证完成,也就是在用户输入的过程中就进行判断,直到用户输入正确的内容,表单验证才会通过。而只有当用户名和验证码都验证通过,并且密码不为空的时候才会进行登录的验证。这也就是上一个项目中所提到的精确提示登录信息。并且,拦截器的配置与之前的操作一致,所以最多只需要修改spring-mvc.xml文件中设置某些不需要拦截的路径即可。
完成用户名和验证码的检测
考虑到本次的验证码检测后台与之前项目中的后台实现完全一样,所以本次就不进行相关验证码内容展示,只会列出验证码在前台的改进。
1、建立Staff.java实体类
public class Staff {
private Integer staffId;
private String staffName;
private String staffAccount;
private String staffPwd;
private String staffPhone;
private String staffPubtime;
private Integer staffIsOut;
}
2、建立IStaffDAO.java类
根据精确提示的提示功能,并且接收到的是账户名或者手机号两种类型的数据内容,所以考虑到了如下的两种验证方式:
·①在业务层将用户输入的用户名或者手机号为Staff对象的对应属性都赋值,然后查询数据库
·②在dao层设置两个方法,分别根据手机号查询用户,或者根据账户查询用户
以上的两种查询方式中,第一种查询方式不需要业务层进行判断用户输入的内容是不是手机号,而第二种却需要在业务层进行判断,而其中的功能当然是第二种方式完成的更加符合实际情况,不过本次使用第①中简单的方式来查询。
public interface IStaffDAO {
/**
* <pre> 根据用户名或者手机号查询是否存在员工
* @param vo 保存有用户输入的账户名或者手机号
* @return 如果存在,则返回查询出来的员工ID,否则返回null
* </pre>
*/
@Select("SELECT t.staff_id AS staffId,t.staff_account AS staffAccount,"
+" t.staff_password AS staffPwd,t.staff_phone AS staffPhone"
+" FROM t_staff t"
+" WHERE t.staff_account=#{staffAccount} OR t.staff_phone=#{staffPhone}")
public Staff findByAccountOrPhone(Staff vo);
}
3、建立IStaffService.java接口以及其实现类StaffServiceImpl.java类
public interface IStaffService {
/**
* <pre>将用户输入的内容分别设置到Staff对象的账户和手机号对应属性中
* 调用DAO中的findByAccountOrPhone方法查询是否存在有该账户或手机号
* @param accountOrPhone 用户输入的账户或者手机号
* @return 如果存在则返回true,否则返回false
* </pre>
*/
public boolean validateAccountOrPhone(String accountOrPhone);
}
@Service
public class StaffServiceImpl implements IStaffService {
@Autowired
private IStaffDAO staffDAO;
@Override
public boolean validateAccountOrPhone(String accountOrPhone) {
if(accountOrPhone != null && !"".equals(accountOrPhone)){
Staff vo = new Staff();
vo.setStaffAccount(accountOrPhone);
vo.setStaffPhone(accountOrPhone);
return this.staffDAO.findByAccountOrPhone(vo) != null;
}
return false;
}
}
根据这样的逻辑,只需要在控制层建立一个类似于验证码验证的方法,并且对应于easyui的异步验证所需要的返回值为boolean类型,即可简单的完成用户名检测功能。同时考虑到登录页面中也会进行相应的表单验证,所以此处就不再进行内容的非空判断的赘述。因为还会加入拦截器的操作。
4、建立StaffController.java类
@Controller
@RequestMapping("logincontroller")
public class LoginController {
@Resource
private IStaffService staffService;
@RequestMapping("validateAP")
@ResponseBody
public boolean validateAP(String accountOrPhone){
return this.staffService.validateAccountOrPhone(accountOrPhone);
}
}
5、建立login.ftl文件
<#assign base=request.contextPath/>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form id="loginForm">
<div>
用户名或手机号:<input type="text" id="staffAccountPhone"/></br>
密 码:<input type="password" id="staffPwd" class="easyui-textbox" required=true/></br>
验证码:<input type="text" id="code"/>
<img src="${base}/code/init" id="codeImg"/></br>
</div>
</form>
<script>
$("#codeImg").on("click",function(){changeImg()});
var changeImg = function(){
$(codeImg).prop("src","${base}/code/init?temp="+Math.random());
}
$('#code').validatebox({
required: true,
validType: "remote['${base}/code/validatecode','yanzhengma']",
tipPosition:'bottom' ,
deltaX:20
});
$('#staffAccountPhone').validatebox({
required: true,
validType: "remote['${base}/logincontroller/validateAP','accountOrPhone']",
tipPosition:'top' ,
deltaX:20
});
</script>
</body>
</html>
按照如上的操作内容,即可完成用户名和验证码的检测操作,然后进行登录检测。
进行登录验证
如果在页面中不进行表单验证,也就是表单的非空验证,那么在后台就必须要进行内容的非空验证。按理说页面的非空验证之后,在后台为了保险起见,还应该进行一层内容的非空验证操作,可是在设定好非空验证之后,会折叠很多层的if-else语句,内容上会出现很多不必要的代码。所以本次业务层中不再进行内容的非空验证。
在提交登录验证之前,前台的表单验证保证了输入的内容不为空,并且根据用户输入的用户名或者手机号查到了对应的用户。所以接下来的操作,首先需要在业务层中继续调该方法,并且接收查询出来的用户信息。然后在进行相关的判断。
1、在IStaffService.java接口中扩充新的方法
/**
* <pre>调用DAO中的findByAccountOrPhone方法查询出该员工信息,
* 然后验证用户输入账户或手机号不为空,并且输入的密码 是否正确
* @param vo 保存有用户输入的账户或手机号
* @return 如果验证成功,则返回用户查询出来的用户信息,否则返回null
* </pre>
*/
public Staff validateStaffPwd(Staff vo);
2、在StaffServiceImpl.java类中进行实现
@Override
public Staff validateStaffPwd(Staff vo) {
if(vo != null){
Staff sta = this.staffDAO.findByAccountOrPhone(vo);
if(sta.getStaffPwd().equals(vo.getStaffPwd())){
return sta;
}
}
return null;
}
3、在StaffController.java类中扩充新的方法
考虑到后续会用到对应的用户信息,所以需要将登陆的用户信息保存在session的属性范围中,名称定义为:“uid”,并且通过设置flag变量的值,来设定不同的提示内容
·flag=1 :表示密码错误
·flag=2:表示登录成功
@RequestMapping("validateLogin")
@ResponseBody
public int login(HttpServletRequest request,Staff vo){
int flag = 0; //用来设置提示信息
HttpSession session = request.getSession(true);
session.removeAttribute("uid");
Staff sta = this.staffService.validateStaffPwd(vo);
if(sta != null){ //用户登录成功
flag = 2; //2表示登录成功
session.setAttribute("uid", sta.getStaffId());
}else{
flag = 1; //1密码错误
}
return flag;
}
4、根据控制层设定的内容,在页面中进行不同消息的提示,以及路径的跳转设置
function user_login(){
var isValid = $("#loginForm").form('validate')
if(isValid){
var staffAccountPhone = $("#staffAccountPhone").val();
var staffPwd = $("#staffPwd").val();
$.ajax({
url:"${base}/logincontroller/validateLogin",
data:{"staffAccount":staffAccountPhone,"staffPhone":staffAccountPhone,"staffPwd":staffPwd},
type:"post",
dataType:"json",
success:function(data){
if(data == 1){
$.messager.alert("提示","密码错误!");
//重置表单
$("#loginForm").form('reset');
//切换验证码
changeImg()
}else{
$.messager.alert("提示","登录成功");
location.href="${base}/";
}
}
});
}
}
至此,登录功能完成。