SpringBoot开发十一-显示登录信息
需求介绍—显示登录信息
我们需要在每个页面的头部都要把登录用户的头像显示出来,另外在详细信息里面你需要显示用户的名字,除此之外如果登录了,我们显示首页 信息 头像 三个功能的链接,否则显示首页 登录两个功能点,也就是根据登录与否显示头部的内容。
我们每个静态页面都有这个内容,都需要显示登录信息,那么开发这个功能你需要每个请求都需要实现这个工能。我们想要低耦合的解决这个功能,就利用 Spring 的拦截器,它可以拦截访问服务器的请求,拦截请求之后可以在拦截这个请求之后的开始或者结束的部分插入一些代码,从而解决一些请求共有点的一些功能实现。
代码实现
使用拦截器的方法:
先写一个类实现 HandlerInterceptor 接口,然后配置拦截器的处理范围,拦截哪些请求,不拦截哪些请求。写个实例,先写类 AlphaInterceptor 实现 HandlerInterceptor 接口:
package com.nowcoder.community.controller.interceptor; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; @Component// 把拦截器交给容器管理
public class AlphaInterceptor implements HandlerInterceptor { private static final Logger logger = LoggerFactory.getLogger(AlphaInterceptor.class); // 在Controller之前执行
// Object是拦截的方法
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
logger.debug("preHandle: "+ handler.toString());
return true;
} // 在调用完Controller之后执行,模板之前执行
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
logger.debug("postHandle:" + handler.toString());
} // 在TemplateEngine之后执行
// 异常是在调用Controller或者模板过程中出现了异常就会赋值给这个ex参数
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
logger.debug("afterCompletion: " + handler.toString());
}
}
我们写好了之后要写一个配置类 WebMvcConfig:
一般配置类都是引入第三方的 Bean,但是拦截器需要实现 WebMvcConfigurer 接口。
package com.nowcoder.community.config; import com.nowcoder.community.controller.interceptor.AlphaInterceptor;
import com.nowcoder.community.controller.interceptor.LoginRequiredInterceptor;
import com.nowcoder.community.controller.interceptor.LoginTicketInterceptor;
import com.nowcoder.community.controller.interceptor.MessageInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private AlphaInterceptor alphaInterceptor;
// .excludePathPatterns 表示哪些路径不被拦截比方说一些静态资源,
// .addPathPatterns 表示确定的拦截的路径
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(alphaInterceptor)
.excludePathPatterns("/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg")
.addPathPatterns("/register", "/login");
}
知道拦截器怎么用了,我们就正式来写一下,根据我们的需求,
我们需要在请求开始时查询登录用户,然后在本次请求中持有用户数据(就是存到内存里),然后在模板视图上引用,最后在请求结束时清理用户数据。

第一步我们知道 Cookie 是从 HttpServletRequest 对象里面取出来的,因为很多情况下都需要获获取 Cookie,所以写一个工具帮我们实现一下 CookieUtil:
package com.nowcoder.community.util; import org.springframework.web.bind.annotation.CookieValue; import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest; public class CookieUtil { public static String getValue(HttpServletRequest httpServletRequest, String name) {
if (httpServletRequest == null || name == null) {
throw new IllegalArgumentException("参数为空!");
} Cookie[] cookies = httpServletRequest.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals(name)) {
return cookie.getValue();
}
}
}
return null;
}
}
其次我们说了我们通过 Ticket 查询到的用户,我们需要把它存下来,但是由于服务器对应客户端是一对多的,它是一个处理多线程的,每个线程隔离的存这个对象,那么我们写个工具 HostHolder 存 User 对象,起到一个容器的作用:
package com.nowcoder.community.util; import com.nowcoder.community.entity.User;
import org.springframework.stereotype.Component; /**
* 持有用户信息,用于代替session对象
*/
@Component
public class HostHolder {
private ThreadLocal<User> users = new ThreadLocal<>(); public void setUser(User user) {
users.set(user);
} public User getUser() {
return users.get();
} public void clear() {
users.remove();
}
}
然后写个拦截器 LoginTicketInterceptor:
package com.nowcoder.community.controller.interceptor; import com.nowcoder.community.entity.LoginTicket;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.service.UserService;
import com.nowcoder.community.util.CookieUtil;
import com.nowcoder.community.util.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.Authenticator;
import java.util.Date; @Component
public class LoginTicketInterceptor implements HandlerInterceptor { @Autowired
private UserService userService; @Autowired
private HostHolder hostHolder; @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 从Cookie中获取凭证
String ticket = CookieUtil.getValue(request, "ticket");
if (ticket != null) {
// 查询凭证
LoginTicket loginTicket = userService.findLoginTicket(ticket);
// 检查凭证是否有效
if (loginTicket != null && loginTicket.getStatus() == 0 && loginTicket.getExpired().after(new Date())) {
// 根据凭证查用户
User user = userService.findUserById(loginTicket.getUserId());
// 在本次请求中持有用户,多线程,利用ThreadLocal
hostHolder.setUser(user);
}
}
return true;
}
// 在模板引擎调用之前把这个User存放到modelAndView里面
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
User user = hostHolder.getUser();
if (user != null && modelAndView != null) {
modelAndView.addObject("loginUser", user);
}
} @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
hostHolder.clear();
SecurityContextHolder.clearContext();
}
}
写好拦截器就要注入到 WebMvcConfig:
package com.nowcoder.community.config; import com.nowcoder.community.controller.interceptor.AlphaInterceptor;
import com.nowcoder.community.controller.interceptor.LoginRequiredInterceptor;
import com.nowcoder.community.controller.interceptor.LoginTicketInterceptor;
import com.nowcoder.community.controller.interceptor.MessageInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private AlphaInterceptor alphaInterceptor; @Autowired
private LoginTicketInterceptor loginTicketInterceptor; @Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(alphaInterceptor)
.excludePathPatterns("/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg")
.addPathPatterns("/register", "/login"); registry.addInterceptor(loginTicketInterceptor)
.excludePathPatterns("/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg");
}
然后就是处理页面了。
SpringBoot开发十一-显示登录信息的更多相关文章
- World Wind Java开发之三 显示状态栏信息
先来看下本篇博客索要达到的效果: 找到源代码下的gov.nasa.worldwind.util下的StatusBar.java文件,能够看到状态栏显示的信息主要包含视点高度以及相应空间点三维坐标以及是 ...
- World Wind Java开发之三 显示状态栏信息(转)
http://blog.csdn.net/giser_whu/article/details/40920315 先来看下本篇博客索要达到的效果: 找到源码下的gov.nasa.worldwind.ut ...
- SpringBoot开发十三-检查登录状态
需求介绍-检查登录状态 防止用户知道我们的一些功能的链接,直接就进到了该页面,就像有些功能是管理员访问才能进的,就需要进行登录状态的判断. 我们知道这个功能点很多其他的功能点都需要使用,所以我们需要使 ...
- Centos启动时停止在登录界面但不显示登录信息(一直在转圈)
进入单用户模式 执行 iscsiadm -m node -o delete,然后reboot
- SpringBoot Web开发(5) 开发页面国际化+登录拦截
SpringBoot Web开发(5) 开发页面国际化+登录拦截 一.页面国际化 页面国际化目的:根据浏览器语言设置的信息对页面信息进行切换,或者用户点击链接自行对页面语言信息进行切换. **效果演示 ...
- [springboot 开发单体web shop] 5. 用户登录及首页展示
用户登录及前端展示 用户登录 在之前的文章中我们实现了用户注册和验证功能,接下来我们继续实现它的登录,以及登录成功之后要在页面上显示的信息. 接下来,我们来编写代码. 实现service 在com.l ...
- DedeCMS中实现在顶层banner中显示自定义登录信息
一.需求描述 dedeCMS自带的模板中有互动中心模块,如下图所示: 由于会员登陆对我来说不是网站的重要模块且默认DedeCMS的会员中心模块的初始化很慢,常会显示“正在载入中,请稍候...”, 所以 ...
- Linux显示登录Shell信息
Linux显示登录Shell信息 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ finger -p Login Name Tty Idle Login Tim ...
- SpringBoot 使用 RestTemplate 调用exchange方法 显示错误信息
SpringBoot使用RestTempate SpringBoot使用RestTemplate摘要认证 SpringBoot使用RestTemplate基础认证 SpringBoot使用RestTe ...
随机推荐
- 分布式唯一ID生成方案选型!详细解析雪花算法Snowflake
分布式唯一ID 使用RocketMQ时,需要使用到分布式唯一ID 消息可能会发生重复,所以要在消费端做幂等性,为了达到业务的幂等性,生产者必须要有一个唯一ID, 需要满足以下条件: 同一业务场景要全局 ...
- Java程序设计(2021春)——第一章续笔记与思考
Java程序设计(2021春)--第一章续笔记与思考 目录 Java程序设计(2021春)--第一章续笔记与思考 Java数据类型 基本数据类型 引用类型 基本数据类型--整数类型的细节 基本数据类型 ...
- Linux:linux网路路由命令
查看路由 #查看所有路由信息 route -n 删除路由 #删除路由 route del default 修改路由 #修改路由 #先删除路由 route del default #在新建 route ...
- XCTF(MISC) 图片隐写
题目描述:菜猫给了菜狗一张图,说图下面什么都没有 1.给了个pdf,打开是这玩意 2.盲猜flag是图片后面,右键直接删除图片试试. 答案出来了.
- wumei-smart智能家居开原项目
一.项目简介 物美智能(wumei-smart)]是一套开源的软硬件系统,可用于二次开发和学习,快速搭建自己的智能家居系统. 硬件工程师可以把自己的设备集成到系统:软件工程师可以使用项目中的设备熟悉软 ...
- 谷粒商城--分布式基础篇(P1~P27)
谷粒商城--分布式基础篇P1~P27 去年3月份谷粒商城分布式基础.进阶.高级刚出的时候就开始学了,但是中途因为一些事就中断了,结果一直到现在才有时间重新开始学,看到现在网上这么多人都学完了,确实感觉 ...
- 抓包工具-Charles
1.简介Charles Charles其实是一款代理服务器,通过成为电脑或者浏览器的代理,然后截取请求和请求结果达到分析抓包的目的.charles有Window版本和Mac OS版本,也同时支持ios ...
- Linux常用命令 day day up系列2
一.alias--设置别名二.du--统计目录及文件空间占用情况三.mkdir--创建新目录四.touch--创建空文件五.ln--创建链接文件1.链接文件类型六.cp--复制文件或目录七.rm--删 ...
- .h .cpp区别
首先,我们可以将所有东西都放在一个.cpp文件内. 然后编译器就将这个.cpp编译成.obj,obj是什么东西? 就是编译单元了.一个程序,可以由一个编译单元组成, 也可以有多个编译单元组成. 如果你 ...
- PyCharm代码区不能编辑的解决办法
问题: 修改之前的Python代码时发现代码区无法编辑,无意中输入i后又可以编辑了. 解决: 原因是打开了工具中的vim Emulator编辑模式,把vim Emulator前面的勾取消即可.