自己实现 SpringMVC 底层机制 系列之-实现任务阶段 7- 完成简单视图解析

news2024/12/22 23:19:17

😀前言
自己实现 SpringMVC 底层机制 系列之-实现任务阶段 7- 完成简单视图解析

🏠个人主页:尘觉主页
在这里插入图片描述

🧑个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力😉😉

在csdn获奖荣誉: 🏆csdn城市之星2名
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 💓Java全栈群星计划top前5
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 🤗 端午大礼包获得者

💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,感谢大家的观看🥰
如果文章有什么需要改进的地方还请大佬不吝赐教 先在次感谢啦😊

文章目录

  • 🥰实现任务阶段 7- 完成简单视图解析
    • 功能说明:
    • 😉完成任务说明
      • 思路分析示意图
      • 😀代码实现
        • 修改MonsterService接口
        • 修改MonsterServiceImpl实现类新增方法
        • 修改MonsterController 增加方法
        • 创建login_ok.jsp
        • 创建login_error.jsp
        • 修改WyxDispatcherServlet.java类
        • 😋完成测试
    • 😄总结

🥰实现任务阶段 7- 完成简单视图解析

功能说明:

通过方法返回的 String, 转发或者重定向到指定页面

😉完成任务说明

- 用户输入白骨精,可以登录成功, 否则失败

- 根据登录的结果, 可以重定向或者请求转发到 login_ok.jsp / login_error.jsp, 并显示妖怪名

img

img

img

思路分析示意图

img

😀代码实现

修改MonsterService接口

public interface MonsterService{

    //增加方法-返回monster列表
    public List<Monster> listMonster();

    //增加方法,通过传入的name,返回monster列表
    public List<Monster> findMonsterByName(String name);

    //增加方法,处理登录
    public boolean login(String name);
}

修改MonsterServiceImpl实现类新增方法

    @Override
    public boolean login(String name) {
        //实际上会到DB验证->这里模拟
        if ("白骨精".equals(name)) {
            return true;
        } else {
            return false;
        }
    }

修改MonsterController 增加方法

    //处理妖怪登录的方法,返回要请求转发/重定向的字符串
    @RequestMapping("/monster/login")
    public String login(HttpServletRequest request,
                        HttpServletResponse response,
                        String mName) {

        System.out.println("--接收到mName---" + mName);
        //将mName设置到request域
        request.setAttribute("mName", mName);
        boolean b = monsterService.login(mName);
        if (b) {//登录成功!
            //return "forward:/login_ok.jsp";
            //测试重定向
            //return "redirect:/login_ok.jsp";
            //测试默认的方式-forward
            return "/login_ok.jsp";

        } else {//登录失败
            return "forward:/login_error.jsp";
        }
    }

创建login_ok.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>登录成功</title>
</head>
<body>
<h1>登录成功</h1>
欢迎你: ${requestScope.mName}
</body>
</html>

创建login_error.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>登录失败</title>
</head>
<body>
<h1>登录失败</h1>
sorry, 登录失败 ${requestScope.mName}
</body>
</html>

修改WyxDispatcherServlet.java类

    private void executeDispatch(HttpServletRequest request,
                                 HttpServletResponse response) {

        WyxHandler wyxHandler = getWyxHandler(request);
        try {
            if (null == wyxHandler) {//说明用户请求的路径/资源不存在
                response.getWriter().print("<h1>404 NOT FOUND</h1>");
            } else {//匹配成功, 反射调用控制器的方法

                //目标将: HttpServletRequest 和 HttpServletResponse封装到参数数组
                //1. 得到目标方法的所有形参参数信息[对应的数组]
                Class<?>[] parameterTypes =
                        wyxHandler.getMethod().getParameterTypes();

                //2. 创建一个参数数组[对应实参数组], 在后面反射调用目标方法时,会使用到
                Object[] params =
                        new Object[parameterTypes.length];

                //3遍历parameterTypes形参数组,根据形参数组信息,将实参填充到实参数组

                for (int i = 0; i < parameterTypes.length; i++) {
                    //取出每一个形参类型
                    Class<?> parameterType = parameterTypes[i];
                    //如果这个形参是HttpServletRequest, 将request填充到params
                    //在原生SpringMVC中,是按照类型来进行匹配,这里简化使用名字来进行匹配
                    if ("HttpServletRequest".equals(parameterType.getSimpleName())) {
                        params[i] = request;
                    } else if ("HttpServletResponse".equals(parameterType.getSimpleName())) {
                        params[i] = response;
                    }
                }

                //将http请求参数封装到params数组中, 提示,要注意填充实参的时候,顺序问题

                //1. 获取http请求的参数集合
                //解读
                //http://localhost:8080/monster/find?name=牛魔王&hobby=打篮球&hobby=喝酒
                //2. 返回的Map<String,String[]> String:表示http请求的参数名
                //   String[]:表示http请求的参数值,为什么是数组
                //
                //处理提交的数据中文乱码
                request.setCharacterEncoding("utf-8");
                Map<String, String[]> parameterMap =
                        request.getParameterMap();

                //2. 遍历parameterMap 将请求参数,按照顺序填充到实参数组params
                for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {

                    //取出key,这name就是对应请求的参数名
                    String name = entry.getKey();
                    //说明:这里只考虑提交的参数是单值的情况,即不考虑类似checkbox提示的数据
                    //    这里做了简化,如果小伙伴考虑多值情况,也不难..
                    String value = entry.getValue()[0];
                    //我们得到请求的参数对应目标方法的第几个形参,然后将其填充

                    //这里专门编写一个方法,得到请求的参数对应的是第几个形参
  
                    int indexRequestParameterIndex =
                            getIndexRequestParameterIndex(wyxHandler.getMethod(), name);
                    if (indexRequestParameterIndex != -1) {//找到对应的位置
                        params[indexRequestParameterIndex] = value;

                    } else {//说明并没有找到@RequestParam注解对应的参数,就会使用默认的机制进行配置[待..]

                        //思路
                        //1. 得到目标方法的所有形参的名称-专门编写方法获取形参名
                        //2. 对得到目标方法的所有形参名进行遍历,如果匹配就把当前请求的参数值,填充到params
                        List<String> parameterNames =
                                getParameterNames(wyxHandler.getMethod());
                        for (int i = 0; i < parameterNames.size(); i++) {
                            //如果请求参数名和目标方法的形参名一样,说明匹配成功
                            if (name.equals(parameterNames.get(i))) {
                                params[i] = value;//填充到实参数组
                                break;
                            }
                        }
                    }
                }

                /**
                 * 解读
                 * 1. 下面这样写法,其实是针对目标方法是 m(HttpServletRequest request , HttpServletResponse response)
                 * 2. 这里准备将需要传递给目标方法的 实参=>封装到参数数组=》然后以反射调用的方式传递给目标方法
                 * 3. public Object invoke(Object obj, Object... args)..
                 */
                //wyxHandler.getMethod()
                //        .invoke(wyxHandler.getController(),request,response);

                //反射调用目标方法
                Object result = wyxHandler.getMethod()
                        .invoke(wyxHandler.getController(), params);

                //这里就是对返回的结果进行解析=>原生springmvc 可以通过视图解析器来完成
                //这里直接解析,只要把视图解析的核心机制讲清楚就OK
                if (result instanceof String) {

                    String viewName = (String) result;
                    if(viewName.contains(":")){//说明你返回的String 结果forward:/login_ok.jsp 或者 redirect:/xxx/xx/xx.xx
                        String viewType = viewName.split(":")[0];//forward | redirect
                        String viewPage = viewName.split(":")[1];//是你要跳转的页面名
                        //判断是forward 还是 redirect
                        if("forward".equals(viewType)) {//说明你希望请求转发
                            request.getRequestDispatcher(viewPage)

                                    .forward(request,response);
                        } else if("redirect".equals(viewType)) {//说明你希望重定向
                            response.sendRedirect(viewPage);
                        }
                    } else {//默认是请求转发
                        request.getRequestDispatcher(viewName)
                                .forward(request,response);
                    }
 } catch (Exception e) {
            e.printStackTrace();
        }
}

😋完成测试

浏览器输入 测试http://localhost:8080/monster/login?mName=xxx

image-20230820093548955
img

😄总结

本文完成了实现任务阶段 7- 完成简单视图解析下一阶段也是最后一阶段实现任务阶段 8- 完成返回 JSON 格式数据-@ResponseBody
            
            
            
😉自己实现 SpringMVC 底层机制 核心分发 控制器+ Controller 和 Service 注入容器 + 对象自动装配 + 控制器 方法获取参数 + 视图解析 + 返回 JSON 格式数系列

第一篇->自己实现 SpringMVC 底层机制 系列之搭建 SpringMVC 底层机制开发环境和开发 WyxDispatcherServlet_springmvc分发器

第二篇->自己实现 SpringMVC 底层机制 系列之–实现任务阶段 2- 完成客户端浏览器可以请求控制层

第三篇->自己实现 SpringMVC 底层机制 系列之–实现任务阶段 3- 从 web.xml动态获取 wyxspringmvc.xml

第四篇-> 自己实现 SpringMVC 底层机制 系列之-实现任务阶段 4- 完成自定义@Service 注解功能

第五篇-> 自己实现 SpringMVC 底层机制 系列之-实现任务阶段 5- 完成 Spring 容器对象的自动装配 -@Autowried

第六篇->自己实现 SpringMVC 底层机制 系列之-实现任务阶段 6-完成控制器方法获取参数-@RequestParam
            
            
            
😁热门专栏推荐
想学习vue的可以看看这个

java基础合集

数据库合集

redis合集

nginx合集

linux合集

等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持

🤔欢迎大家加入我的社区 尘觉社区

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞

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

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

相关文章

SAP VK11/VK12 创建/更新价格记录

1、事务码VK11&#xff0c;创建物料价格 例如&#xff0c;客户10001&#xff0c;物料200001&#xff0c;价格120&#xff0c;有效期是2023.08.23-9999.12.31 现在有活动&#xff0c;在2023.08.23到2023.08.31想要维护一个活动价格100&#xff0c;而2023.09.01到9999.12.31还是…

Java开发中非常好用的工具

一、项目工具 1.1 IDE 主流的 Java 开发工具现在非 IntelliJ IDEA 莫属。前几年&#xff0c;可能 Eclipse 还能和 IDEA 一争高下&#xff0c;到了现在已经基本是 IDEA 的天下了。 就拿我自己来说吧&#xff0c;我最早用 IDEA&#xff0c;后来用了几年 Eclipse&#xff0c;再后…

EasyExcel实现多sheet文件导出

文章目录 EasyExcel引入依赖表结构学生表课程表教师表 项目结构下载模板实体类StudentVoCourseVoTeacherVo ControllerServiceEasyExcelServiceStudentServiceCourseServiceTeacherService ServiceImplEasyExcelServiceImplStudentServiceImplCourseServiceImplTeacherServiceI…

嵌入式是假风口?其实是你不够强!

嵌入式系统&#xff0c;作为一种集成电路技术的应用&#xff0c;近年来备受瞩目。然而&#xff0c;有人质疑嵌入式系统是否真的有那么大的市场前景&#xff0c;甚至认为这只是一个假风口。但实际上&#xff0c;嵌入式系统的发展潜力远不止于此&#xff0c;关键在于个人实力的提…

PI SSL证书导入

导语&#xff1a;最近在通过PI系统&#xff0c;做REST接口&#xff0c;对方地址是https的&#xff0c;调用时出现错误&#xff1a;【适配器框架出现异常: iaik.security.ssl.SSLCertificateException; Peer certificate relected by ChainVerifie】&#xff0c;此问题是因为这个…

SIP播放解码器

SIP-7101 SIP播放解码器 一、描述 SIP-7101是我司的一款壁挂式SIP网络播放终端&#xff0c;具有10/100M以太网接口&#xff0c;配置一路继电器输出和一路线路输出&#xff0c;可将内部音源输出到外接功放&#xff0c;可实现广播播放功能。SIP-7101作为网络SIP系统的播放终端&…

在Linux上安装redis7

1.检测虚拟机环境 1.1 bit检测命令&#xff1a;getconf LONG_BIT&#xff08;建议使用64bit做开发&#xff09; 1.2 gcc环境检测&#xff1a;gcc -v 如果不具备gcc环境&#xff0c;则使用yum -y install gcc- c命令进行c环境的安装 2.开始安装 2.1 下载redis&#xff1a; 进…

7、Vue 核心技术与实战 day07

1.1 vuex概述 1.2 构建 vuex [多组件数据共享] 环境 1.创建项目 vue create vuex-demo2.创建三个组件, 目录如下 |-components |--Son1.vue |--Son2.vue |-App.vue3.源代码如下 App.vue在入口组件中引入 Son1 和 Son2 这两个子组件 <template><div id"app&qu…

利用LLM模型微调的短课程;钉钉宣布开放智能化底座能力

&#x1f989; AI新闻 &#x1f680; 钉钉宣布开放智能化底座能力AI PaaS&#xff0c;推动企业数智化转型发展 摘要&#xff1a;钉钉在生态大会上宣布开放智能化底座能力AI PaaS&#xff0c;与生态伙伴探寻企业服务的新发展道路。AI PaaS结合5G、云计算和人工智能技术的普及和…

【TS】typescript基础知识

一、类型注解 : number就是类型注解&#xff0c;为变量添加类型约束的方式&#xff0c;约定了什么类型&#xff0c;就只能给变量赋什么类型的值 let age: number 18二、变量命名规则和规范 命名规则&#xff1a;变量名称只能出现数字&#xff0c;字母&#xff0c;下划线(_)…

无涯教程-Python - 环境设置

Python在包括Linux和Mac OS X在内的各种平台上都可用。让无涯教程了解如何安装设置Python环境。 最新的源代码,二进制文件,文档,新闻等可在Python的官方网站上找到https://www.python.org/ 您可以从https://www.python.org/doc/该文档有HTML,PDF和PostScript格式。 安装Pyth…

SD内存卡格式化后如何数据恢复教程

SD内存卡是一种常用的存储设备&#xff0c;可用于储存各种类型的数据&#xff0c;包括照片、音频、视频等。在使用过程中&#xff0c;你是否因为SD卡格式化而失去了重要数据而感到困扰&#xff1f;那么这篇文章的内容将能够帮助您快速有效地恢复格式化后的数据。 图片来源于网络…

python编写四画面同时播放swap视频

当代技术让我们能够创建各种有趣和实用的应用程序。在本篇博客中&#xff0c;我们将探索一个基于wxPython和OpenCV的四路视频播放器应用程序。这个应用程序可以同时播放四个视频文件&#xff0c;并将它们显示在一个GUI界面中。 C:\pythoncode\new\smetimeplaymp4.py 准备工作…

Unity实现广告滚动播放、循环播放、鼠标切换的效果

效果&#xff1a; 场景结构&#xff1a; 特殊物体&#xff1a;panel下面用排列组件horizent layout group放置多个需要显示的面板&#xff0c;用mask遮罩好。 using System.Collections; using System.Collections.Generic; using DG.Tweening; using UnityEngine; using Unity…

达梦数据库curd的简单使用

目录 添加表空间 删除表空间 添加表空间 create tablespace "test_db" datafile E:\dm_data\DM6.DBF size 32--制定路径 create tablespace “test_db”&#xff1a;创建一个名为test_db的表空间 datafile ‘DM6.DBF’&#xff1a;表示数据文件名为TDM6.DBF&…

胖小酱之听话

首先&#xff0c;我们来看看何为“物质奖励”&#xff1f; 所谓的物质奖励&#xff0c;简单通俗地说就是运用物质上的满足&#xff0c;去调动孩子的积极、主动和创造能力&#xff0c;其中物质奖励的形式一般体现在各种实物的需求方面&#xff0c;比如游戏机、玩具车、手机…

富仕转债上市价格预测

富仕转债 基本信息 转债名称&#xff1a;富仕转债&#xff0c;评级&#xff1a;AA-&#xff0c;发行规模&#xff1a;5.7亿元。 正股名称&#xff1a;四会富仕&#xff0c;今日收盘价&#xff1a;36.29元&#xff0c;转股价格&#xff1a;41.77元。 当前转股价值 转债面值 / 转…

Windows共享文件夹,用户密码访问

Windows共享文件夹&#xff0c;用户密码访问 小白教程&#xff0c;一看就会&#xff0c;一做就成。 1.先创建一个用户 计算机右键----管理----本地用户和组----点击用户进去---右键新建用户 这里以kk为例 2.找到你想共享的文件夹 3.共享-想共享的文件夹---右键---属性---共…

优化Python代理爬虫的应用

当我们在资源受限的环境中使用Python代理爬虫时&#xff0c;我们需要采取一些优化措施&#xff0c;以确保程序的高效性和稳定性。在本文中&#xff0c;我将分享一些关于如何优化Python代理爬虫在资源受限环境下的应用的实用技巧。 首先我们来了解&#xff0c;哪些情况算是资源…

Anolis 8.6 下 Redis 7.2.0 集群搭建和配置

Redis 7.2.0 搭建和集群配置 一.Redis 下载与单机部署1.Redis 下载2.虚拟机配置3.Redis 单机源码安装和测试4.Java 单机连接测试1.Pom 依赖2.配置文件3.启动类4.配置类5.单元测试6.测试结果 二.Redis 集群部署1.主从1.从节点配置2.Java 测试 2.哨兵1.哨兵节点配置2.复制一个哨兵…