up:: SpringBoot电商项目购物车模块介绍

说明:

(1) 本篇博客必要性说明:

● 我们知道,项目中有的接口(其实就是后台系统的那些接口),是需要管理员登录时,才能够访问的;所以在这些接口正式执行前,我们需要先检查当前是否有管理员用户的登录;

而,为了提高效率,在【SpringBoot电商项目商品分类模块统一校验管理员身份】 中,我们使用过滤器来统一校验管理员身份,以提高开发效率、提高程序的可维护性、可扩展性;

● 同理,对于【购物车模块】这个全部内容都是前台的模块来说,在调用这部分的接口时,我们要需要检查下当前是否有用户登录;(没有区分是管理员用户还是普通用户)

所以,同理,我们这儿也开发一个过滤器,来统一处理这个问题;这样一来,我们在开发【购物车模块】的每个接口时,就不需要再写检查用户登录的逻辑代码了;

(2)声明: 对本篇博客有不明白的地方,可以参考 【SpringBoot电商项目商品分类模块统一校验管理员身份】 ;

(3) 补充说明,对于本项目来说:

● 【前台需要登录才能够操作的接口】,没有区分是普通用户还是管理员用户,只要有用户登录,就可以访问;

● 【后台的接口】,是需要管理员登录,才能够访问;


一:正式开发,使用过滤器,来实现【统一校验用户登录状态】的需求;

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前缀;


二:测试;

启动项目;