资料来源于:B站尚硅谷JavaWeb教程(全新技术栈,全程实战) ,本人才疏学浅,记录笔记以供日后回顾
由于是多个视频内容混合在一起,因此只放了第一个链接
视频链接
知识点
1. 注册页面表单验证
1) <form>有一个事件 onsubmit ,
onsubmit="return false" , 那么表单点击提交按钮时不会提交
onsubmit="return true" , 那么表单点击提交按钮时会提交
2) 获取文档中某一个节点的方式:
//DOM:Document 文档对象模型
//var unameTxt = document.getElementById("unameTxt");
//BOM:Browser 浏览器对象模型
//document.forms[0].uname
2. 原生的Ajax(了解)
第一步: 客户端发送异步请求;并绑定对结果处理的回调函数
1) <input type="text" name="uname" onblur="ckUname()"/> 当失去焦点时调用ckUname()
2) 定义ckUname方法:
- 创建XMLHttpRequest对象
- XMLHttpRequest对象操作步骤:
- open("GET",url,true)
- onreadyStateChange 设置回调
- send() 发送请求
- 在回调函数中需要判断XMLHttpRequest对象的状态:
readyState(0-4) , status(200)
第二步:服务器端做校验,然后将校验结果响应给客户端
3.详细解释
Ajax : 异步的JavaScript and XML
目的: 用来发送异步的请求,然后当服务器给我响应的时候再进行回调操作
好处: 提高用户体验;局部刷新:降低服务器负担、减轻浏览器压力、减轻网络带宽压力
开发步骤:
1) 创建XMLHttpRequest
2) 调用open进行设置:"GET" , URL , true
3) 绑定状态改变时执行的回调函数 - onreadystatechange
4) 发送请求 - send()
5) 编写回调函数,在回调函数中,我们只对XMLHttpRequest的readystate为4的时候感兴趣
我们只对XMLHttpRequest的status为200的时候感兴趣
0: (Uninitialized) the send( ) method has not yet been invoked.
1: (Loading) the send( ) method has been invoked, request in progress.
2: (Loaded) the send( ) method has completed, entire response received.
3: (Interactive) the response is being parsed.
4: (Completed) the response has been parsed, is ready for harvesting.
0 - (未初始化)还没有调用send()方法
1 - (载入)已调用send()方法,正在发送请求
2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
3 - (交互)正在解析响应内容
4 - (完成)响应内容解析完成,可以在客户端调用了
代码示例
regist.html代码
点击查看代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>尚硅谷会员注册页面</title>
<link type="text/css" rel="stylesheet" th:href="@{/static/css/style.css}" />
<link rel="stylesheet" th:href="@{/static/css/register.css}"/>
<style type="text/css">
.login_form {
height: 420px;
margin-top: 25px;
}
</style>
<script language="JavaScript" th:src="@{/static/script/regist.js}"></script>
</head>
<body>
<div id="login_header">
<a href="../index.html">
<img class="logo_img" alt="" th:src="@{/static/img/logo.gif}" />
</a>
</div>
<div class="login_banner">
<div class="register_form">
<h1>注册尚硅谷会员</h1>
<form th:action="@{/user.do}" method="post" onsubmit="return preRegist() ;">
<input type="hidden" name="operate" value="regist"/>
<div class="form-item">
<div>
<label>用户名称:</label>
<input id="unameTxt" type="text" placeholder="请输入用户名" name="uname" value="hello2022" onblur="ckUname(this.value)"/>
</div>
<span id="unameSpan" class="errMess">用户名应为6~16位数字和字母组成</span>
</div>
<div class="form-item">
<div>
<label>用户密码:</label>
<input id="pwdTxt" type="password" placeholder="请输入密码" name="pwd" value="ok"/>
</div>
<span id="pwdSpan" class="errMess">密码的长度至少为8位</span>
</div>
<div class="form-item">
<div>
<label>确认密码:</label>
<input id="pwdTxt2" type="password" placeholder="请输入确认密码" value="ok"/>
</div>
<span id="pwdSpan2" class="errMess">密码两次输入不一致</span>
</div>
<div class="form-item">
<div>
<label>用户邮箱:</label>
<input id="emailTxt" type="text" placeholder="请输入邮箱" name="email" value="bao@126.com"/>
</div>
<span id="emailSpan" class="errMess">请输入正确的邮箱格式</span>
</div>
<div class="form-item">
<div>
<label>验证码:</label>
<div class="verify">
<input type="text" name="verifyCode" placeholder="" />
<img th:src="@{/kaptcha.jpg}" alt="" />
</div>
</div>
<span class="errMess">请输入正确的验证码</span>
</div>
<button class="btn">注册</button>
</form>
</div>
</div>
<div id="bottom">
<span>
尚硅谷书城.Copyright ©2015
</span>
</div>
</body>
</html>
regist.js代码
点击查看代码
function $(id){
return document.getElementById(id);
}
function preRegist(){
//用户名不能为空,而且是6~16位数字和字母组成
var unameReg = /[0-9a-zA-Z]{6,16}/;
var unameTxt = $("unameTxt");
var uname = unameTxt.value ;
var unameSpan = $("unameSpan");
if(!unameReg.test(uname)){
unameSpan.style.visibility="visible";
return false ;
}else{
unameSpan.style.visibility="hidden";
}
//密码的长度至少为8位
var pwdTxt = $("pwdTxt");
var pwd = pwdTxt.value ;
var pwdReg = /[\w]{8,}/; // /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,}$/;
var pwdSpan = $("pwdSpan");
if(!pwdReg.test(pwd)){
pwdSpan.style.visibility="visible";
return false ;
}else{
pwdSpan.style.visibility="hidden";
}
//密码两次输入不一致
var pwd2 = $("pwdTxt2").value ;
var pwdSpan2 = $("pwdSpan2") ;
if(pwd2!=pwd){
pwdSpan2.style.visibility="visible";
return false ;
}else{
pwdSpan2.style.visibility="hidden";
}
//请输入正确的邮箱格式
var email = $("emailTxt").value ;
var emailSpan = $("emailSpan");
var emailReg = /^[a-zA-Z0-9_\.-]+@([a-zA-Z0-9-]+[\.]{1})+[a-zA-Z]+$/;
if(!emailReg.test(email)){
emailSpan.style.visibility="visible";
return false ;
}else{
emailSpan.style.visibility="hidden";
}
return true ;
}
//如果想要发送异步请求,我们需要一个关键的对象 XMLHttpRequest
var xmlHttpRequest ;
function createXMLHttpRequest(){
if(window.XMLHttpRequest){
//符合DOM2标准的浏览器 ,xmlHttpRequest的创建方式
xmlHttpRequest = new XMLHttpRequest() ;
}else if(window.ActiveXObject){//IE浏览器
try{
xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}catch (e) {
xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP")
}
}
}
function ckUname(uname){
createXMLHttpRequest();
var url = "user.do?operate=ckUname&uname="+uname ;
xmlHttpRequest.open("GET",url,true);
//设置回调函数
xmlHttpRequest.onreadystatechange = ckUnameCB ;
//发送请求
xmlHttpRequest.send();
}
function ckUnameCB(){
if(xmlHttpRequest.readyState==4 && xmlHttpRequest.status==200){
//xmlHttpRequest.responseText 表示 服务器端响应给我的文本内容
//alert(xmlHttpRequest.responseText);
var responseText = xmlHttpRequest.responseText ;
// {'uname':'1'}
//alert(responseText);
if(responseText=="{'uname':'1'}"){
alert("用户名已经被注册!");
}else{
alert("用户名可以注册!");
}
}
}
UserController类
检测用户名是否被注册
点击查看代码
package com.ypf.book.controller;
import com.ypf.book.pojo.Cart;
import com.ypf.book.pojo.User;
import com.ypf.book.service.CartItemService;
import com.ypf.book.service.UserService;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
public class UserController {
private UserService userService ;
private CartItemService cartItemService ;
public String login(String uname , String pwd , HttpSession session){
User user = userService.login(uname, pwd);
if(user!=null){
Cart cart = cartItemService.getCart(user);
user.setCart(cart);
session.setAttribute("currUser",user);
return "redirect:book.do";
}
return "user/login";
}
public String regist(String verifyCode , String uname , String pwd , String email , HttpSession session , HttpServletResponse response) throws IOException {
Object kaptchaCodeObj = session.getAttribute("KAPTCHA_SESSION_KEY");
if(kaptchaCodeObj==null || !verifyCode.equals(kaptchaCodeObj)){
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//out.println("<script language='javascript'>alert('验证码不正确!');window.location.href='page.do?operate=page&page=user/regist';</script>");
out.println("<script language='javascript'>alert('验证码不正确!');</script>");
//return "user/regist";
return "user/regist";
}else{
if(verifyCode.equals(kaptchaCodeObj)){
userService.regist(new User(uname , pwd , email,0));
return "user/login";
}
}
return "user/login";
}
public String ckUname(String uname){
User user = userService.getUser(uname);
if(user!=null){
//用户名已经被占用,不可以注册
return "json:{'uname':'1'}";
//return "ajax:1";
}else{
//用户名可以注册
return "json:{'uname':'0'}";
//return "ajax:0";
}
}
}
DispatcherServlet类
修改DispatcherServlet类的视图处理,添加对json格式的解析。
点击查看代码
package com.ypf.myssm.myspringmvc;
import com.ypf.myssm.ioc.BeanFactory;
import com.ypf.myssm.util.StringUtil;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
@WebServlet("*.do")
public class DispatcherServlet extends ViewBaseServlet {
private BeanFactory beanFactory ;
public DispatcherServlet(){
}
public void init() throws ServletException {
super.init();
//之前是在此处主动创建IOC容器的
//现在优化为从application作用域去获取
//beanFactory = new ClassPathXmlApplicationContext();
ServletContext application = getServletContext();
Object beanFactoryObj = application.getAttribute("beanFactory");
if(beanFactoryObj!=null){
beanFactory = (BeanFactory)beanFactoryObj ;
}else{
throw new RuntimeException("IOC容器获取失败!");
}
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置编码
//request.setCharacterEncoding("UTF-8");
//假设url是: http://localhost:8080/pro15/hello.do
//那么servletPath是: /hello.do
// 我的思路是:
// 第1步: /hello.do -> hello 或者 /fruit.do -> fruit
// 第2步: hello -> HelloController 或者 fruit -> FruitController
String servletPath = request.getServletPath();
servletPath = servletPath.substring(1);
int lastDotIndex = servletPath.lastIndexOf(".do") ;
servletPath = servletPath.substring(0,lastDotIndex);
Object controllerBeanObj = beanFactory.getBean(servletPath);
String operate = request.getParameter("operate");
if(StringUtil.isEmpty(operate)){
operate = "index" ;
}
try {
Method[] methods = controllerBeanObj.getClass().getDeclaredMethods();
for(Method method : methods){
if(operate.equals(method.getName())){
//1.统一获取请求参数
//1-1.获取当前方法的参数,返回参数数组
Parameter[] parameters = method.getParameters();
//1-2.parameterValues 用来承载参数的值
Object[] parameterValues = new Object[parameters.length];
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
String parameterName = parameter.getName() ;
//如果参数名是request,response,session 那么就不是通过请求中获取参数的方式了
if("request".equals(parameterName)){
parameterValues[i] = request ;
}else if("response".equals(parameterName)){
parameterValues[i] = response ;
}else if("session".equals(parameterName)){
parameterValues[i] = request.getSession() ;
}else{
//从请求中获取参数值
String parameterValue = request.getParameter(parameterName);
String typeName = parameter.getType().getName();
Object parameterObj = parameterValue ;
if(parameterObj!=null) {
if ("java.lang.Integer".equals(typeName)) {
parameterObj = Integer.parseInt(parameterValue);
}
}
parameterValues[i] = parameterObj ;
}
}
//2.controller组件中的方法调用
method.setAccessible(true);
Object returnObj = method.invoke(controllerBeanObj,parameterValues);
//3.视图处理
String methodReturnStr = (String)returnObj ;
if(methodReturnStr.startsWith("redirect:")){ //比如: redirect:fruit.do
String redirectStr = methodReturnStr.substring("redirect:".length());
response.sendRedirect(redirectStr);
}else if(methodReturnStr.startsWith("json:")){
String jsonStr = methodReturnStr.substring("json:".length());
PrintWriter out = response.getWriter();
out.print(jsonStr);
out.flush();
}else{
super.processTemplate(methodReturnStr,request,response); // 比如: "edit"
}
}
}
/*
}else{
throw new RuntimeException("operate值非法!");
}
*/
} catch (Exception e) {
e.printStackTrace();
throw new DispatcherServletException("DispatcherServlet出错了...");
}
}
}
// 常见错误: IllegalArgumentException: argument type mismatch