说明:
(1)本篇博客必要性说明:
? ? ? ? ? ●?我们知道,项目中有的接口(其实就是后台系统的那些接口),是需要管理员登录时,才能够访问的;所以在这些接口正式执行前,我们需要先检查当前是否有管理员用户的登录;
? ? ? ? ? ? ?而,为了提高效率,在【Spring Boot电商项目27:商品分类模块六:统一校验管理员身份;(选用【J2EE中的过滤器】来实现需求;重难点是【如何在Spring Boot项目中,使用过滤器】;)】?中,我们使用过滤器来统一校验管理员身份,以提高开发效率、提高程序的可维护性、可扩展性;
? ? ? ? ? ●?同理,对于【购物车模块】这个全部内容都是前台的模块来说,在调用这部分的接口时,我们要需要检查下当前是否有用户登录;(没有区分是管理员用户还是普通用户)
? ? ? ? ? ? ?所以,同理,我们这儿也开发一个过滤器,来统一处理这个问题;这样一来,我们在开发【购物车模块】的每个接口时,就不需要再写检查用户登录的逻辑代码了;
(2)声明:对本篇博客有不明白的地方,可以参考?【Spring Boot电商项目27:商品分类模块六:统一校验管理员身份;(选用【J2EE中的过滤器】来实现需求;重难点是【如何在Spring Boot项目中,使用过滤器】;)】 ;
(3)补充说明,对于本项目来说:
? ? ? ? ? ●?【前台需要登录才能够操作的接口】,没有区分是普通用户还是管理员用户,只要有用户登录,就可以访问;
? ? ? ? ? ●?【后台的接口】,是需要管理员登录,才能够访问;
目录
一:正式开发,使用过滤器,来实现【统一校验用户登录状态】的需求;
1.定义一个过滤器类:UserFilter;
2.配置过滤器类,即注册过滤器类到容器;
二:测试;
一:正式开发,使用过滤器,来实现【统一校验用户登录状态】的需求;
1.定义一个过滤器类:UserFilter;
UserFilter:
package com.imooc.mall.filter;
import com.imooc.mall.common.Constant;
import com.imooc.mall.model.pojo.User;
import com.imooc.mall.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
/**
* 描述:过滤器类;
* 功能:校验用户身份;
*/
public class UserFilter implements Filter {
public static User currentUser;
@Autowired
UserService userService;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//首先,获取Session对象;以便可以尝试从Session对象中,获取当前登录用户;
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpSession session = httpServletRequest.getSession();
//尝试获取当前登录用户
currentUser = (User) session.getAttribute(Constant.IMOOC_MALL_USER);
//如果获取不到,说明当前没有用户登录;就返回【用户未登录】的信息
if (currentUser == null) {
PrintWriter out = new HttpServletResponseWrapper((HttpServletResponse) response).getWriter();
out.write("{\n" +
" \"status\": 10007,\n" +
" \"msg\": \"NEED_LOGIN测试的中文\",\n" +
" \"data\": null\n" +
"}");
out.flush();
out.close();
//直接return的意思是,直接结束方法;不会执行后面的内容了;(自然,这儿直接结束方法的结果就是:这个请求不会进入Controller)
return;
}
//如果当前有用户登录,那么就放行
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
说明:
(1)声明:
? ? ? ? ? ●?本系统的用户分为普通用户和管理员用户;
? ? ? ? ? ●?从一般理解上,管理员用户只是用来针对后台系统的,也就是说一个管理员用户不认为会去访问前台;
? ? ? ? ? ● 【购物车模块】全部是前台的接口;按理说,应该是普通用户才能去访问这些接口;也就是说,我们似乎应该去校验当前用户是否是普通用户,如果是普通用户就允许访问【购物车模块】的接口,否则就不允许访问;
? ? ? ? ? ●?但是,这儿针对这些前台接口,我们仅仅是判断了是否有用户登录;而没有区分是普通用户还是管理员用户;换句话说,如果一个(本来是用来操作后台的)管理员用户去访问前台接口,也是默许了;(PS:在实际开发中,对这一点的处理,要看具体的产品要求)
? ? ? ? ? ●?其实,我们在UserController中,我们普通用户登录和管理员用户登录时,保存在Session中的User对象其名字我们也起做一样了;
(2)我们这儿创建了一个User对象,用来保存【获取的当前登录用户】;
(3)这儿我们并没有仔细区分是管理员用户还是普通用户;只要当前有用户登录,就允许其访问【购物车模块】的接口;
(4)一个特别需要注意的点:我们之所以,要把当前登录用户的信息在一个currentUser中,这是因为:
? ? ? ? ? ●?如果我们不这样做的话;那么我们需要获取到当前登录用户的地方,就需要在Session中获取(Controller中,通过HttpServletRequest来获取;非Controller中,借助RequestContextHolder来获取);如下所示:
? ? ? ? ? ●?如果我们这样做了,那么在需要获取当前登录用户的地方,我们就可以通过直接通过这个类来获取了;如下图所示:
2.配置过滤器类,即注册过滤器类到容器;
UserFilterConfig:
package com.imooc.mall.config;
import com.imooc.mall.filter.AdminFilter;
import com.imooc.mall.filter.UserFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 描述:【校验用户的过滤器:UserFilter】的配置类;
*/
@Configuration
public class UserFilterConfig {
@Bean
public UserFilter userFilter() {
return new UserFilter();
}
@Bean(name = "userFilterConf")
public FilterRegistrationBean userFilterConfig() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(userFilter());
filterRegistrationBean.addUrlPatterns("/cart/*");
filterRegistrationBean.addUrlPatterns("/order/*");
filterRegistrationBean.setName("userFilterConfig");
return filterRegistrationBean;
}
}
说明:
(1)拦截的url说明:可以配合接口文档来看;
(1.1)用户模块:
? ? ? ? ? ●【用户模块】:有【注册新用户】、【登录】、【更新个性签名】、【退出登录】、【管理员登录】5个接口;其中【注册新用户】、【登录】、【退出登录】、【管理员登录】是不需要任何登录校验的,也就说没有登录的时候,就可以调用这些接口;
? ? ? ? ? ●【更新个性签名】是需要校验登录;(PS:其实按照这儿的处理逻辑,也没必要区分是普通用户和管理员用户);所以,我们在UserFilterConfig中也应该配置上【更新个性签名】的url;
? ? ? ? ? ●但是,因为我们在开发【更新个性签名】接口的时候,已经在那个接口处手写了校验登录的逻辑,所以在UserFilterConfig中,我们就没有配置;(可以看到,这儿在校验的时候,也没有区分普通用户和管理员用户)
(1.2)商品分类模块:
? ? ? ? ? ● 后台有:【增加目录分类】、【更新目录分类】、【删除分类】、【分类列表(平铺)】这4个接口;这4个接口是需要管理员用户登录的;我们在AdminFilterConfig中已经配置了;
? ? ? ? ? ● 前台有:【分类列表(递归)】这1个接口;这个接口是不需要校验登录的;很显然我们就算没有登录,也能够在前台看有哪些商品分类;
(1.3)商品模块:
? ? ? ? ? ●?后台有:【增加商品】、【上传图片】、【更新商品】、【删除商品】、【批量上下架商品】、【商品列表(后台)】6个接口;这6个接口是需要管理员用户登录的;我们在AdminFilterConfig中已经配置了;
? ? ? ? ? ●?前台有:【商品列表】、【商品详情】2个接口;这两个接口是不需要校验登录的;很显然我们就算没有登录,也能够在前台看有哪些商品,也可以查看商品的详情;
(1.4)购物车模块:
?? ? ? ? ? ●?购物车模块的接口都是前台的,有:【购物车列表】、【添加商品到购物车】、【更新购物车某个商品的数量】、【删除购物车的某个商品】、【选中/不选中购物车的某个商品】、【全选/全不选中购物车的商品】6个接口;这6个接口是需要用户登录才能够调用的;(没有区分是普通用户还是管理员用户)对此,我们在UserFilterConfig中进行了处理;
(1.5)订单模块:
?? ? ? ? ? ●?后台有:【订单列表】、【订单发货】这2个接口;这两个接口需要是管理员用户登录,才能够操作;我们在AdminFilterConfig中已经配置了;
?? ? ? ? ? ●?前台有:【创建订单】、【订单详情】、【订单列表】、【取消订单】、【生成支付二维码】、【支付订单】6个接口;这6个接口是需要用户登录才能够调用的;(没有区分是普通用户还是管理员用户)对此,我们在UserFilterConfig中进行了处理;
?? ? ? ? ? ●?后台和前台均使用的接口有:【订单完结】;这个接口前后台都需要调用,所以,这个接口只需要校验是否有用户登录就行了,而没有区分是普通用户和管理员用户;
(2)通过上面的分析可以得出以下经验总结:
?? ? ? ? ? ●?上面的过程中,url的前缀是比较重要的;我们可以通过前缀来给不同的接口进行模块划分;这有助于接口的归类和管理;
?? ? ? ? ? ●?于是,我们在开发Controller的时候,可以在Controller上使用@RequestMapping注解,来统一指定该Controller中不同接口的url前缀;
二:测试;
启动项目;
|