博客系统(二)
- 博客系统
- 获取当前用户的信息
- 对密服务器托管网码进行加密和解密的操作
- 设置统一的数据返回格式
- 设置未登录拦截
- 设置线程池
博客系统
博客系统是干什么的?
CSDN就是一个典型的博客系统。而我在这里就是通过模拟实现一个博客系统,这是一个较为简单的博客系统,但是主要功能一个不缺,不过就是 UI 有些 low,我学习前端是为了写后端更加顺手。不至于前后端完全分离,但是有个问题设计的 web 页面不是很好看。
首先我将整体的业务流程展现
我们继博客系统(一)继续,编写
获取当前用户的信息
根据项目结构图可以知道,我们无论是登录还是查询必须要获取当前的用户的信息。
根据session的特点,他会自己生成一个cooker值,我们这里只需要获取信息,但是session是一个 key:value 结构的值,所以还需要的一个公共的,全局变量 ,key值。用来保存和查找对应的value值
/**
* 全局变量
*/
public class Variable {
public static final String SESSION_USERINFO_KEY="SESSION_USERINFO";
}
接下来我们就可以根据key去寻找当前的用户信息了。
/**
* 得到当前的用户信息
*/
public class SessionUtis {
public static Userinfo getUser(HttpServletRequest request){
HttpSession httpSession=request.getSession(false);
if (httpSession!=null&&httpSession.getAttribute(Variable.SESSION_USERINFO_KEY)!=httpSession){
return (Userinfo) httpSession.getAttribute(Variable.SESSION_USERINFO_KEY);
}
return null;
}
}
对密码进行加密和解密的操作
首先 UUID 这个类是可以生产出世界上唯一的值(目前是),市面上的加密工具,有很多,我们用 MD5(C级)的就够了,毕竟是个小网站。
我规定:
- 最终密码生成为65位字符
- UUID生成的唯一值与用户所注册的密码合并通过加密工具进行加密。得到一个唯一的值
- 将这个唯一的值与UUID数生成的唯一的值合并。二者通过 @ 分隔
- 因为在MD5只能正向加密不能反向解密,所以我们要将唯一的UUID进行保存,从而在解密以及验证密码正确性上有操作空间
- java基本库里为我们提供了UUID生成类,要搭配方法 randomUUID 使用,且生成的uuid有一些特殊字符,需要我们手动去除,此时得到的是一个32位的唯一字符串
- java基本库里为我们提供了MD5的加密工具类,DigestUtils,搭配md5DigestAsHex()使用,但是参数是一个二进制数组所以,需要getBytes转换。
/**
* 对密码进行加密,解密
*/
public class PasswordUtils {
/**
* 加密
*/
public String encryption(String password){
//uuid生成为唯一值
String salt= UUID.randomUUID().toString().replace("-","");
//将uuid和password经过MD5加密得到密码
String finalPassword=
DigestUtils.md5DigestAsHex((salt+password).getBytes(StandardCharsets.UTF_8));
return salt+"@"+finalPassword;
}
/**
* 解密,并验证密码正确
*/
public static boolean decrypt(String password,String dbPassword){
if (!StringUtils.hasLength(password)||!StringUtils.hasLength(dbPassword)||dbPassword.length()!=65){
return false;
}
String [] dbPasswordArray=dbPassword.split("@");
if (dbPasswordArray.length!=2){
return false;
}
//获取唯一的uuid
String salt=dbPasswordArray[0];
//获取生成的md5的密码
String finalDBpassword=dbPasswordArray[1];
//通过同样的uuid 和 密码生成出来的值是唯一的。
String finalPassword=DigestUtils.md5DigestAsHex((salt+password).getBytes(StandardCharsets.UTF_8));
if (finalDBpassword.equals(finalPassword)){
return false;
}
return true;
}
设置统一的数据返回格式
设置这个的目的很简单,在开发的时候有很多人,一起开发,使得数据格式会不一样,我们在这里做一个保底策略。
这里我们需要添加一个拦截,将返回出去的数据进行统一的格式规划,这里我用常见的j son 格式
-
ResponseBodyAdvice 接口允许在执行 @ResponseBody 或 ResponseEntity 控制器方法之后,但在使用HttpMessageConverter 写入响应体之前自定义响应,进行功能增强。通常用于 加密,签名,统一数据格式等。
-
instanceof 是Java中的二元运算符,左边是对象,右边是类;当对象是右边类或子类所创建对象时,返回true;否则,返回false。
-
类的实例包含本身的实例,以及所有直接或间接子类的实例
-
instanceof左边显式声明的类型与右边操作元必须是同种类或存在继承关系,也就是说需要位于同一个继承树,否则会编译错误
-
注意,这里返回的 object 类,但是对于ResponseBodyAdvice 来说,是没有String类型的说法所以需要自己去判断,不然就会报错
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
//格式生成唯一json格式
@Resource
private ObjectMapper objectMapper;
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType,
MediaType selectedContentType,
Class selectedConverterType,
服务器托管网 ServerHttpRequest request, ServerHttpResponse response) {
//格式符合要求,就不用转换格式直接返回
if (body instanceof ResultAjax){
return body;
}
//格式为String类型,属于特殊类,需要我们手动调换
if (body instanceof String){
ResultAjax resultAjax=ResultAjax.success(body);
try {
//将格式转换层json格式,然后返回
return objectMapper.writeValueAsString(resultAjax);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
return ResultAjax.success(body);
}
}
这里有不明白的可以去看我的博客—–Spring AOP (拦截器)
设置未登录拦截
上述一样不知道原理的可以去看我的 博客 Spring AOP (拦截器)
HandlerInterceptor 和 WebMvcConfigurer搭配使用,前者设置规则,设置拦截的网页
/**
* 设置登录拦截规则
*/
public class LoginIntercept implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession httpSession=request.getSession(false);
if (httpSession!=null&&httpSession.getAttribute(Variable.SESSION_USERINFO_KEY)!=null){
return true;
}
response.sendRedirect("/login.html");
return false;
}
}
/**
* 拦截的网页和资源
*/
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginIntercept())
.addPathPatterns("/**")
.excludePathPatterns("/css/*");
}
}
设置线程池
这里用的线程池是Spring下的,不用像java本库中的线程池,填入参数,只需要调用set方法写入(不知道线程池可以看我的多线程文章)
@Configuration
public class ThreadPoolUltisConfig {
public ThreadPoolTaskExecutor taskExecutor(){
ThreadPoolTaskExecutor executor=new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(10000);
executor.setThreadNamePrefix("MyThread-");
executor.initialize();
return executor;
}
}
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
相关推荐: LeetCode155:最小栈,最简单的中等难度题,时间击败100%,内存也低于官方
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 最近运气不错,在LeetCode上白捡一道送分题,官方设定的难度是中等,然而此题难度放在简单的题库中都是…