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 ...
随机推荐
- SpringBoot缓存管理(二) 整合Redis缓存实现
SpringBoot支持的缓存组件 在SpringBoot中,数据的缓存管理存储依赖于Spring框架中cache相关的org.springframework.cache.Cache和org.spri ...
- Jmeter之cokie管理器和http默认值
根据上文中,都配置好以后就可以开始启动了,点击启动,线程组里面就会开始记录你的网页请求.这里使用CNode网站做测试.我分别记录进行了"登入","话题创建",& ...
- 使用Hugo框架搭建博客的过程 - 部署
前言 完成前期的准备工作后,在部署阶段需要配置服务器或对象存储服务. 对象存储和服务器对比 对象存储平台 国内有阿里云OSS.腾讯COS.又拍云.七牛云等.国外有Github Pages.Netlif ...
- 矩阵按对角线打印---python
将一个矩阵(二维数组)按对角线向右进行打印.(搜了一下发现好像是美团某次面试要求半小时手撕的题)Example:Input:[[1,2,3,4],[5,1,2,3],[9,5,1,2]]Output: ...
- 你觉得我的这段Java代码还有优化的空间吗?
上周,因为要测试一个方法的在并发场景下的结果是不是符合预期,我写了一段单元测试的代码.写完之后截了个图发了一个朋友圈,很多人表示短短的几行代码,涉及到好几个知识点. 还有人给出了一些优化的建议.那么, ...
- python twain 扫描
def multiScan(self): """ Scan and return an array of PIL objects If no images, will r ...
- 第 3 题:如何理解 HTML5 语义化?
什么是标签语义化? 提升代码可读性,便于团队开发和维护 为什么要标签语义化? 当网页去掉 CSS 样式时,页面能呈现出来清晰的结构 案例 不存在语义化 <div></div> ...
- sqliab刷题笔记-联合注入
Less-1 测试是字符型还是数字型 判断所在字段数 查看显示值 可以看出显示2,3位置.因此我们选择2的位置进行联合注入 查看表名 我们要对admin,users等字符敏感 查看admin表中的字段 ...
- CF1032G Chattering
CF1032G Chattering 题意 思路 对于每一个位置,它转移的范围是确定的. 对于一段可以走到的区间,我们可以求出区间中所有点再能走到区间范围. 于是这个就可以倍增进行转移. 如何快速求出 ...
- 基于小熊派Hi3861鸿蒙开发的IoT物联网学习【四】
一.互斥锁基本概念: 1.互斥锁又称互斥型信号量,是一种特殊的二值性信号量[二值型信号量可以理解为任务与中断间或者两个任务间的标志,该标志非"满"即"空"],用 ...