1.1 写一个登录拦截器普通类
//检验登录状态拦截器
//实现接口HandlerInterceptor 重写方法preHandle
public class LoginInterceptor implements HandlerInterceptor {
/*
* 该方法返回为true,用户已登录
* 该方法返回为false,用户未登录
* */
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//获取会话
HttpSession session = request.getSession(false);
if(session != null && session.getAttribute(AppVariable.USER_SESSION_KEY) != null) {
//用户已经登录
return true;
}
//未登录,则跳转到登录页面
response.sendRedirect("/login.html");
return false;
}
}
2.2 设置拦截规则
//设置拦截规则
// 1. 加注解@Configuration
// 2. 实现接口WebMvcConfigurer 重写方法addInterceptors
@Configuration
public class AppConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor()) //参数就是第一步的普通类
.addPathPatterns("/**") //先拦截全部的 再排除一些不需要拦截的
.excludePathPatterns("/css/**")
.excludePathPatterns("/editor.md/**")
.excludePathPatterns("/img/**")
.excludePathPatterns("/js/**")
.excludePathPatterns("/login.html")
.excludePathPatterns("/reg.html")
.excludePathPatterns("/blog_list.html")
.excludePathPatterns("/blog_content.html")
.excludePathPatterns("/art/detail")
.excludePathPatterns("/user/login")
.excludePathPatterns("/user/reg");
}
}
这种方式的缺点是只对时间数据类型为date的生效,对于java8的LocalDate,LocalDateTime是不生效的。
全局和局部都设置时,默认是优先局部。? 由于时间格式类型的原因,最好用如下局部这种注解,全局太局限。
?
//获取当前页面url中的参数的公共方法
function getUrlVal(key) {
var params = location.search;
if(params.length>1) {
params = location.search.substring(1);
var paramArr = params.split("&");
for(var i=0;i<paramArr.length;i++) {
var kv = paramArr[i].split("=");
if(kv[0]==key) {
return kv[1];
}
}
}
return "";
}
Java自带MD5码加密。
String password = "12345";
String md5password = DigestUtils.md5DigestAsHex(password.getBytes());
1.加密
用java自带的UUID生成一个随机数再拼接上用户的密码,就是最终的密码。
先是生成盐值,再拼接盐值和密码,将拼接后的整体用md5加密。最后将盐值拼接$符拼接md5加密后的密文形成最终存储在数据库中的密文。共65个字符。
2.验证
首先获取盐值,拿到数据库中的密文,进行截断。
盐值知道了。再和用户登录时输入的密码一起重复上面加密操作。最终也会得到一个65个字符的密文,两个进行比较。
3.代码
// 加盐算法
public class PasswordUtils {
// 1. 加盐并生成密码
public static String encrypt(String password) {
// 1.产生盐值 128位
String salt = UUID.randomUUID().toString().replace("-","");
// 2.拼接盐值和密码,再对这个整体使用md5加密,得到一个128位的密文
String saltPassword = DigestUtils.md5DigestAsHex((salt + password).getBytes());
// 3.最终密码格式 【128位的盐值+$+128位的密文】 并保存到数据库 共65个字符
String finalPassword = salt + "$" + saltPassword;
return finalPassword;
}
// 2.解密算法
// 解密还是根据用户的密码再次模拟生成加盐后的密文,再对比数据库中的密文,相同就说明正确
// 和上面写法一样,只是盐值固定了
public static String encrypt(String password,String salt) {
String saltPassword = DigestUtils.md5DigestAsHex((salt + password).getBytes());
String finalPassword = salt + "$" + saltPassword;
return finalPassword;
}
// 3.密码验证
public static boolean check(String password,String finalPassword) {
if(StringUtils.hasLength(password) && StringUtils.hasLength(finalPassword) && finalPassword.length()==65) {
//得到盐值
String salt = finalPassword.split("\\$")[0]; //特殊字符得转义
//重新模拟生成最终密码
String confirmPassword = PasswordUtils.encrypt(password, salt);
return confirmPassword.equals(finalPassword);
}
return false;
}
}
1.引入 Spring Security 框架?
有插件在插件中搜索,没插件去Maven仓库中搜索。
2.排除Spring Security框架自带的登录界面
3.使用
它的两个方法跟我手写的加盐算法的方法的思想都比较相似 encode()对应我的encrypt()方法,matches()对应我的check()方法。
共60个字符组成的加密密文
select * from articleinfo limit M offset N;??
select * from articleinfo limit M ,N;
以上两种分页是完全不同的。第一种涉及分页算法,分页常用第一种。
第一种(offset):
M : 每页显示条数
N :? 由算法得出? = (当前页面页数-1)* 每页显示条数(M)
举例:要求每页显示2条数
页数 | M | N? ? ?? | 算法 |
1? ? | 2 | 0? ? ? ? ? ? | (1-1)*2 |
2?? | 2 | 2? ? ? ? | (2-1)*2 |
3 | 2 | 4 | (3-1)*2 |
select * from articleinfo limit 2 offset 0; 表示每页显示2条数据,且当前在第一页
?举例:要求每页显示3条数
页数 | M | N? ? ?? | 算法 |
1? ? | 3 | 0? ? ? ? ? ? | (1-1)*3 |
2?? | 3 | 3? ? ?? | (2-1)*3 |
3 | 3 | 6 | (3-1)*3 |
第二种(逗号):
select * from articleinfo limit M ,N;
M : 表示当前从M号位置开始查找,且M号不算,是从M+1号开始的。
N : 总共查N条。?
即查找的范围就是 [M+1,M+1+N] 闭区间。
以返回博客列表集合为例:
success: function (result) {
if(result!=null && result.code==200 && result.data.length>0) {
var blogs = "";
for (var i = 0; i < result.data.length; i++) {
blogs += '<div class="blog">';
blogs += '<div class="title">'+result.data[i].title+'</div>';
blogs += '<div className="date">'+result.data[i].createtime+'</div>';
blogs += '<div class="desc">'+result.data[i].content+'</div>';
blogs += '<a href="blog_content.html?id='+result.data[i].id+'" class="detail">查看全文 >></a>';
blogs += '</div>';
}
Query('#articleList').html(blogs);
}
验证码插件Hutool?文档->Hutool参考文档。