若依不分离----->登录模块保姆级源码解析(0)

若依不分离登录模块源码解析

首先将项目运行起来

我们发现 localhost有一个login路径就可以去idea找这个路径看看干了什么走起
在这里插入图片描述
打开项目右键 find in path
在这里插入图片描述我们点进去这个GetMapping
在这里插入图片描述
我们把这个代码拿出来品尝一番,可以看到有个if判断如果是Ajax请求,返回Json字符串。
否则返回登录页

@GetMapping("/login")
    public String login(HttpServletRequest request, HttpServletResponse response, ModelMap mmap)
    {
        // 如果是Ajax请求,返回Json字符串。
        if (ServletUtils.isAjaxRequest(request))
        {
            return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}");
        }
        // 是否开启记住我
        mmap.put("isRemembered", rememberMe);
        // 是否开启用户注册
        mmap.put("isAllowRegister", Convert.toBool(configService.getKey("sys.account.registerUser"), false));
        return "login";
    }

那么如何返回呢我们点进这个renderString方法

同样的把代码拿过来品尝一番
呦呵设置了数据类型为json,字符编码为utf-8,并且把json数据输出到浏览器,相当于把json对象返回给了Ajax

/**
     * 将字符串渲染到客户端
     * 
     * @param response 渲染对象
     * @param string 待渲染的字符串
     * @return null
     */
    public static String renderString(HttpServletResponse response, String string)
    {
        try
        {
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            response.getWriter().print(string);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return null;
    }

注释说明
response.setContentType()的作用及参数

response.setContentType(MIME)的作用是使客户端浏览器,区分不同种类的数据,并根据不同的MIME调用浏览器内不同的程序嵌入模块来处理相应的数据。

上代码

    /**
    *  是设置响应连接过来的编码格式
    *  比如我像一个url说:你好,那么传过来的话我就默认用UTF-8编码接受。
    **/
    response.setCharacterEncoding("UTF-8");
     
    /**
    *  设置页面以什么编码格式显示,这里设置为UTF-8
    **/
    response.setContentType("text/html;charset=UTF-8");
     
    /**
    *  是每个请求进来的话就发送给每个请求的客户端
    **/
    response.geWriter().print(msg);

为什么要加上这样一个判断呢?

是为了解决前后分离的项目,如果将来用手机登录,手机是独立的前端,视图解析器就派不上用场了。我自己登录的时候,写上/login显示未登录,前端会根据 code = 1自行跳转到登录页面。前端能怎么跳呢 location.href = ctx + ‘index’; 就跳了

// 如果是Ajax请求,返回Json字符串。
        if (ServletUtils.isAjaxRequest(request))
        {
            return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}");
        }

还想再看看验证码?

点击验证码就会刷新
http://localhost/captcha/captchaImage?type=math&s=0.15619298308869167
在这里插入图片描述同样复制 captchaImage 去idea中 find in path

将这部分代码粘过来食用即可

 /**
     * 验证码生成
     */
    @GetMapping(value = "/captchaImage")
    public ModelAndView getKaptchaImage(HttpServletRequest request, HttpServletResponse response)
    {
        ServletOutputStream out = null;
        try
        {
            HttpSession session = request.getSession();
            response.setDateHeader("Expires", 0);
            response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
            response.addHeader("Cache-Control", "post-check=0, pre-check=0");
            response.setHeader("Pragma", "no-cache");
            //响应告诉类型
            response.setContentType("image/jpeg");

            //从请求里获取参数类型(此处type对应的是math类型)
            String type = request.getParameter("type");
            String capStr = null;
            String code = null;
            BufferedImage bi = null;
            if ("math".equals(type))
            {
                //创建了文本类型
                String capText = captchaProducerMath.createText();
                //生成的文本是"0+7=?@7"这一步截取@之前的部分
                capStr = capText.substring(0, capText.lastIndexOf("@"));
                //截取最后一个7
                code = capText.substring(capText.lastIndexOf("@") + 1);

                //根据文本创建图片
                bi = captchaProducerMath.createImage(capStr);
            }
            else if ("char".equals(type))
            {
                capStr = code = captchaProducer.createText();
                bi = captchaProducer.createImage(capStr);
            }
            session.setAttribute(Constants.KAPTCHA_SESSION_KEY, code);
            out = response.getOutputStream();
						//以流的形式将生成的图片输出到输出流
            ImageIO.write(bi, "jpg", out);
            out.flush();

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                if (out != null)
                {
                    out.close();
                }
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
        return null;
    }

继续回到登录页面
输入验证码查看
在这里插入图片描述
同样 复制 login去查找 这次是Post请求

找到代码开始食用即可

@PostMapping("/login")
    @ResponseBody
//    将对象返回转换为json格式
    public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe)
    {
        //将前端获取到的信息,封装成一个Shiro中的用户名密码令牌对象
        //这个令牌对象还实现了rememberMe记住我功能
        UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
        //Subject是Shiro的用户机制,用于安全验证等功能
        //为了获取到Subject,我们通常使用SecurityUtils工具类
//        package org.apache.shiro; 的工具类
//        package org.apache.shiro.subject;
        Subject subject = SecurityUtils.getSubject();
        try
        {

            //用户验证,出错会抛出异常AuthenticationException
            //其具体的异常在subject的实现类DelegatingSubject中具体制定
            subject.login(token);
            //调用父类BaseController的返回成功success方法
            return success();
        }
        //验证码错误异常
        catch (AuthenticationException e)
        {
            String msg = "用户或密码错误";
            //判断是否有其他的错误
            if (StringUtils.isNotEmpty(e.getMessage()))
            {
                //如果有,则替换成该错误
                //比如验证码错误
                msg = e.getMessage();
            }
            //将错误消息返回到前端
            //@ResponseBody
            //error的类型是AjaxResult,其本质是一个hashMap
            return error(msg);
        }
    }

这里发现直接调用return success();我们点进去看一看

 /**
     * 返回成功
     */
    public AjaxResult success()
    {
        return AjaxResult.success();
    }

再点AjaxResult封装类,类中有枚举方法

 /**
     * 状态类型
     */
    public enum Type
    {
        /** 成功 */
        SUCCESS(0),
        /** 警告 */
        WARN(301),
        /** 错误 */
        ERROR(500);
        private final int value;

        Type(int value)
        {
            this.value = value;
        }

        public int value()
        {
            return this.value;
        }
    }

很显然 return success(); 没有用到视图解析器 是在前端判断跳转的

我们跟到login.html
简单看一看是怎么登录的 请求是怎么发送的
啊呦找不见,没关系我们进入login.js去找

老规矩粘出来食用即可

function login() {
    $.modal.loading($("#btnSubmit").data("loading"));
    //获取账号密码 消除空格
    var username = $.common.trim($("input[name='username']").val());
    var password = $.common.trim($("input[name='password']").val());
    //获取验证码的值
    var validateCode = $("input[name='validateCode']").val();
    var rememberMe = $("input[name='rememberme']").is(':checked');
    $.ajax({
        type: "post",
        //var ctx = [[@{/}]]; 在index.html中有定义的
        url: ctx + "login",
        //把这四个传到 控制层的login页面 扣出数据封装成对象给后端
        data: {
            "username": username,
            "password": password,
            "validateCode": validateCode,
            "rememberMe": rememberMe
        },
        success: function(r) {
            //判断状态码是否等于0
            if (r.code == web_status.SUCCESS) {
                //跳到/index页面
                location.href = ctx + 'index';
            } else {
                //如果失败了就 关闭转圈圈
            	$.modal.closeLoading();
            	//触发更新验证码
            	$('.imgcode').click();
            	//验证码内容清空
            	$(".code").val("");
            	//弹窗登录失败
            	$.modal.msg(r.msg);
            }
        }
    });
}

补充 js的特性 一个页面引了8个js就相当于8个js写在一个页面互相之间可以相互调用

到这里登录已经成功了

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
当涉及到 Vue DHTMLX-Gantt 导出 Excel 的保姆完整教程时,以下是一步一步的指南: 1. 确保您的项目中已经安装了 Vue 和 DHTMLX-Gantt。如果尚未安装,请使用以下命令进行安装: ```bash npm install vue dhtmlx-gantt ``` 2. 在您的 Vue 组件中引入所需的库和样式: ```javascript import 'dhtmlx-gantt'; import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'; ``` 3. 创建一个 Vue 组件,并在模板中添加一个 Gantt 图表和一个按钮: ```html <template> <div ref="ganttContainer" style="width: 100%; height: 600px;"></div> <button @click="exportData">导出 Excel</button> </template> <script> import * as XLSX from 'xlsx'; import FileSaver from 'file-saver'; export default { mounted() { const ganttContainer = this.$refs.ganttContainer; gantt.init(ganttContainer); // 设置 Gantt 图表的配置和数据 // 示例数据 const tasks = [ { id: 1, text: '任务1', start_date: '2022-01-01', duration: 5, progress: 0.5 }, { id: 2, text: '任务2', start_date: '2022-01-06', duration: 4, progress: 0.2 }, // 其他任务... ]; gantt.parse({ data: tasks }); }, methods: { exportData() { const gantt = this.$refs.ganttContainer.$gantt; const tasks = gantt.getDatastore('task').getItems(); // 将任务数据转换为 Excel 数据格式 const data = tasks.map((task) => { return { id: task.id, text: task.text, start_date: task.start_date, duration: task.duration, progress: task.progress, }; }); // 创建 Excel 文件 const worksheet = XLSX.utils.json_to_sheet(data); const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, 'Gantt Data'); const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); const excelData = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); // 下载 Excel 文件 FileSaver.saveAs(excelData, 'gantt_data.xlsx'); }, }, }; </script> <style> /* 可选的样式 */ </style> ``` 4. 在上述示例代码中,需要注意以下部分: - 在 `mounted` 钩子中,使用 `gantt.init(ganttContainer)` 初始化 Gantt 图表,并根据您的需求设置其配置和数据。 - `exportData` 方法用于将 Gantt 图表数据导出到 Excel。确保在 `exportData` 方法中的 `this.$refs.ganttContainer.$gantt` 是对 Gantt 图表组件的正确引用。 - 点击 "导出 Excel" 按钮时,将会生成一个名为 `gantt_data.xlsx` 的 Excel 文件,其中包含了 Gantt 图表的数据。 这就是使用 Vue DHTMLX-Gantt 导出 Excel 的保姆完整教程。希望对您有所帮助!如果您有任何其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

明月常新

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

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

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

打赏作者

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

抵扣说明:

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

余额充值