需求介绍—显示登录信息

  我们需要在每个页面的头部都要把登录用户的头像显示出来,另外在详细信息里面你需要显示用户的名字,除此之外如果登录了,我们显示首页 信息 头像 三个功能的链接,否则显示首页 登录两个功能点,也就是根据登录与否显示头部的内容。

  我们每个静态页面都有这个内容,都需要显示登录信息,那么开发这个功能你需要每个请求都需要实现这个工能。我们想要低耦合的解决这个功能,就利用 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开发十一-显示登录信息的更多相关文章

  1. World Wind Java开发之三 显示状态栏信息

    先来看下本篇博客索要达到的效果: 找到源代码下的gov.nasa.worldwind.util下的StatusBar.java文件,能够看到状态栏显示的信息主要包含视点高度以及相应空间点三维坐标以及是 ...

  2. World Wind Java开发之三 显示状态栏信息(转)

    http://blog.csdn.net/giser_whu/article/details/40920315 先来看下本篇博客索要达到的效果: 找到源码下的gov.nasa.worldwind.ut ...

  3. SpringBoot开发十三-检查登录状态

    需求介绍-检查登录状态 防止用户知道我们的一些功能的链接,直接就进到了该页面,就像有些功能是管理员访问才能进的,就需要进行登录状态的判断. 我们知道这个功能点很多其他的功能点都需要使用,所以我们需要使 ...

  4. Centos启动时停止在登录界面但不显示登录信息(一直在转圈)

    进入单用户模式  执行 iscsiadm -m node -o delete,然后reboot

  5. SpringBoot Web开发(5) 开发页面国际化+登录拦截

    SpringBoot Web开发(5) 开发页面国际化+登录拦截 一.页面国际化 页面国际化目的:根据浏览器语言设置的信息对页面信息进行切换,或者用户点击链接自行对页面语言信息进行切换. **效果演示 ...

  6. [springboot 开发单体web shop] 5. 用户登录及首页展示

    用户登录及前端展示 用户登录 在之前的文章中我们实现了用户注册和验证功能,接下来我们继续实现它的登录,以及登录成功之后要在页面上显示的信息. 接下来,我们来编写代码. 实现service 在com.l ...

  7. DedeCMS中实现在顶层banner中显示自定义登录信息

    一.需求描述 dedeCMS自带的模板中有互动中心模块,如下图所示: 由于会员登陆对我来说不是网站的重要模块且默认DedeCMS的会员中心模块的初始化很慢,常会显示“正在载入中,请稍候...”, 所以 ...

  8. Linux显示登录Shell信息

    Linux显示登录Shell信息 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ finger -p Login Name Tty Idle Login Tim ...

  9. SpringBoot 使用 RestTemplate 调用exchange方法 显示错误信息

    SpringBoot使用RestTempate SpringBoot使用RestTemplate摘要认证 SpringBoot使用RestTemplate基础认证 SpringBoot使用RestTe ...

随机推荐

  1. 【转载】CentOS-yum安装Docker环境

    安装Docker环境 $ yum install docker -y 启动Docker $ systemctl start docker 设置自启动 $ systemctl enable docker ...

  2. NoSql非关系型数据库之MongoDB应用(三):MongoDB在项目中的初步应用

    业精于勤,荒于嬉:行成于思,毁于随. 我们可以结合相关的IDE做一个简单的增删改查了,实现MongoDB在项目中的初步应用. 前提是安装了MongoDB服务和MongoDB可视化工具,没有安装的可以点 ...

  3. buu crypto 变异凯撒

    一.由题目就可知是凯撒加密,但是是变异,说明有改动,但是凯撒的本质移位是不变的,将密文afZ_r9VYfScOeO_UL^RWUc,和flag进行比较,字符表查一下,发现 a:97 f:102 f:1 ...

  4. Jmeter常见报错信息: ERROR - jmeter.protocol.http.proxy.ProxyControl: Could not initialise key store java.io.IOException: Cannot run program "keytool"

    JMeter 2.10 用的新方法来录制HTTPS请求Java 7. 录制的过程中会碰到一些问题或者报错,就目前碰到的,做出一些总结. ERROR - jmeter.protocol.http.pro ...

  5. PYTHON 读取ADB记录文件输入ACTIVITY

    import re lb=[] with open("daaa.txt",encoding="utf8") as f: data = f.readlines() ...

  6. web系统国际化思路

    需求:php开发多个中文系统支持国际化 思路: 提炼各个系统中的中文字符,替换为资源key. 多媒体文件中的中文定位(图片中的中文,中文录音,中文视频,中文模板等). 统一翻译文字.准备资源文件. 各 ...

  7. MongoDB 基础学习

    1.MongoDB 概念解析 SQL术语/概念 MongoDB术语/概念 解释/说明 database database 数据库 table collection 数据库表/集合 row docume ...

  8. Spark—初识spark

    Spark--初识spark 一.Spark背景 1)MapReduce局限性 <1>仅支持Map和Reduce两种操作,提供给用户的只有这两种操作 <2>处理效率低效 Map ...

  9. Java成长之路--一个非科班生的进阶之路

    前言 笔者从事Java开发六年有余,从什么都不懂的小白一路成长到上市公司管理20人的技术leader.管理的团队,虽然人数不算多,但也是对于我这个非科班生这么多年努力的一种肯定.在技术的道路上,我没有 ...

  10. 微信小程序云开发-数据库-用户更新数据并提交

    一.wxml增加input输入框和[更新商品价格]按钮 在商品详情页新增[更新商品价格]按钮,wxml新增部分代码,input绑定事件,用于获取用户输入的内容.按钮绑定事件,用于更新商品价格.  二. ...