设为首页 加入收藏

TOP

day08-SpringMVC底层机制简单实现-04(三)
2023-07-26 08:16:05 】 浏览:75
Tags:day08-SpringMVC 简单实 -04
eBody { String value() default ""; }

(2)修改 MyDispatcherServlet 的 executeDispatch 方法

//编写方法,完成分发请求
private void executeDispatch(HttpServletRequest request, HttpServletResponse response) {
    MyHandler myHandler = getMyHandler(request);
    try {
        //如果 myHandler为 null,说明请求 url没有匹配的方法,即用户请求的资源不存在
        if (myHandler == null) {
            response.getWriter().print("<h1>404 NOT FOUND</h1>");
        } else {//匹配成功,就反射调用控制器的方法
            Class<?>[] parameterTypes = myHandler.getMethod().getParameterTypes();
            //2.创建一个参数数组(对应实参数组),在后面反射调动目标方法时会用到
            Object[] params = new Object[parameterTypes.length];
            //遍历形参数组 parameterTypes,根据形参数组的信息,将实参填充到实参数组中
            //...
            //...
            //...
            //...
        
            //反射调用目标方法
            Object result = 
                myHandler.getMethod().invoke(myHandler.getController(), params);
            //对返回的结果进行解析(原生的SpringMVC通过视图解析器来完成)
            if (result instanceof String) {
              //....略
            }//这里还可以拓展
            else if (result instanceof ArrayList) {//如果是一个集合
                Method method = myHandler.getMethod();
                //判断目标方法是否有一个@ResponseBody注解
                if (method.isAnnotationPresent(ResponseBody.class)) {
                    String valueType = method.getAnnotation(ResponseBody.class).value();
                    //如果注解的为默认值,或者value="json",就认为目标方法要返回的数据格式为json
                    if ("json".equals(valueType) || "".equals(valueType)) {
                        //对Arraylist转为json字符串
                        //这里我们使用jackson包下的工具类解决
                        ObjectMapper objectMapper = new ObjectMapper();
                        String resultJson = objectMapper.writeva lueAsString(result);
                        //这里简单处理,就直接返回
                        response.setContentType("text/html;charset=utf-8");
                        PrintWriter writer = response.getWriter();
                        writer.write(resultJson);
                        writer.flush();
                        writer.close();
                    }
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

(3)pom.xml文件中引入jackson

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.12.4</version>
</dependency>

(4)MonsterController 测试类增加方法测试

/**
 * 编写方法,返回json格式的数据
 * 1.目标方法返回的结果是给SpringMVC底层通过反射调用的位置
 * 2.我们在SpringMVC底层反射调用的位置接收到结果并进行解析即可
 * 3. @ResponseBody(value = "json") 表示希望以json格式返回数据给浏览器
 * @param request
 * @param response
 * @return
 */
@RequestMapping(value = "/monster/list/json")
@ResponseBody(value = "json")
public List<Monster> listMonsterByJson(HttpServletRequest request,
                                       HttpServletResponse response) {
    List<Monster> monsters = monsterService.listMonster();
    return monsters;

}

(5)启动 tomcat,浏览器访问 http://localhost:8080/li_springmvc/monster/list/json,返回如下结果,测试成功。

image-20230213200853614

10.小结

SpringMVC机制梳理

  1. web.xml 中配置前端控制器(DispatcherServlet)和 spring 容器文件

  2. 当启动 tomcat 时,DispatcherServlet 被 tomcat 创建

  3. 前端控制器工作:

    • (1)创建 spring 容器并初始化(从 web.xml 文件中获取 spring配置文件名):

      • a. 扫描包,获取要注入的类的全路径。

      • b. 将扫描到的类进行反射,放入ioc容器。

      • c. 完成属性自动装配

    • (2)记录控制器的目标方法和 url 的映射关系(在原生 SpringMVC 中,这个工作由 HandlerMapping 完成)

    • (3)完成分发请求:

      • a. 完成用户 url 和控制器 url 的匹配以及目标方法的调用

      • b. 目标方法参数的自动赋值:对浏览器请求 url 的参数进行处理,考虑目标方法形参的多样性,将其封装到参数数组,以反射调用的形式传递给目标方法

        目标方法的实参是在 SpringMVC 底层通过封装好的参数数组传入的

      • c. 反射目标方法,对目标方法返回的结果进行解析(原生SpringMVC中,解析的工作由视图解析器完成),决定请求转发/重定向/返回 json 格式的数据等

首页 上一页 1 2 3 下一页 尾页 3/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇文盘Rust -- 领域交互模式如何实现 下一篇《分布式技术原理与算法解析》学..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目