crm项目bug小结

news2024/9/21 13:42:08

项目主要内容分析:

 第一天完成了系统用户登录、退出、密码修改、全局异常、非法请求与记住我等系统基本功能。

项目的目录结构如图:

1 登录思路:

**
* 1.参数校验
*   用户名 非空
*   密码 非空
* 2.根据用户名 查询用户记录
* 3.校验用户存在性
*     不存在 -->记录不存在 方法结束
* 4.用户存在
*     校验密码
*       密码错误-->密码不正确 方法结束
* 5.密码正确
*     用户登录成功 返回用户相关信息
*/

 各个文件逻辑

UserService->login 方法代码实现

UserDao->queryUserByUserName 方法定 义 & Sql 配置

UserController层login方法实现

.前端登录js 方法实现

其中:前端用ndex.ftl 添加对应index.js 使用layui 表单组件实现表单提交操作

layui的用法可以在官网找到layer弹层组件开发文档 - Layui

 ==================================================

2主页面显示用户名信息

IndexController.java main方法转发时查询登录用户信息并放置到 request域。

@Controller
public class IndexController extends
BaseController {
    /**
     * 后端管理主页面
     * @return
     */
    @RequestMapping("main")
    public String main(HttpServletRequest
request){
        Integer userId =
LoginUserUtil.releaseUserIdFromCookie(request);
      
request.setAttribute("user",userService.selectB
yPrimaryKey(userId));
        return "main";
   }
}

 3全局异常统一处理:

控制层

方法返回的内容两种情况

1 视图:视图异常  

2 Json:方法执行错误 返回错误json信息

全局异常拦截器实现

实现HandlerExceptionResolver 接口 ,处理应用程序异常信息

package com.xxxx.crm;

import com.alibaba.fastjson.JSON;
import com.xxxx.crm.base.ResultInfo;
import com.xxxx.crm.exceptions.NoLoginException;
import com.xxxx.crm.exceptions.ParamsException;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.annotation.Annotation;
import java.util.logging.Handler;

@Component
public class GlobalExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {


        if (ex instanceof NoLoginException) {
// 如果捕获的是未登录异常,则重定向到登录⻚⾯
            ModelAndView mv = new ModelAndView("redirect:/index");
            return mv;
        }
        //设置默认异常统一处理
        ModelAndView modelAndView = new ModelAndView("error");
        modelAndView.addObject("code", 500);
        modelAndView.addObject("msg", "系统异常 请重试...");
        //判断HandlerMethod 是否是控制器异常
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            ResponseBody responseBody = handlerMethod.getMethod().getDeclaredAnnotation(ResponseBody.class);

            if (responseBody == null) {
                if (ex instanceof ParamsException) {
                    ParamsException p = (ParamsException) ex;
                    modelAndView.addObject("code", p.getCode());
                    modelAndView.addObject("msg", p.getMsg());
                }
                return modelAndView;
            } else {
                ResultInfo resultInfo = new ResultInfo();
                resultInfo.setCode(500);
                resultInfo.setMsg("异常异常,请重试。。。");
                if (ex instanceof ParamsException) {
                    ParamsException p = (ParamsException) ex;
                    resultInfo.setCode(p.getCode());
                    resultInfo.setMsg(p.getMsg());
                }
                response.setContentType("application/json;charset=UTF-8");
                PrintWriter out=null;
                try{
                    out=response.getWriter();
                    String json= JSON.toJSONString(resultInfo);
                    out.write(json);
                }catch(IOException e){
                    e.printStackTrace();
                }finally {
                    if(out!=null){
                        out.close();
                    }
                }
            }
        }
        return modelAndView;
    }
}

之后再消除try-catch 代码

4. 非法请求拦截

获取cookie 解析用户id

 如果用户id存在 并且

数据库存在对应用户记录 放行

否 则进行拦截 重定向到登录页面 

NoLoginInterceptor

package com.xxxx.crm.exceptions;

/**
 * 自定义参数异常
 */
public class NoLoginException extends RuntimeException {
    private Integer code=300;
    private String msg="用户未登录!";


    public NoLoginException() {
        super("用户未登录!");
    }

    public NoLoginException(String msg) {
        super(msg);
        this.msg = msg;
    }

    public NoLoginException(Integer code) {
        super("用户未登录!");
        this.code = code;
    }

    public NoLoginException(Integer code, String msg) {
        super(msg);
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

拦截器生效配置 mvcConfig

package com.xxxx.crm.config;

import com.xxxx.crm.intercepter.NoLoginInterceptor;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Bean
    public NoLoginInterceptor noLoginInterceptor(){
        return new NoLoginInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(noLoginInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/CSS/*","/images/**","/js/**","/lib/**","/index","/user/login");
    }
}

统一异常类引入未登录异常判断

@Override
    public ModelAndView
resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler,
Exception ex) {
        /**
         * 首先判断异常类型
         *   如果异常类型为未登录异常 执行视图转发
         */
        ModelAndView mv=new ModelAndView();
        if(ex instanceof NoLoginException){
            NoLoginException ne =(NoLoginException) ex;mv.setViewName("no_login");
            mv.addObject("msg",ne.getMsg());
             mv.addObject("ctx",request.getContextPath());
            return mv;
       }
        
        /**
          后续代码省略
        */
   }

 5记住我功能实现

记住我功能核心在于当用户上次登录时如果点击了记住我,下次在重 新打开浏览器时可以不用选择登录,此时可以借助拦截器+cookie来 实现,当用户在登录时,如果用户点击了记住我功能,默认设置 cookie存储时间为7天即可

 

如上图 红色花的圈,其实区别就在这里 设置了cookie的失效时间。

以下是index.js的详细代码:

layui.use(['form','jquery','jquery_cookie'], function () {

    var form = layui.form,
        layer = layui.layer,
        $ = layui.jquery,
        $ = layui.jquery_cookie($);

    form.on('submit(login)',function (data) {

       console.log(data.field)

        $.ajax({
            type:"post",
            url:ctx+"/user/login",
            data:{
                userName:data.field.username,
                userPwd:data.field.password
            },
            success:function(result){
                console.log(result);
                if(result.code==200){
                    layer.msg("登录成功", function(){

                        //判断用户是否记住密码
                        if($("#rememberMe").prop("checked")){
                            $.cookie("userIdStr", result.userIdStr, { expires: 7 });
                            $.cookie("userName", result.userName, { expires: 7 });
                            $.cookie("trueName", result.trueName, { expires: 7 });
                        }else {
                            $.cookie("userIdStr", result.result.userIdStr);
                            $.cookie("userName", result.result.userName);
                            $.cookie("trueName", result.result.trueName);
                            window.location.href = ctx + "/main";
                        }
                    })
                }else{
                    layer.msg(result.msg,{icon:5})
                }
            }
        })
        return false;
    })
});

=======================================================================

小知识点小结:

instanceof 是 Java 的一个二元操作符,类似于 ==,>,< 等操作符。

instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。

=================================================

今日bug小结:

1.方法名字 最好复制 以防写错

2 run/debug 每次运行这个的时候

mybatis-generator:generate -e

会自动增添mapper vo等文件  不要重复运行 不然又生成冗余的代码 从而报错

一般就运行starter就行了 main方法

@SpringBootApplication
@MapperScan("com.xxxx.crm.dao")
public class Starter {
    public static void main(String[] args) {
        SpringApplication.run(Starter.class);
    }
}

3 SaleChanceService记得继承BaseService

 前者的方法是由后者继承来的 后者的方法如下 是调用了

 忘记写继承就错了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/494702.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

搞懂 API ,API 中 URI 设计规范分享

API&#xff08;Application Programming Interface&#xff09;是现代软件开发中的一项关键技术&#xff0c;它为不同应用程序间提供了数据和功能交互的标准化方式。而 URI&#xff08;Uniform Resource Identifier&#xff09;作为 API 中的重要部分&#xff0c;其规范和良好…

BigCode开放性能超越Copilot的代码生成模型Starcoder

BigCode释出高效能程式码生成模型StarCoderBase&#xff0c;与为Python调校的StarCoder&#xff0c;效能超越GitHub Copilot初期版本所用的OpenAI code-cushman-001模型&#xff1a; BigCode昨晚发布了基于源代码和自然语言文本训练的编程语言生成模型StarCoder。其训练数据包…

JavaSE基础(五)—— 方法(定义、调用、重载)、return关键字

目录 一、方法定义、调用 1. 方法完整的定义形式、调用 2. 方法的其他定义形式、调用 二、方法使用的常见问题 三、方法案例 1. 定义方法的技巧、计算 1- n的和返回 2. 数组求最值案例改方法形式 四、方法调用的内存图 五、方法的参数传递机制 基本类型和引用类型的参…

携带信息的Ajax GET请求

前端页面代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>ajax get请求</title><script type"text/javascript">window.onload function () {document.getEle…

Spring管理数据库事务

Spring编程式事务和声明式事务的验证 1、工程目录pom.xml 2、在resources目录创建配置文件applicationContext_1.xmlapplicationContext_2.xmlapplicationContext_3.xmljdbc.properties 3、创建数据表accountaccount 4、创建dao类5、创建service类6、创建测试类7、实验结果图1 …

基于python的点云处理库总结

想对于PCL&#xff0c;python处理点云的库还是比较多的&#xff0c;下面对此进行简单的总结&#xff1a; 一、Open3D A Modern Library for 3D Data Processing&#xff0c;Intel出品&#xff0c;MIT协议。 Open3D是一个支持3D数据处理软件快速开发的开源库。Open3D使用C和P…

CSS - 垂直菜单(鼠标移入时显示右侧容器)

效果图 示例源码 <body><section class="content"><ul class=

OpenVINO 2022.3之四:OpenVINO模型转换

OpenVINO 2022.3之四&#xff1a;OpenVINO模型转换 OpenVINO 2022.3 支持的模型格式: OpenVINO IR&#xff08;中间表示&#xff09; - OpenVINO™的专有格式&#xff0c;可以完全利用其全部功能。 ONNX和PaddlePaddle - 直接支持的格式&#xff0c;这意味着它们可以在OpenVI…

DT7遥控DBUS协议解析

文章目录 运行环境&#xff1a;1.1 DBUS协议解析1)DT7遥控2)配置串口引脚3)配置串口接收DMA 2.1例程代码移植1)例程移动到 Inc 和 Src2)makefile添加.c文件 3.1核心代码解释4.1代码修改1)bsp_rc.c 和 remote_control.c2)调用代码 5.1调试1)硬件接线2)串口工具监视拨杆数据 运行…

【C进阶】-- 字符串函数(1)

目录 0. 前言 1. 函数介绍 1.1 strlen 1.1.1主动改变\0的位置 ✅"strlen函数的返回类型是size_t - 无符号整型"✅ 当使用strlen函数但不引用头文件时&#xff0c;执行结果超出预料: 求字符串长度的方法&#x1f4a5; 1.计数器 2.递归 3.指针 - 指针 1.2 st…

HBase安装下载与集群(高可用)

一、准备 1.1 安装zookeeper zookeeper 安装下载与集群 1.2 安装HADOOP hadoop搭建集群搭建 1.3下载HBase https://mirrors.tuna.tsinghua.edu.cn/apache/hbase/ 二、正常部署 2.1 检查是否正常启动 2.2解压 tar -zvxf hbase-2.4.11-bin.tar.gz2.3配置环境变量 vim /…

高效的工作团队都在使用什么工具?

、 移动互联网时代&#xff0c;企业需要开源节流&#xff0c;需要提高员工整体工作效率。尤其对于互联网公司来说&#xff0c;要快速发展业务&#xff0c;更需要让团队工作简单、方便、高效。然而大多公司都面临以下低效阻碍&#xff1a;跨公司、跨部门沟通合作困难。不同部门和…

2、Flutter布局和状态管理

一、Flutter布局之Row&Column 1.1 Container的center属性: 让子控件在父控件的中间显示 Container(color: Colors.yellow,//1.Center让子部件在父控件中间child: Center(child: Text(Layout Center)),); 1.2 alignment让子控件相对父控件位置,取值范围在-1&#xff5e;1…

Mysql索引(1):索引概述

1 介绍 索引&#xff08;index&#xff09;是帮助MySQL高效获取数据的数据结构(有序)。在数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结构&#xff0c;这些数据结构以某种方式引用&#xff08;指向&#xff09;数据&#xff0c; 这样就可以在这些数据结构上…

【半监督学习】Match系列.1

半监督学习(SSL) 半监督学习(SSL). 让学习器不依赖外界交互、自动地利用未标记样本来提升学习性能. 即在少量样本标签的引导下, 能够充分利用大量无标签样本提高学习性能, 避免了数据资源的浪费, 同时解决了有标签样本较少时监督学习方法泛化能力不强和缺少样本标签引导时无监…

YoloV8涨点神器:CFPNet-ECVBlock的小目标检测,即插即用,助力检测涨点

1.Centralized Feature Pyramid for Object Detection 论文地址: https://arxiv.org/abs/2210.02093 1.摘要: CFPNet简介 CFPNet即插即用,助力检测涨点,YOLOX/YOLOv5/YOLOV7均有效 1.3 Centralized Feature Pyramid (CFP) 如图2所示,CFP主要由以下部分组成:输入图像、…

<IBM AIX><ERRPT><No.001>《出现E86653C3、49183216、8003764C告警的处理 20230506》

《出现E86653C3、49183216、8003764C告警的处理 20230506》 1 现象2 分析3 结论4 引申 1 现象 服务器出现errpt告警&#xff0c;告警为E86653C3、49183216、8003764C。 2 分析 1、hdisk1对应的VG&#xff0c;为rootvg。 lspv |grep hdisk12、查看VG状态 lsvg rootvg说明…

聊聊压电材料高温介电温谱仪所知道的那些事(GWJDN-600A)

GWJDN-600A型压电材料高温介电温谱仪 关键词&#xff1a;单通道&#xff0c;双通道&#xff0c;四通道&#xff0c;高低温 GWJDN-600A压电材料高温介电温谱仪本高频介电温谱系统主要用于绝缘材料在不同温度不同频率下的电学性能测试&#xff0c;系统包含高温炉膛&#xff0c;阻…

【云原生】k8s集群部署Rook+Ceph云原生存储

文章目录 一、Rook介绍二、Ceph介绍三、部署Rook和Ceph3.1 前置准备3.2 部署Rook3.3 部署Ceph集群3.4 部署ceph dashboard 四、部署Rook工具箱五、部署RBD StorageClass 一、Rook介绍 Rook 官网地址&#xff1a;https://rook.io 是一个自管理的分布式存储编排系统&#xff0c;…

c++基础学习Num04

目录 基于for循环 一维数组 二维数组理解 c语言的null和c的null 基于for循环 for(ELEMTYPE val:array){}ELEMTYPE:是范围变量的类型。通常使用auto自动转换范围变量类型 val:范围变量的名称。通过迭代依次接收数组中的元素值 array:容器&#xff0c;注意这里的array必须是…