0


【JAVA后端开发】Part1--瑞吉外卖项目

文章目录

1,项目环境搭建

开发语言Java开发工具IDEA数据库MYSQL/8.0使用框架springboot+vue用到的技术栈MybatisPlus,lombok,fastjson,druid数据库JDK版本jdk1.8

1.1 数据库环境搭建

创建数据库:reggie,并执行sql文件导入11张表,每张表对应信息如下:

在这里插入图片描述

1.2 maven环境搭建

创建maven项目,并命名为reggie_take_out。检查项目设置中的maven仓库是否正确以及Runner中JRE是否正确,最后检查项目设置中的JKD是否正确。详细步骤见下图:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2,项目开发

2.1 项目框架搭建

2.1.1,导入依赖pom文件,以及编写配置文件application.yml。

pom文件

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.5</version><relativePath/><!-- lookup parent from repository --></parent><groupId>com.wang</groupId><artifactId>reggie_take_out</artifactId><version>1.0-SNAPSHOT</version><properties><java.version>1.8</java.version></properties><!--配置依赖--><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><scope>compile</scope></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.20</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.76</version></dependency><dependency><groupId>commons-lang</groupId><artifactId>commons-lang</artifactId><version>2.6</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.23</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.4.5</version></plugin></plugins></build></project>

application.yml配置文件:

server:
  port:8080
spring:
  application:
    name: reggie_take_out
  datasource:
    druid:
      driver-class-name:com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/reggie?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
      username: root
      password: root
mybatis-plus:
  configuration:
    #在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射
    map-underscore-to-camel-case:true
    log-impl:org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      id-type: ASSIGN_ID

2.1.2 编写项目启动类

将依赖注入后,我们需要写一个springboot的项目启动类ReggieApplication,代码如下:

@Slf4j//日志注解@SpringBootApplicationpublicclassReggieApplication{publicstaticvoidmain(String[] args){SpringApplication.run(ReggieApplication.class,args);
        log.info("项目启动成功。。。");}}

这一步,一个空空的springboot就搭建完成了,大家可以点击启动类,看看项目能不能正常运行。可以的话,就可以进行下一步操作了!!

2.1.3 导入静态资源,并进行静态资源映射。

1,将该项目对应的静态资源

(静态资源的获取方式见文末)

赋值到resource目录下面。又因为正常情况下只有在资源resource的目录statictemplates下的静态资源,项目才可以直接访问到,所以这里我们需要写一个能够让我们访问静态资源的配置类,进行资源映射。

2,创建config目录,存放我们的配置类,并编写WebMvcConfig.java文件:

@Slf4j@ConfigurationpublicclassWebMvcConfigextendsWebMvcConfigurationSupport{/**
     *@Author wjq
     *@Date 2022/6/23
     *@Version v1.0
     *@Description 设置静态资源映射
     */@OverrideprotectedvoidaddResourceHandlers(ResourceHandlerRegistry registry){
        registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
        registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");
        log.info("开始静态资源映射。。。");}}

到这一步项目的基本大框架就已经搭建好了,接下来就要进行具体功能的需求分析和开发了。

2.2 后台登录功能开发

按照视频讲解,完整功能开发一般要分为需求分析—>代码开发—>功能测试,三个步骤。但是我们在学习的过程中,功能测试其实就是查看代码是否能实现对应的功能并且无Bug。因此本文不再赘述这一步骤。

在这里插入图片描述

2.2.1 需求分析

1,查看登录页面

    s
   
   
    r
   
   
    c
   
   
    /
   
   
    m
   
   
    a
   
   
    i
   
   
    n
   
   
    /
   
   
    r
   
   
    e
   
   
    s
   
   
    o
   
   
    u
   
   
    r
   
   
    c
   
   
    e
   
   
    s
   
   
    /
   
   
    b
   
   
    a
   
   
    c
   
   
    k
   
   
    e
   
   
    n
   
   
    d
   
   
    /
   
   
    p
   
   
    a
   
   
    g
   
   
    e
   
   
    /
   
   
    l
   
   
    o
   
   
    g
   
   
    i
   
   
    n
   
   
    /
   
   
    l
   
   
    o
   
   
    g
   
   
    i
   
   
    n
   
   
    .
   
   
    h
   
   
    t
   
   
    m
   
   
    l
   
  
  
   src/main/resources/backend/page/login/login.html
  
 
src/main/resources/backend/page/login/login.html,获取登录页面需要信息,以及执行流程。

2,查看登录所用到的信息

在这里插入图片描述

3,对数据Employee的模型进行分析,查看我们登录用到的信息。

2.2.2 代码开发


  1. 导入实体类Employee,与表Employee进行映射。(登录必须要有用户,对应的就是数据表中的表一Employee)
  2. 使用MybatisPlus,编写mapper文件EmployeeMapper。@Mapperpublic interface EmployeeMapper extends BaseMapper<Employee> {}
  3. 使用MybatisPlus,编写service接口以及接口实现类。
  4. 导入最终结果返回类R。/** *@Author wjq *@Date 2022/6/23 *@Version v1.0 *@Description 通用返回结果类,服务端相应的数据最终都会封装成该类 */@DatapublicclassR<T>{privateInteger code;//编码:1成功,0和其它数字为失败privateString msg;//错误信息privateT data;//数据privateMap map =newHashMap();//动态数据publicstatic<T>R<T>success(T object){R<T> r =newR<T>(); r.data = object; r.code =1;return r;}publicstatic<T>R<T>error(String msg){R r =newR(); r.msg = msg; r.code =0;return r;}publicR<T>add(String key,Object value){this.map.put(key, value);returnthis;}}
  5. 编写Controller文件,在controller类中编写登录方法,登录方法的处理逻辑。a, 将页面提交的密码password进行md5加密处理b,根据页面提交的用户名username查询数据库c,如果没有查询到则返回登录失败结果d, 密码比对,如果不一致则返回登录失败结果e, 查看员工状态,如果为已禁用状态,则返回员工已禁用结果f, 登录成功,将员工id存入Session并返回登录成功结果在这里插入图片描述
@Slf4j@RestController@RequestMapping("/employee")publicclassEmployeeController{@AutowiredprivateEmployeeService employeeService;/**
     *@Author wjq
     *@Date 2022/6/24
     *@Version v1.0
     *@Description 管理元登录功能
     */@PostMapping("/login")publicR<Employee>login(HttpServletRequest request,@RequestBodyEmployee employee){//1、将页面提交的密码password进行md5加密处理String password = employee.getPassword();
        password =DigestUtils.md5DigestAsHex(password.getBytes());//2、根据页面提交的用户名username查询数据库LambdaQueryWrapper<Employee> queryWrapper =newLambdaQueryWrapper<>();
        queryWrapper.eq(Employee::getUsername,employee.getUsername());Employee emp = employeeService.getOne(queryWrapper);//3、如果没有查询到则返回登录失败结果if(emp ==null){returnR.error("登录失败");}//4、密码比对,如果不一致则返回登录失败结果if(!emp.getPassword().equals(password)){returnR.error("登录失败");}//5、查看员工状态,如果为已禁用状态,则返回员工已禁用结果if(emp.getStatus()==0){returnR.error("账号已禁用");}//6、登录成功,将员工id存入Session并返回登录成功结果
        request.getSession().setAttribute("employee",emp.getId());returnR.success(emp);}}

2.3 后台退出功能开发


2.3.1 需求分析

在这里插入图片描述

1,登录上去后,点击退出图标,要返回到登录页面。

2,打开

    s
   
   
    r
   
   
    c
   
   
    /
   
   
    m
   
   
    a
   
   
    i
   
   
    n
   
   
    /
   
   
    r
   
   
    e
   
   
    s
   
   
    o
   
   
    u
   
   
    r
   
   
    c
   
   
    e
   
   
    s
   
   
    /
   
   
    b
   
   
    a
   
   
    c
   
   
    k
   
   
    e
   
   
    n
   
   
    d
   
   
    /
   
   
    i
   
   
    n
   
   
    d
   
   
    e
   
   
    x
   
   
    .
   
   
    h
   
   
    t
   
   
    m
   
   
    l
   
  
  
   src/main/resources/backend/index.html
  
 
src/main/resources/backend/index.html文件,看到推出按键会触发方法logout。
 <img src="images/icons/[email protected]" class="outLogin" alt="退出" @click="logout" />

3,分析logout方法,其中会调用函数logoutApi()。打开该函数发现其会post到

    /
   
   
    e
   
   
    m
   
   
    p
   
   
    l
   
   
    o
   
   
    y
   
   
    e
   
   
    e
   
   
    /
   
   
    l
   
   
    o
   
   
    g
   
   
    o
   
   
    u
   
   
    t
   
  
  
   /employee/logout
  
 
/employee/logout,因此我们只要在controller中编写退出方法,并返回一个通用类R就行了。
          logout() {
            logoutApi().then((res)=>{
              if(res.code === 1){
                localStorage.removeItem('userInfo')
                window.location.href = '/backend/page/login/login.html'
              }
            })
          },
function logoutApi(){
  return $axios({
    'url': '/employee/logout',
    'method': 'post',
  })
}

2.3.2 代码开发

1,清理Session中保存的当前登录员工的id。

2,返回通用类R。

/**
     * 员工退出
     * @param request
     * @return
     */@PostMapping("/logout")publicR<String>logout(HttpServletRequest request){//清理Session中保存的当前登录员工的id
        request.getSession().removeAttribute("employee");returnR.success("退出成功");}

2.4 完善登录功能

2.4.1 需求分析

1,当我们直接访问

    h
   
   
    t
   
   
    t
   
   
    p
   
   
    :
   
   
    /
   
   
    /
   
   
    l
   
   
    o
   
   
    c
   
   
    a
   
   
    l
   
   
    h
   
   
    o
   
   
    s
   
   
    t
   
   
    :
   
   
    8080
   
   
    /
   
   
    b
   
   
    a
   
   
    c
   
   
    k
   
   
    e
   
   
    n
   
   
    d
   
   
    /
   
   
    i
   
   
    n
   
   
    d
   
   
    e
   
   
    x
   
   
    .
   
   
    h
   
   
    t
   
   
    m
   
   
    l
   
  
  
   http://localhost:8080/backend/index.html
  
 
http://localhost:8080/backend/index.html页面时,不需要账号和密码就可以直接登录上去,这是不符合实际需求的。实际需求是:只有用户输入正确账号和密码才能完成登录!

2,实现该功能有两种方式:用过滤器和拦截器,在过滤器和拦截器中判断用户是否已经完成登录,如果没有登录则跳转到登录页面。

如下图展示:第一次我们用账号密码登录属于正常需求。但是当我们推出了,直接访问index页面,竟然也能直接访问,这就是很严重的问题了。

在这里插入图片描述

2.4.2 代码开发

  1. 创建自定义过滤器LoginCheckFilter实现Filter,并重写doFilter方法
@WebFilter(filterName ="loginCheckFilter",urlPatterns ="/*")@Slf4jpublicclassLoginCheckFilterimplementsFilter{@OverridepublicvoiddoFilter(ServletRequest servletRequest,ServletResponse servletResponse,FilterChain filterChain)throwsIOException,ServletException{}}
  1. 在启动类上加入注解@ServletComponentScan,相当于打开过滤器的开关。
  2. 完善过滤器的处理逻辑 a, 获取本次请求的URI。 b,定义不需要处理的请求路径,并放在String数组中。 ​ c,判断本次请求是否需要处理,在函数check中实现,利用了AntPathMatcher类。如果不需要处理,则直接放行。
//路径匹配器,支持通配符publicstaticfinalAntPathMatcher PATH_MATCHER =newAntPathMatcher();publicbooleancheck(String[] urls,String requestURI){for(String url : urls){boolean match = PATH_MATCHER.match(url, requestURI);if(match){returntrue;}}returnfalse;}

​ d,判断登录状态,如果已登录,则直接放行。
​ e,如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据。

4,在我们写完过滤器后,前端页面中,通过文件

    j
   
   
    r
   
   
    e
   
   
    q
   
   
    u
   
   
    e
   
   
    s
   
   
    t
   
   
    .
   
   
    j
   
   
    s
   
  
  
   jrequest.js
  
 
jrequest.js中的下面方法来响应过滤器,阅读代码可以发现,其最后仍需要获取一个通用类型R,这正好对应了步骤3中流程e,需要我们向客户端即前端页面响应数据。
  service.interceptors.response.use(res=>{if(res.data.code ===0&& res.data.msg ==='NOTLOGIN'){// 返回登录页面
        console.log('---/backend/page/login/login.html---')
        localStorage.removeItem('userInfo')
        window.top.location.href ='/backend/page/login/login.html'}else{return res.data
      }},

整合后的过滤器代码,LoginCheckFilter类如下:

/**
 * 检查用户是否已经完成登录*/@WebFilter(filterName ="loginCheckFilter",urlPatterns ="/*")@Slf4jpublicclassLoginCheckFilterimplementsFilter{//路径匹配器,支持通配符publicstaticfinalAntPathMatcher PATH_MATCHER =newAntPathMatcher();@OverridepublicvoiddoFilter(ServletRequest servletRequest,ServletResponse servletResponse,FilterChain filterChain)throwsIOException,ServletException{HttpServletRequest request =(HttpServletRequest) servletRequest;HttpServletResponse response =(HttpServletResponse) servletResponse;//1、获取本次请求的URIString requestURI = request.getRequestURI();// /backend/index.html

        log.info("拦截到请求:{}",requestURI);//定义不需要处理的请求路径String[] urls =newString[]{"/employee/login","/employee/logout","/backend/**","/front/**"};//2、判断本次请求是否需要处理boolean check =check(urls, requestURI);//3、如果不需要处理,则直接放行if(check){
            log.info("本次请求{}不需要处理",requestURI);
            filterChain.doFilter(request,response);return;}//4、判断登录状态,如果已登录,则直接放行if(request.getSession().getAttribute("employee")!=null){
            log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("employee"));
            filterChain.doFilter(request,response);return;}

        log.info("用户未登录");//5、如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据
        response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));return;}/**
     * 路径匹配,检查本次请求是否需要放行
     * @param urls
     * @param requestURI
     * @return*/publicbooleancheck(String[] urls,String requestURI){for(String url : urls){boolean match = PATH_MATCHER.match(url, requestURI);if(match){returntrue;}}returnfalse;}}

3,总结

到此,项目的整体框架以及基础的登录推出功能已经完成了,看看自己搭建的项目的详细目录,对每个模块以及其作用是不是一目了然,接下来的功能开发也是按照上述的流程逐步完成。

在这里插入图片描述

注意:本博客为跟随《黑马程序员》学习,并搭建项目的详细流程记录。文中所需要的数据库sql文件以及静态资源文件和详细代码,都可以通过关注公众号黑马程序员,回复”瑞吉外卖“获得。


本文转载自: https://blog.csdn.net/qq_44085437/article/details/125491411
版权归原作者 王二黑_Leon 所有, 如有侵权,请联系我们删除。

“【JAVA后端开发】Part1--瑞吉外卖项目”的评论:

还没有评论