基于springboot和vue2外卖点餐系统的项目总结


写在前面

项目介绍:本项目是一个外卖点餐的系统

使用的主要技术栈 springboot,mybatis-plus,redis,vue2

本项目比较基础,对于熟悉写项目的整体架构会有一个比较清晰的认识。

下面梳理出来的项目中的亮点部分。

具体的项目的源码以及项目的项目详细介绍在gitte仓库中

使用过滤器

过滤器可以对于用户的请求进行拦截,避免了用户在没有登录的情况下访问项目。
如何使用过滤器,通过一个最基础的springboot项目进行演示,分别为LoginController类,LoginFilter类,以及一个启动类,端口号使用的是8081
在这里插入图片描述
LoginFilter.java代码如下
该类实现了Filter接口,注意是javax.serlet包下的,该接口中有三个方法,而只有doFilter是抽象方法,所以需要重写该方法。需要在该类上面加上注解,@WebFilter(filterName = "LoginFilter",urlPatterns = {"/*"}),表明需要拦截的请求路径,在该演示中使用的是{"/*}表示拦截的所有的请求,因此用户的任何请求,首先都会进入该类进行处理之后,才会进入到controller层。要想让该类其作用,并且要让springboot在启动的时候知道该类的存在,需要在启动类中加上注解@ServletComponentScan

package com.wjiangquna.filter;

import com.sun.deploy.net.HttpResponse;
import lombok.extern.slf4j.Slf4j;
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过滤器名字
 * urlPatterns拦截的请求,这里是拦截所有的请求
 *
 */

@Slf4j
@WebFilter(filterName = "LoginFilter",urlPatterns = {"/*"})
public class LoginFilter implements Filter{

    //路径匹配器,支持通配符(spring给我们提供的工具)
    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;

        // 获取本次请求的URUI
        String requestURI = request.getRequestURI();    //获取请求的URI
        StringBuffer requestURL = request.getRequestURL(); //获取请求的URL

        log.info("拦截到请求:{},请求的URL为:{}",requestURI,requestURL);

        // 定义不需要拦截的请求
        String[] urls = new String[]{"/user/login", "/user/logout"};

        // 检测请求是否需要处理
        boolean check = check(urls, requestURI);
        if(check){
            log.info("本次请求{}不需要处理",requestURI);
            // 放行
            filterChain.doFilter(request,response);
            return;
        }
        response.getWriter().write("You do not have access rights");
    }
    
    /**
     * 路径匹配,检查本次请求是否需要放行
     * @param requestURI 请求的URI地址
     * @return true说明匹配上了
     */
    public boolean check(String[] urls,String requestURI){
        for (String url:urls){
            boolean match = PATH_MATCHER.match(url, requestURI);
            if(match){
                return true;
            }
        }
        return false;
    }
}

启动类的代码

package com.wjiangquna;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
@ServletComponentScan  //这个是注解是让过滤器中那些生效的,可以扫描到过滤器的那些,才能扫描WebFilter这些注解
@Slf4j
public class FilterDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(FilterDemoApplication.class, args);
        log.info("项目启动了");
    }
}

LoginController.java

package com.wjiangquna.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author weijiangquan
 * @date 2022/8/7 -21:12
 * @Description
 */
@RestController
@RequestMapping("/user")
public class LoginController {

    @GetMapping("/login")
    public String login() {
        return "success";
    }

    @GetMapping("logout")
    public String logout() {
        return "logout";
    }

    @GetMapping("/list")
    public String list() {
        return "error";
    }

}

测试过滤器
启动项目之后进行测试,对于Logincontroller的三个接口进行的测试
在这里插入图片描述
在控制台上可以看到该日志信息
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
对于请求http://localhost:8081/user/logouthttp://localhost:8081/user/login由在过滤器中的下面的代码匹配上了之后,就会直接返回,这里的返回的意思就是可以访问LoginController层的相应的接口了

 // 定义不需要拦截的请求
        String[] urls = new String[]{"/user/login", "/user/logout"};

        // 检测请求是否需要处理
        boolean check = check(urls, requestURI);
        if(check){
            log.info("本次请求{}不需要处理",requestURI);
            // 放行
            filterChain.doFilter(request,response);
            return;
        }

对于接口http://localhost:8081/user/list,由于没有匹配上,所以直接通过response对象返回信息给用户
在这里插入图片描述
在这里插入图片描述

总结:
在本次过滤器的演示的功能中,或许功能比较简单,没有涉及到复杂的逻辑,而是提供了一种在项目中使用过滤器的思路,在不同的情况下可以根据自己的需要和项目的走向进行拓展。而在瑞吉外卖的项目中基于上面也拓展了一些功能,比如在过滤器中判断用户是否登录,也就是检测session
是否存在唯一的标识,如果没有使用过滤器的化,就需要在controller每一个接口中进行判断,这样的化,就会让代码量变大,维护性更差。

使用全局异常进行捕获

在本项目中使用到全局异常的处理,
在这里插入图片描述
全局异常可以使整个项目更加的完善

package com.wjiangquan.whale.common;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.sql.SQLIntegrityConstraintViolationException;

/**
 * @author weijiangquan
 * @date 2022/7/23 -23:12
 * @Description 全局异常的处理
 */

@ControllerAdvice(annotations = {RestController.class, Controller.class})
//拦截加了这个RestController注解的controller 加到了普通的也会拦截
@ResponseBody   //最终的结果返回json
@Slf4j
public class GlobalExceptionHandler {
    /**
     * 进行异常处理的方法
     *
     * @return
     */
    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)  //处理哪些类型的异常
    public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex) {
        log.error(ex.getMessage());
        // getMessage的内容为 Duplicate entry 'aaa' for key 'idx_username'
        if (ex.getMessage().contains("Duplicate entry")) {
            String[] split = ex.getMessage().split(" ");
            String msg = split[2] + "已存在";
            return R.error(msg);
        }
        return R.error("未知错误");
    }


    /**
     * 捕获自定义的异常
     * @return
     */
    @ExceptionHandler(CustomException.class)  //处理哪些类型的异常
    public R<String> exceptionHandler(CustomException ex) {
        log.error(ex.getMessage());
        return R.error(ex.getMessage());
    }
}

自定义异常类

package com.wjiangquan.whale.common;

/**
 * @author weijiangquan
 * @date 2022/7/30 -19:43
 * @Description 自定义业务异常
 */
public class CustomException extends RuntimeException{
    public CustomException(String message){
        super(message);
    }
}

参考视频

https://www.bilibili.com/video/BV13a411q753?share_source=copy_web&vd_source=1f198fa093790427b60b33b612ecabca

项目笔记和源码地址

项目笔记文档截图

在这里插入图片描述

下面是做项目的过程中整理的源码和以及笔记的地址。

https://gitee.com/wei-jiangquan/reggie_take_out/tree/master/

mybatis-plus的官网

https://baomidou.com/

总结:
平时在项目中要学会处理异常,而全局异常的处理就是一个很好的选择,就异常进行统一出处理,可以处理系统异常以及自定义的异常。可以给整个项目指定一个标准。

  • 29
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 21
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莪假裝堅強

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值