自己实现 SpringMVC 底层机制 系列之-实现任务阶段 8- 完成返回 JSON 格式数据-@ResponseBody

news2025/3/1 23:07:49

😀前言
自己实现 SpringMVC 底层机制 系列之-实现任务阶段 8- 完成返回 JSON 格式数据-@ResponseBody

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

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

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

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

文章目录

  • 实现任务阶段 8- 完成返回 JSON 格式数据-@ResponseBody
    • 功能说明:
    • 分析示意图
      • ● 代码实现
        • 创建自定义注解ResponseBody
        • 修改MonsterController.java类 增加方法
        • 修改pom.xml
        • 修改WyxDispatcherServlet.java类
    • 😄总结

实现任务阶段 8- 完成返回 JSON 格式数据-@ResponseBody

功能说明:

通自定义@ResponseBody 返回 JSON 格式

分析示意图

img

● 代码实现

说明,整个实现思路,就是参考 SpringMVC

创建自定义注解ResponseBody

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {
}

修改MonsterController.java类 增加方法

编写方法,返回json格式的数据

  1. 目标方法返回的结果是给springmvc底层通过反射调用的位置

  2. 我们在springmvc底层反射调用的位置,接收到结果并解析即可

  3. 方法上标注了 @ResponseBody 表示希望以json格式返回给客户端/浏览器

  4. 目标方法的实参,在springmvc底层通过封装好的参数数组,传入…

    @RequestMapping("/monster/list/json")
    @ResponseBody
    public List<Monster> listMonsterByJson(HttpServletRequest request,
                                           HttpServletResponse response) {

        List<Monster> monsters = monsterService.listMonster();
        return monsters;
    }

修改pom.xml

        <!--引入jackson 使用他的工具类可以进行json操作 -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.4</version>
        </dependency>

修改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;
                    }
                }

                
                
                //处理提交的数据中文乱码
                request.setCharacterEncoding("utf-8");

                //将http请求参数封装到params数组中, 提示,要注意填充实参的时候,顺序问题
                //1. 获取http请求的参数集合
                //解读
                //http://localhost:8080/monster/find?name=牛魔王&hobby=打篮球&hobby=喝酒
                //2. 返回的Map<String,String[]> String:表示http请求的参数名
                //   String[]:表示http请求的参数值,为什么是数组

                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);
                    }

                }//这里还可以扩展
                else if(result instanceof ArrayList) {//如果是ArrayList

                    //判断目标方法是否有@ResponseBody
                    Method method = wyxHandler.getMethod();
                    if(method.isAnnotationPresent(ResponseBody.class)) {
                        //把result [ArrayList] 转成json格式数据-》返回
                        //这里我们需要使用到java中如何将 ArrayList 转成 json
                        //这里我们需要使用jackson包下的工具类可以轻松的搞定.

                        ObjectMapper objectMapper = new ObjectMapper();
                        String resultJson =
                                objectMapper.writeValueAsString(result);

                        response.setContentType("text/html;charset=utf-8");
                        //这里简单的处理,就直接返回
                        PrintWriter writer = response.getWriter();
                        writer.write(resultJson);
                        writer.flush();
                        writer.close();

                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

😄总结

到这里本文就正式完成了自己实现 SpringMVC 底层机制了过程太多不易了 如有帮到您希望可以点赞
            
            
😉自己实现 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

第七篇->自己实现 SpringMVC 底层机制 系列之-实现任务阶段 7- 完成简单视图解析
            
                        
                        
😁热门专栏推荐
想学习vue的可以看看这个

java基础合集

数据库合集

redis合集

nginx合集

linux合集

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

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

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

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

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

相关文章

大数据风控介绍

众所周知&#xff0c;金融是数据化程度最高的行业之一&#xff0c;也是人工智能和大数据技术重要的应用领域。随着大数据收集、存储、分析和模型技术日益成熟&#xff0c;大数据技术逐渐应用到金融风控的各个环节。个推作为专业的数据智能服务商&#xff0c;拥有海量数据资源&a…

Android项目如何上传Gitee仓库

前言 最近Android项目比较多&#xff0c;我都是把Android项目上传到Gitee中去&#xff0c;GitHub的话我用的少&#xff0c;可能我还是更喜欢Gitee吧&#xff0c;毕竟Gitee仓库用起来更加方便 一. 创建Gitee仓库 1. 先创建一个Gitee账号&#xff0c;然后登录上去 2. 创建Androi…

基于JSP+Servlet+mysql养老院管理系统

基于JSPServletmysql养老院管理系统 一、系统介绍二、功能展示四、其他系统实现五、获取源码 一、系统介绍 项目类型&#xff1a;Java web项目 项目名称&#xff1a;基于JSPServlet的养老院管理系统 [yanglaoyuan] 当前版本&#xff1a;V1.0.0版本 难度等级&#xff1a;✩✩点…

恒运资本分析:科技股有哪些股票?

跟着科技的不断进步&#xff0c;科技职业越来越遭到人们的重视。在股市中&#xff0c;出资科技股票已经成为人们赚取高额收益的一种方法。那么科技股有哪些值得出资的股票呢&#xff1f;本文将从多个角度剖析科技股。 一、美股科技股票 在美股商场中&#xff0c;科技股票一向以…

QIIME 2教程. 29补充资源SupplementaryResources(2023.5)

补充资源 Supplementary resources https://docs.qiime2.org/2023.5/supplementary-resources/ 教学内容 Educational content 以下资源对于了解有关微生物组分析和生物信息学的更多信息很有用&#xff1a; 应用生物信息学导论 An Introduction to Applied Bioinformatics http…

三维模型OBJ格式轻量化压缩处理的数据质量提升方法分析

三维模型OBJ格式轻量化压缩处理的数据质量提升方法分析 在三维模型的OBJ格式轻量化压缩处理过程中&#xff0c;除了减小文件大小和提高加载速度之外&#xff0c;我们也需要考虑如何提升数据质量。以下是几种常见的方法&#xff1a; 1、优化顶点数据&#xff1a;顶点数据是三维…

三层架构与MVC模式区别

三层架构 三层即 视图层、业务逻辑层、持久层&#xff08;数据访问层&#xff09; MVC模式 MVC 即 Model&#xff08;模型&#xff09;&#xff0c;View&#xff08;视图&#xff09;&#xff0c;Controller&#xff08;控制控制器&#xff09;。 --------------------------…

fastapi集成elastic-apm,实现性能监控

fastapi集成elastic-apm&#xff0c;实现性能监控 本文适用于 Starlette/FastAPIStarlette/FastAPI SupportInstallationSetupFastAPIUsagePerformance metricsIgnoring specific routes Supported Starlette and Python versions 具体使用示例官网的配置项介绍各语言框架集成e…

33、在SpringBoot项目添加Web组件(Servlet、Filter 和 Listener) 的三种方法

通过Spring Bean 来添加 Servlet、Filter 和 Listener ★ 添加Web组件&#xff08;Servlet、Filter、Listener&#xff09;的三种方式&#xff1a; - 使用Spring Bean添加Servlet、Filter或Listener。- 使用XxxRegistrationBean手动添加Servlet、Filter或Listener。- 使用Clas…

Spring Cloud Alibaba-Sentinel--服务容错

1 高并发带来的问题 在微服务架构中&#xff0c;我们将业务拆分成一个个的服务&#xff0c;服务与服务之间可以相互调用&#xff0c;但是由于网络 原因或者自身的原因&#xff0c;服务并不能保证服务的100%可用&#xff0c;如果单个服务出现问题&#xff0c;调用这个服务就会出…

kafka--技术文档--架构体系

架构体系 Kafka的架构体系包括以下几个部分&#xff1a; Producer. 消息生产者&#xff0c;就是向Kafka broker发送消息的客户端。Broker. 一台Kafka服务器就是一个Broker。一个集群由多个Broker组成。一个Broker可以容纳多个Topic。Topic. 可以理解为一个队列&#xff0c;一…

从零开始的Hadoop学习(二)| Hadoop介绍、优势、组成、HDFS架构

1. Hadoop 是什么 Hadoop是一个由Apache基金会所开发的分布式系统基础架构。主要解决&#xff0c;海量数据的存储和海量数据的分析计算问题。广义上来说&#xff0c;Hadoop通常是指一个更广泛的概念—Hadoop生态圈。 2. Hadoop 的优势 高可靠性&#xff1a;Hadoop底层维护多…

js reverse实现数据的倒序

2023.8.25今天我学习了如何在数组顺序进行倒序排列&#xff0c;如&#xff1a; 原数组为&#xff1a; 我们只需要对数组使用reverse()方法 let demo [{id: 1, name: 一号},{id: 2, name: 二号},{id: 3, name: 三号},]demo.reverse()console.log(demo) 扩展&#xff1a; 当我…

SV-9032 机架式网络采播器

SV-9032 机架式网络采播器 一、描述 18123651365微信 SV-9032是我司的一款机架式网络采播器&#xff0c;具有10/100M以太网接口&#xff0c;后面板上有两路线路输入接口&#xff0c;可以直接连接音源输出设备&#xff0c;将采集音源编码后发送至网络播放终端上。同时还具有三…

Python Scrapy网络爬虫框架从入门到实战

Python Scrapy是一个强大的网络爬虫框架&#xff0c;它提供了丰富的功能和灵活的扩展性&#xff0c;使得爬取网页数据变得简单高效。本文将介绍Scrapy框架的基本概念、用法和实际案例&#xff0c;帮助你快速上手和应用Scrapy进行数据抓取。 Scrapy是一个基于Python的开源网络爬…

淘宝免费爬虫数据 商品详情数据 商品销售额销量API

场景&#xff1a;一个宽敞明亮的办公室&#xff0c;一位公司高管坐在办公桌前。 高管&#xff08;自言自语&#xff09;&#xff1a;淘宝&#xff0c;这个平台上商品真是琳琅满目&#xff0c;应该有不少销售数据吧。我该怎么利用这些数据呢&#xff1f; 突然&#xff0c;房间…

vue 后台管理系统登录 记住密码 功能(Cookies实现)

安装插件 import Cookies from js-cookie 组件引入 import Cookies from js-cookie; 存值&#xff1a; Cookies.set(username, state.account, { expires: 30 }); // username 存的值的名字&#xff0c;state.account 存的值 expires 存储的时间&#xff0c;30天Cookies…

Android开发之性能优化工具Profiler

前言 性能优化问题&#xff0c;在我们开发时都会遇到&#xff0c;但是在小厂和对自己要求不严格的情况下&#xff0c;我都很少去做性能优化&#xff1b; 在性能优化上&#xff0c;基本大家都是通过自己的开发经验和性能分析工具来发现问题&#xff0c;今天给大家分享一下小编最…

学习中ChatGPT的17种用法

ChatGPT本质上是一个聊天工具&#xff0c;旧金山的人工智能企业OpenAI于2022年11月正式推出ChatGPT。那么&#xff0c;ChatGPT与其他人工智能产品相比有什么特殊呢&#xff1f; 它除了可以回答结构性的问题&#xff0c;例如语法修正、翻译和查找答案之外。最关键的是它能够去解…

CSDN编程题-每日一练(2023-08-25)

CSDN编程题-每日一练&#xff08;2023-08-25&#xff09; 一、题目名称&#xff1a;影分身二、题目名称&#xff1a;小鱼的航程(改进版)三、题目名称&#xff1a;排查网络故障 一、题目名称&#xff1a;影分身 时间限制&#xff1a;1000ms内存限制&#xff1a;256M 题目描述&am…