springboot官方文档
本项目地址
项目目录
│ pom.xml
└─src
└─main
├─java
│ └─com
│ └─base
│ │ Application.java # 启动类
│ │
│ ├─config
│ │ │ WebMvcConfig.java mvc配置类,配置拦截器和资源策略
│ │ │
│ │ ├─filter # 过滤器
│ │ │ MainFilter.java
│ │ │
│ │ ├─Interceptor # 拦截器
│ │ │ Intercept.java
│ │ │ OtherIntercept.java
│ │ │
│ │ └─listener # 监听器
│ │ Listener.java
│ │
│ └─controller # 测试Controller
│ IndexController.java
│
└─resources
application.yml # springboot配置
Application.java 启动类代码
package com.base;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
/**
* 开发公司:个人
* 版权:个人
* <p>
* Application
* @SpringBootApplication(scanBasePackages = {"com.base"}) scanBasePackages 扫描基础类包
* @ServletComponentScan(basePackages = {"com.base"}) 扫描服务程序组件 (@WebServlet、@WebFilter、@WebListener等注解注解)
* 启用@ServletComponentScan 注解后 Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册,无需其他代码。
* @author 刘志强
* @created Create Time: 2019/5/23
*/
@SpringBootApplication(scanBasePackages = {"com.base"})
@ServletComponentScan(basePackages = {"com.base"})
public class Application implements CommandLineRunner {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... strings) throws Exception {
logger.info("程序启动");
}
}
用@ServletComponentScan注解后,Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册,无需其他代码。
拦截器
拦截器应用场景
1. 用拦截器控制单点登录
前后端不分离,使用session:
登录
登录时将用户信息存储至session中。
session.setAttribute("usserId",user.getId());
然后在将userId和sessionId 进行绑定存储至redis(也可以使用别的全局唯一数据源来存储,如静态Map,或别的缓存中间件)
redisTemplate.opsForValue().set(user.getId(),session.getId());
拦截器判断是否在别处登录
拦截器从session中取出userId
Long userId = (Long)session.getAttribute("usserId");
=》 能取到表示已登录。取不到表示未登录或session过期已下线
然后在根据userId从redis中取出sessionId 根据redis中的sessionId
和当前登录sessionId进行比较
String sessionId = (String) redisTemplate.opsForValue().get(userId);
if (sessionId === session.getId())
=》 如果一致表示没有在别处登录,如果不一致表示用户已在别处登录(因为如果有另一人在别处登录相同userId的redis会覆盖掉)
前后端分离:
登录
登录时将用户信息存储至redis中。
redisTemplate.opsForValue().set(token,user.getId());
然后在将userId和token 进行绑定存储至redis(也可以使用别的全局唯一数据源来存储,如静态Map,或别的缓存中间件)
redisTemplate.opsForValue().set(user.getId(),token);
拦截器判断是否在别处登录
拦截器从redis中根据token取出userId
Long userId = (Long)redisTemplate.opsForValue().get(token);
=》 能取到表示已登录。取不到表示未登录或token过期已下线
然后在根据userId从redis中取出token 根据redis中的token
和当前登录token进行比较
String redisToken = (String) redisTemplate.opsForValue().get(userId);
if (redisToken === token)
=》 如果一致表示没有在别处登录,如果不一致表示用户已在别处登录(因为如果有另一人在别处登录相同userId的redis会覆盖掉)
Intercept.java
package com.base.config.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 Intercept implements HandlerInterceptor {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
logger.info("Controller方法调用前,被调用");
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
logger.info("请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
logger.info("在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)");
}
}
@Component 创建实例
WebMvcConfig.java 将拦截器实例注册
package com.base.config;
import com.base.config.Interceptor.Intercept;
import com.base.config.Interceptor.OtherIntercept;
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.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* 开发公司:个人
* 版权:刘志强
* <p>
* WebMvcConfig
*
* @author 刘志强
* @created Create Time: 2019/2/16
*/
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Autowired
public Intercept intercept;
@Autowired
public OtherIntercept otherIntercept;
//添加资源处理程序,resources资源目录下的static目录下的资源可以被直接访问
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
/**
* 多个拦截器组成一个拦截器链
* addPathPatterns 用于添加拦截规则
* excludePathPatterns 用于排除拦截
*/
registry.addInterceptor(intercept)
.addPathPatterns("/**")
.excludePathPatterns("/index");
registry.addInterceptor(otherIntercept)
.addPathPatterns("/**");
super.addInterceptors(registry);
}
}
过滤器
MainFilter.java
package com.base.config.filter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.*;
import javax.servlet.FilterConfig;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
/**
* 开发公司:个人
* 版权:个人
* <p>
* MainFilter
* @WebFilter(filterName = "mainFilter", urlPatterns = {"/*"})
* filterName 过滤器名称 urlPatterns 需要过滤的url
* @author 刘志强
* @created Create Time: 2019/5/25
*/
@WebFilter(filterName = "mainFilter", urlPatterns = {"/*"})
public class MainFilter implements Filter {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Override
public void init(FilterConfig filterConfig) throws ServletException {
logger.info("过滤器创建");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
logger.info("执行过滤请求");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
logger.info("过滤器销毁");
}
}
init() 服务器启动时执行,初始化过滤器
doFilter() 对urlPatterns声明请求进行过滤时执行
监听器
Listener.java
package com.base.config.listener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* 开发公司:个人
* 版权:个人
* <p>
* Listener
*
* @author 刘志强
* @created Create Time: 2019/5/25
*/
@WebListener()
public class Listener implements ServletRequestListener, HttpSessionListener,ServletContextListener {
protected Logger logger = LoggerFactory.getLogger(getClass());
// ServletRequestListener start
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
logger.info("监听器到" + servletRequestEvent.getServletRequest().getServerName() + "被销毁");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
logger.info("监听器到" + servletRequestEvent.getServletRequest().getServerName() + "被创建");
}
// ServletRequestListener end
// HttpSessionListener start
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
logger.info("监听器到" + httpSessionEvent.getSession().getId() + "被创建");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
logger.info("监听器到" + httpSessionEvent.getSession().getId() + "被销毁");
}
// HttpSessionListener end
// ServletContextListener start
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
logger.info("监听器到" + servletContextEvent.getServletContext().getServerInfo() + "被创建");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
logger.info("监听器到" + servletContextEvent.getServletContext().getContextPath() + "被销毁");
}
// ServletContextListener end
}