前端-5-【登录】验证-心血版

话说:

各位读者,晚上好!今天总结下登录的前端验证和后端代码,虽说是作为前端发布的,但是重心还是在后端。

包含功能:
1.前端Ajax验证;非空验证、验证码验证;
2.根据是否记住?存放用户于cookie中;存放Session中;
3.JSP页面显示

目录


1.前端效果展示
2.前端验证
3.后端代码
4.JSP页面代码
5.总结


难度系数:★★☆☆☆
建议用时:1H

1.前端效果展示

这里写图片描述

2.前端验证

1)页面代码
2)验证代码

1)页面代码

<form id="loginForm"  action="userLogin" method="post" novalidate="novalidate" onsubmit="return checkLoginForm()">
	<table>
		<tbody>	
		<tr>
			<td></td>
			<td>
				<span id="loginInfo" style="color:red;font-size:15px;font-weight:bolder;"><%=loginMsg %></span>
			</td>
		</tr>
		
		<tr>
			<th>
					用户名/E-mail:
			</th>
			<td>
				<input type="text" id="userName" name="userName"  value="<%=userName%>"class="text" maxlength="20">
				<span id="userNameInfo"></span>
			</td>
		</tr>
		<tr>
			<th>
				密&nbsp;&nbsp;码:
			</th>
			<td>
				<input type="password" id="password" name="password" value="<%=password%>" class="text" maxlength="20" autocomplete="off">
				<span id="passwordInfo" style="color:red;font-size:15px;font-weight:bolder;"></span>
			</td>
		</tr>
			<tr>
				<th>
					验证码:
				</th>
				<td>
					<span class="fieldSet">
						<input type="text" id="code" name="code" class="text captcha" maxlength="4" autocomplete="off" style="width:105px;">
						&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img id="captchaImage" class="captchaImage" src="vertifyCode" onclick="this.src='vertifyCode?'+new Date()" title="点击更换验证码" style="height:30px;">
						
					</span>
					<span id="codeInfo"></span>
				</td>
			</tr>
		<tr>
			<th>&nbsp;
			</th>
			<td>
				<label>
					<input type="checkbox" id="remember" name="remember" value="1" style="width: 20px;height:20px;">记住我
					
				</label>
				<label>
					&nbsp;&nbsp;<a >找回密码</a>
				</label>
			</td>
		</tr>
		<tr>
			<th>&nbsp;
				
			</th>
			<td>
				<input type="submit"  class="submit" value="登 录">
			</td>
		</tr>
		<tr class="register">
			<th>&nbsp;
				
			</th>
			<td>
				<dl>
					<dt>还没有注册账号?</dt>
					<dd>
						立即注册即可体验在线购物!
						<a href="register.jsp">立即注册</a>
					</dd>
				</dl>
			</td>
		</tr>
	</tbody></table>
</form>


2)验证代码

<!--  引入jQuery-->
<script src="js/jquery-1.8.3.js"></script>

<!--用户名Ajax验证  -->
<script type="text/javaScript">
	$(function() {
		$("#userName").focus();
		$("#userName").blur(function() {
			var userName =	$(this).val().trim();
			
			console.log("用户名:"+userName);
			//登录 用户名Ajax验证
			$.ajax({
				url:"loginForm",
				type:"get",
				dataType:"json",
				async:true,
				data:{"userName":userName},
				success:function(data) {
					console.log("后台传过来的data:"+data);
					console.log("登录名请求后台成功!");
					if(data == null) {
						$("#userNameInfo").html("×");
						$("#userNameInfo").css({"color":"red","font-size":"25px","font-weight":"bolder"});
					}else{
						$("#userNameInfo").html("√");
						$("#userNameInfo").css({"color":"green","font-size":"22px","font-weight":"bolder"});

					}
					
				},
				error:function() {
					console.log("登录请求后台失败!");
				}
			});
		})
		
		
		//密码位数验证
		$("#password").blur(function() {
			var password = $(this).val().trim();
			console.log("密码长度:"+password.length);
			if(password.length<6){
				$("#passwordInfo").html("密码位数有误");
				//$(this).focus();
			}else{
				$("#passwordInfo").html("");

			}
		
		});
		
		
		//前台验证验证码
		$("#code").keyup(function() {
			var code = $(this).val().trim();
			//因为要用到转换为小写函数,这个属于DO对象的,转换麻烦,直接用JS方法取值
			var code2 = document.getElementById("code").value.toLowerCast();
			var  remember = $("#remember").val().trim();
			console.log("键盘动了...");
			console.log("转小写后的验证码:"+code2);
			console.log("是否记住《《《《《《《《《《:"+remember);
			//1.Ajax 请求后台拿到验证码
			$.ajax({
				url:"getRegisterCode",
				type:"get",
				dataType:"json",
				async:true,
				data:{"code":code},
				success:function(data) {
					console.log("登录请求后台成功啦!"+data);
					//思路是:如果用户输入错误,直接清空;如果正确,直接√
					if(code2.length>4) {
						$("#codeInfo").html("验证码有误");
		$("#codeInfo").css({"color":"red","font-size":"15px","font-weight":"bolder"});
						//$("#code").val("").focus();
					}else if(code2.length==4){
						if(code2 == data){
							$("#codeInfo").html("√");
				$("#codeInfo").css({"color":"green","font-size":"25px","font-weight":"bolder"});
						}else{
							$("#codeInfo").html("验证码有误");
			$("#codeInfo").css({"color":"red","font-size":"15px","font-weight":"bolder"});
	
						}
					}else{
							//这里判断有点多余,但是也无可厚非,用户可能回删数据
						if(code2 == data) {
							$("#codeInfo").html("√");
		$("#codeInfo").css({"color":"green","font-size":"25px","font-weight":"bolder"});
						}else{
							$("#codeInfo").html("验证码有误");
	$("#codeInfo").css({"color":"red","font-size":"15px","font-weight":"bolder"});
						}
					}
					
				},
				error:function() {
					console.log("登录请求后台失败!");
				}
			})

		});

			//是否记住?
			
		$("#remember").click(function() {
			console.log("进来了!");
			var remember =$(this).val().trim();
			console.log("根据选择判断是否记住???????????????"+remember);
		})
		
	});
	
	
	//onsubmit事件验证
	function	checkLoginForm(){
		var flag = false;
		//提交验证
		$(function() {
			var userName = $("#userName").val().trim();
			var password = $("#password").val().trim();
			var code = $("#code").val().trim();
			var remember = $("#remember").val().trim();
			console.log("用户名"+userName);
			console.log("是否记住?>>>>>>>>>>>>>>>>"+remember);
			if(userName == "") {
				console.log("用户名不能为空。。");
				$("#loginInfo").html("请填写用户名");
				$("#userName").focus();
				return false;
			}else{
				$("#loginInfo").html("");
				if(password == "") {
					$("#loginInfo").html("请填写密码");
					$("#password").focus();
					return false;
				}else{
					$("#loginInfo").html("");
					if(code =="") {
					 	$("#loginInfo").html("请填写验证码");
					 	$("#code").focus();
					 	return false;
					}else{
						$("#loginInfo").html("");
						flag = true;
						return false;//这里return什么不重要
					}
					
				}
			}
		})
		
			return flag;//这里才是控制表单提交与否的关键所在! 因为执行完$(function(){})之后,此方法需要返回值  onsubmit = "return checkLoginForm()"
	}
</script>

温馨提示:验证码长度可以直接用input的属性maxlength控制,而不用在前端代码中判断。

3.后端代码

1)Pojo
2)Dao
3)UserMapper.xml
4)Controller层

我们要优化的问题是:注册用户会Ajax验证用户名;登录Ajax也会验证用户名;登录后还要进行判断操作,这3种方式都用1个SQL语句搞定,而不用写2个。
Mybatis的动态SQL,非常方便。因为前端的注册userName和登录userName都是blur()事件,这个时候password都是null(String password)。

1)Pojo

这里面当然也有:【记住我?】 这个属性。

public class User {
private int userId;
private String userName;
private String password;
private String rePassword;
private String email;
private String name;
private String sex;
private Date birth;
private String address;
private String code;
private Date registerTime;
private Date loginTime;

private int remember;//记住我?checkbox 
public User() {}
其他省略......
}

2)Dao

public interface UserDao {

//注册用户名Ajax验证   登录Ajax验证  及登录都用这个方法
	User getUserByUserName(User user);
}

3)UserMapper.xml

<!-- 3.用户名是否存在 -->
	<select id="getUserByUserName" parameterType="com.hmc.pojo.User"  resultType="com.hmc.pojo.User">
		select * from user where userName = #{userName}
		<if test="password != null">
			and 
			password  = #{password}
		</if>
	</select>

注意,用到 where或者 c:if等,参数要封装在一个对象里面,否则找不到。
这里是动态SQL的核心。

4)Controller层

Service层就省略,调一下Dao方法即可。
这里要搞定的事情是:
1.取得后台验证码,并回调给前台做判断;
2.查数据,存Cookie,存Session,页面跳转

@Controller
public class StoreCustomerController {
@Autowired
	private UserService userService;
	@Autowired
	private VertifyCodeServlet vertifyCodeServlet;


//6.登录用户名Ajax验证
	
	@RequestMapping("loginForm")
	@ResponseBody
	public String vertifyLoginUserName(User user) {
		User user2 =	userService.getUserByUserName(user);
		System.out.println("根据用户名查到的用户为:"+user2);
		if(user2 != null) {
			System.out.println("转换后的用户json不为空:格式为:"+new Gson().toJson(user2));
			return new Gson().toJson(user2);//当然的导包进去喽~
		}else {
			System.out.println("转换后的用户json为空:格式为:"+new Gson().toJson(user2));//null
			return new Gson().toJson(user2);
		}
	}


//7.用户登陆操作
	
	@RequestMapping("userLogin")
	public String userLogin(User user,Model model,HttpServletResponse resp,HttpServletRequest req) {
		int remember  =	user.getRemember();
		System.out.println("用户名是否记住?   "+remember);
		//1.判断用户名和密码是否正确?正确在进行以下操作
			User user2 =	userService.getUserByUserName(user);
			System.out.println("动态Sql 得到的用户为:"+user2);
			if(user2 == null) {
				model.addAttribute("loginMsg", "用户名或密码不正确");//因为是重定向,所以存不了值,怎么办?
				Cookie cookie = new Cookie("loginMsg", "用户名或密码不正确");
				cookie.setMaxAge(4);//4s就够啦,下次登录就会消失
				resp.addCookie(cookie);
				
				//返回登录接界面,并给错误信息提示
				return "redirect:login.jsp";
			}else {
				//2.根据用户是否勾选记住我?选择是否存cookie
				if(remember == 1) {
					//如果用户勾选记住我?就先默认存储60S
					Cookie cookieUserName = new Cookie("userName", user2.getUserName());
					Cookie cookiePassword = new Cookie("password", user2.getPassword());
					cookieUserName.setMaxAge(60);
					cookiePassword.setMaxAge(60);
					
					resp.addCookie(cookieUserName);
					resp.addCookie(cookiePassword);
				}
				
				//不论勾选记住否,都要存到session里面
				req.getSession().setAttribute("user", user2);
				
				//跳转页面
				return "index";
				
			}
	}


}
--------------------------------------------------------------------------------

4.JSP页面代码

这个主要是从cookie里面拿数据:用户信息和登录错误信息

<%
//如果用户保存了cookie,取出来
	Cookie[] cookies =	request.getCookies();
	String userName = "";
	String password = "";
	String loginMsg = "";
	if(cookies != null) {
		for(int i=0;i<cookies.length;i++) {
			//取出用户名和密码
			if("userName".equals(cookies[i].getName())) {
				 userName = cookies[i].getValue();
			}
			if("password".equals(cookies[i].getName())) {
				
				 password = cookies[i].getValue();
			}
			//取出用户名和密码不正确时的提示信息
			if("loginMsg".equals(cookies[i].getName())) {
				
				 loginMsg =  cookies[i].getValue();
			}
		}
	}
%>


页面这么取值:
value="<%=userName%>"
 value="<%=password%>" 

5.总结


1.input框中maxlength属性作用蛮大的。比如,用这个属性后,前端验证就不用判断code.length>4的情况了,因为不可能输入4位!
直接在表单里面做了控制!

之前我是这么处理的:
if(code.length>4){
$("#code").val("").focus();这样的效果就是强制清空输入内容了,感觉还是有点强制!
}

2.后端怎么知道前端是否记住用户名呢?怎么判定选择还是未选择的状态呢?

在前端,地球人都知道,type=“checkbox” 如果选择,那么用前端技术直接判断其属性
$("#remember").checked == true;
判断即可,但是后端怎么判断呢?

<input type="checkbox" name="remember" value="1"> 

value的值给还是不给?不给后端根据name获取到的是啥情况?
给了比如value=“1” 那么选择或者不选择,框架中,封装后对象怎么判断选择还是没选择?这个和你封装的对象参数类型有关。比如,我们是否记住?对应user对象的一个属性remember 是int类型的,那么value=“1” 如果用户勾选,那么后台获取的就是这个value值;若未勾选,就是remember实体类属性对应的默认值。比如:int 默认未勾选就是0; String 未勾选默认就是null…

3.问题背景:无论注册用户名Ajax验证、登录用户名Ajax验证、登录后整个用户判断;
都需要用到同一个SQL语句,所以写成动态的,而不是写2个SQL。

.<select id="getUserByUserName" parameterType="com.hmc.pojo.User"  resultType="com.hmc.pojo.User">
				select * from user where userName = #{userName}
				<if test="password != null || password != ''">
					and 
					password  = #{password}
				</if>
		 </select>
	 这段代码有什么问题?在c:if test=""里面,是不能用|| 或者 && 只能用  and  or 
	 不行你试一试?另外,password没有,就null,当然满足 != ""所以会满足条件,所以就差不到。不是|| 或&& 用错!而是条件错了!
	 
	 	<!-- 3.用户名是否存在 -->
<select id="getUserByUserName" parameterType="com.hmc.pojo.User"  resultType="com.hmc.pojo.User">
				select * from user where userName = #{userName}
				<if test="password != null">
					and 
					password  = #{password}
				</if>
			</select>

4.autocomplete=“off” inpu属性
input 的属性autocomplete 默认为on其含义代表是否让浏览器自动记录之前输入的值
很多时候,需要对客户的资料进行保密,防止浏览器软件或者恶意插件获取到可以在input中加入autocomplete=“off” 来关闭记录

5.Cookie、Session还是蛮神奇的。Cookie在创建添加的时候,用到的是response对象,前端取值遍历的时候,用到的是request对象,Session用request对象。
这个要深刻理解。用户发起请求,是否存Cookie,用户选择,用户一旦选择,那么服务器在处理请求的时候,会给用户地址带一个信息(Cookie),添加Cookie是服务器端在响应的时候做的处理,所以response.addCookie()要这么用;
下次用户再次请求,便携带上次服务器给它传递的cookie信息,这个时候,前端是否显示,自然request就能够拿到这些信息了。所有在得到cookie的时候,用request.getCookies()得到一个Coookies[];同理,Session会话是用户请求主动建立的,每次添加用request.getSession().addAttribute()即可。

6.我在处理用户名或密码错误的时候,因为要重定向,所以没发用model.addAttribute()带参;但是又不能用session,因为下次访问login.jsp,错误提示不能一直在吧?所以用的是cookie,生命周期短点,有点小残忍。


好了!开饭吧!一会再会!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值