登录思路梳理
1.使用拦截器拦截不开放的请求路径,拦截后判断Session中有无用户数据
(有则放行请求,无则重定向到登录页面)
2.接收用户名和密码,判断是否正确(不正确返回错误信息,前端跳转到登录页面)
3.正确则将用户数据存入Session
代码实现
业务层中接收用户数据去数据库查询有无数据,不为空则存入Session。
JsonResult 是自定义的返回数据类。
@Override
public JsonResult login(SysUser user, HttpSession session) {
SysUser sysUser = sysUserLoginDao.login(user);
if (sysUser != null ){
session.setAttribute("user",user);
return new JsonResult(ErrorCode.SUCCESS);
}
return new JsonResult(ErrorCode.PARAM_ERROR);
}
spring登录拦截器
HandlerInterceptor 拦截器使用aop思想,对请求进行处理
preHandle:在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制、权限校验等处理;
postHandle:在业务处理器处理请求执行完成后,生成视图之前执行。后处理(调用了Service并返回ModelAndView,但未进行页面渲染),有机会修改ModelAndView (这个博主就基本不怎么用了);
afterCompletion:在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面);
@Configuration //配置类注解
public class LoginInterceptor implements HandlerInterceptor {
/**
* 返回true表示不拦截
* false表示拦截
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
Object user = session.getAttribute("user");
if(!Objects.isNull(user)){
return true;
}
response.sendRedirect("/login/login");
return false;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
spring-mvc.xml路径拦截和放行
<!-- 拦截请求-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/*"/> //拦截所有请求
<!-- 放行的请求 -->
<mvc:exclude-mapping path="/static/*"/>
<mvc:exclude-mapping path="/templates/*"/>
<mvc:exclude-mapping path="/css/*"/>
<mvc:exclude-mapping path="/js/*"/>
<mvc:exclude-mapping path="/fonts/*"/>
<mvc:exclude-mapping path="/images/*"/>
<mvc:exclude-mapping path="/lib/*"/>
<mvc:exclude-mapping path="/login/*"/>
<mvc:exclude-mapping path="/login-1.html"/>
<mvc:exclude-mapping path="/kaptcha"/>
<!-- 注册拦截器,拦截请求后跳转到这个类进行处理 -->
<bean id="loginInterceptor" class="org.lanqiao.config.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
springBoot过滤器
相较于spring,springboot则方便很多,直接使用一个类即可实现session判断和资源拦截与放行。
package com.itheima.reggie.filter;
import com.alibaba.fastjson.JSON;
import com.itheima.reggie.common.BaseContext;
import com.itheima.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
过滤器
检查用户是否登陆
filterName = "loginCheckFilter" 过滤器自定义名称
urlPatterns = "/* 拦截所有请求
* */
*
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
//路径匹配器,支持通配符
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//获取本次请求的URI
String requestURI = request.getRequestURI();
//定义放行的请求
String[] urls = new String[]{
//自定义可以放行的请求,比如登录注册请求,页面静态资源的请求等
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**",
"/common/**",
"/user/sendMsg", //移动端发送短信
"/user/login", //移动端登录
};
//判断本次请求是否需要处理
boolean check = check(urls, requestURI);
//如果不需要处理,就放行
if (check){
filterChain.doFilter(request,response);
return;
}
//判断是否登陆
if (request.getSession().getAttribute("user") != null){ //查看存入的用户session是否为空
//获取当前用户id
Long empId = (Long) request.getSession().getAttribute("user");
BaseContext.setCurrentId(empId);
filterChain.doFilter(request,response);
return;
}
//判断登陆状态,未登陆就通过输出流向客户端响应数据
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
return;
}
//判断路径的方法
public boolean check(String[] urls,String requestURI){
for (String url:urls){
boolean match = PATH_MATCHER.match(url,requestURI);
if (match){
return true;
}
}
return false;
}
}
静态资源映射(扩展)
使用springboot时,resources目录底下有static和template,系统会默认在这两个目录底下寻找前端文件,如果你的前端资源不想放在这两个目录下,可以配置映射告诉springboot在你新建的目录中找前端资源,请求访问时会自动跳转到配置的目录下。
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
/**
* 设置静态资源映射
* @param registry
*/
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
log.info("开始进行静态资源映射...");
//静态资源
registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");
}
}