day23_密码加密 前端验证码 监听器 svn版本控制
day23_密码加密 前端验证码 监听器 svn版本控制
1密码加密
注意点:
1数据库保存密文
2用户输入明文 用同样的加密算法进行加密
3在程序中直接判断密文是否相同
package com.javasm.utils;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/*** @className: CommonUtils* @author: gfs* @date: 2025/10/31 9:38* @version: 0.1* @since: jdk17* @description:*/
public class CommonUtils {
//传入明文 转出密文public static String transPWD(String pwd){String transPWD ="";try {MessageDigest md5 = MessageDigest.getInstance("MD5");md5.update(pwd.getBytes());transPWD = new BigInteger(1, md5.digest()).toString(16);} catch (NoSuchAlgorithmException e) {throw new RuntimeException(e);}return transPWD;
}
}
对比密码时 转成密文对比

密码加密知识点

注意:
在公开免费的算法下 可以通过加盐值(自定义逻辑改变密码字符串) 进一步提高安全性
2前端验证码
为什么要验证码 可以防止一些脚本自动点击登录
如果要求更高 需要使用 邮箱 或者手机校验
前台系统会使用(给普通用户使用)
后台系统使用较少(后台系统经常不上外网)
拖动验证码组件: vue3-puzzle-vcode
https://www.npmjs.com/package/vue3-puzzle-vcode
<script setup>
import { ref,reactive } from 'vue'
import axios from 'axios'
import qs from 'qs';
import { ElMessage } from 'element-plus'
import router from '@/router';
import Vcode from "vue3-puzzle-vcode";
const isShow = ref(false);
// const onShow = () => {
// isShow.value = true;
// };
const onClose = () => {isShow.value = false;};//后端校验用户名密码环节 挪到验证码拖动成功之后const onSuccess = () => {//验证码验证成功console.log("向后端发请求 传用户数据", user)console.log("向后端发请求 传用户数据", qs.stringify(user))axios.post("http://localhost:8080/baseProj/login",qs.stringify(user)).then(resp=>{console.log("请求成功",resp.data)if(resp.data.code == 10001){ElMessage.error(resp.data.msg)}else if(resp.data.code == 10002){ElMessage.info(resp.data.msg)}else if(resp.data.code == 10000){ElMessage.success(resp.data.msg)//登录用户信息加入缓存 方便其他页面使用sessionStorage.setItem("loginUser",JSON.stringify(resp.data.returnData))//跳转到主页面router.push('/main')}})
onClose(); // 验证成功,手动关闭模态框};
const rules = reactive({username: [{ required: true, message: '请输入用户名', trigger: 'blur' },],password: [{ required: true, message: '请输入密码', trigger: 'blur' },{ min: 4, max: 8, message: '长度4-8位之间', trigger: 'blur' },],
})
const user = reactive({username: '',password: '',
})
const mySubmit = ()=>{// 通过form对象上预设的validate方法,对表单数据进行验证loginForm.value.validate((valid)=>{console.log(valid);//如果验证成功 提交请求if(valid){//验证码开框isShow.value = true;}})
}
//一键重置
const myReset = ()=>{loginForm.value.resetFields()
}
//通过相同的名称 和空ref函数 获取指定ref名称的组件对象
const loginForm = ref()
console.log(loginForm);
</script>
<template><div class="loginPanel"><img src="/src/assets/login.png"/><el-form style="margin-top: 20px;" ref="loginForm" :model="user" hide-required-asterisk :rules="rules" label-width="80px" ><el-form-item label="用户名" prop="username"><el-input style="width: 240px;" v-model="user.username" /></el-form-item><el-form-item label="密码" prop="password"><el-input type="password" style="width: 240px;" v-model="user.password" /></el-form-item>
<el-form-item><el-button type="primary" color="#626aef" @click="mySubmit">登录</el-button><el-button color="#626aef" @click="myReset">重置</el-button></el-form-item></el-form>
</div><!-- <hr> 增加验证码的弹出框 --><Vcode :show="isShow" @success="onSuccess" @close="onClose"/><!-- <button @click="onShow">开始验证</button> -->
<video class="videoBG" autoplay loop muted playsinline><source src="/src/assets/tongyi_branding.mp4" type="video/mp4">Your browser does not support the video tag.</video>
</template>
<style scoped>.loginPanel{width: 365px;height: 300px;border: 1px solid lightgrey;padding: 30px;margin: 200px auto;background-color: rgba(206, 206, 206, 0.486);border-radius: 5px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);}
.videoBG {position: fixed;right: 0;bottom: 0;min-width: 100%;min-height: 100%;width: 200%;height: auto;z-index: -1;
}
</style>
3监听器(了解)
JAVAEE
servlet 接收请求 返回响应 处理报文
filter 接收请求 返回响应 处理报文 同样地址请求先进filter (进入请求前 做公共代码处理)
listener 监听器 类似钩子函数 指定对象创建/销毁时会自动触发
request ServletRequestListener
session HttpSessionListener
servletContext ServletContextListener
在服务器启动时 加载mybatis对象 生成数据库连接池
package com.javasm.listener;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import java.io.IOException;
import java.io.InputStream;
/*** @className: ListenerDemo* @author: gfs* @date: 2025/10/31 10:42* @version: 0.1* @since: jdk17* @description:*/
//各种框架中 都会使用监听器
//伴随服务器启动 加载资源 创建对象
@WebListener
public class ListenerDemo implements ServletContextListener {
static SqlSessionFactory sqlSessionFactory = null;
@Overridepublic void contextInitialized(ServletContextEvent sce) {String resource = "mybatis-config.xml";InputStream inputStream = null;try {inputStream = Resources.getResourceAsStream(resource);sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);} catch (IOException e) {throw new RuntimeException(e);}}
@Overridepublic void contextDestroyed(ServletContextEvent sce) {
}
//获得连接public static SqlSession getSqlSession(){SqlSession sqlSession = sqlSessionFactory.openSession();return sqlSession;}//归还连接public static void backSqlSession(SqlSession sqlSession){//归还连接sqlSession.close();
}
//归还并提交public static void backAndCommitSqlSession(SqlSession sqlSession){sqlSession.commit();//归还连接sqlSession.close();}
}
//public class ListenerDemo implements HttpSessionListener {
//
// @Override
// public void sessionCreated(HttpSessionEvent se) {
// HttpSessionListener.super.sessionCreated(se);
// }
//
// @Override
// public void sessionDestroyed(HttpSessionEvent se) {
// HttpSessionListener.super.sessionDestroyed(se);
// }
//}
//public class ListenerDemo implements ServletRequestListener {
//
// @Override
// public void requestInitialized(ServletRequestEvent sre) {
// //对象创建了
// }
//
// @Override
// public void requestDestroyed(ServletRequestEvent sre) {
// //对象销毁了
// }
//
//
//}
这个改造 理解即可 不需要在当前项目使用
4svn版本控制工具

1辅助团队开发 做代码合并
2通过正常提交 更新 保持代码一致
3在提交时 需要检测版本号 如果本地版本比服务器新 可以提交
否则需要手工合并
4.1使用idea中的版本控制插件
检查是否有svn.exe 如果没有 重装svn客户端


检查目录:

如果有 在idea中配置 svn命令提示行 svn.exe

4.2在svn服务器上 上传基础版本

4.3从服务器checkout代码

选择使用subversion 添加中心仓库地址

checkout 检出代码

4.4 梳理项目目录结构


把 .idea目录 和 target目录 加入忽略列表 之后 提交目录变更

提交时 注意填写提交日志

4.5正常的提交和更新


注意:
svn中 文件和目录不同的颜色
白色 与服务器一致
红色 未标记文件 需要加入版本控制 addVCS
加入忽略列表 ignored
绿色 新增的文件
蓝色 已有文件的修改(文件 和 目录都需要提交)
如果删除文件 要记得提交

更新操作

如果没有及时本地更新 点从本地重新加载

4.6代码冲突
同时修改一个版本 后提交的会提交失败

如果提交失败 点更新

更新并重新加载文件

融合代码

如果不知道该怎么改代码 找写这个代码的人商量



商量完怎么修改
三份代码都会列出来
点击确定

可以正常提交
附加说明:
1一天至少合一次 早上或者晚上
2测试通过的代码再提交
3尽量减少冲突 公共代码专人负责
4不要随意改包名类名
