设为首页 加入收藏

TOP

day08-SpringMVC底层机制简单实现-04(一)
2023-07-26 08:16:05 】 浏览:69
Tags:day08-SpringMVC 简单实 -04

SpringMVC底层机制简单实现-04

https://github.com/liyuelian/springmvc-demo.git

8.任务7-完成简单视图解析

功能说明:通过目标方法返回的 String,转发或重定向到指定页面

8.1分析

原生的 SpringMVC 使用视图解析器来对 Handler 方法返回的 String(该String会转为视图类)进行解析,然后转发或重定向到指定页面。

这里为了简化,直接在自定义的前端控制器编写方法完成视图解析器的功能。

image-20230212213432844

8.2代码实现

(1)修改 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 {//匹配成功,就反射调用控制器的方法
            //1.先获取目标方法的所有形参的参数信息
            Class<?>[] parameterTypes = myHandler.getMethod().getParameterTypes();
            //2.创建一个参数数组(对应实参数组),在后面反射调动目标方法时会用到
            Object[] params = new Object[parameterTypes.length];
            //遍历形参数组 parameterTypes,根据形参数组的信息,将实参填充到实参数组中

            //步骤一:将方法的 request 和 response 参数封装到参数数组,进行反射调用
            for (int i = 0; i < parameterTypes.length; i++) {
                //....
                //....略
                //....
            }
            //步骤二:将 http请求的参数封装到 params数组中[要注意填充实参数组的顺序问题]
            //先处理中文乱码问题
            request.setCharacterEncoding("utf-8");
            Map<String, String[]> parameterMap = request.getParameterMap();
            // 遍历 parameterMap,将请求参数按照顺序填充到实参数组 params
            for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
                //....
                //....略
                //....
            }
            //反射调用目标方法
            Object result = myHandler.getMethod()
                .invoke(myHandler.getController(), params);
            //对返回的结果进行解析(原生的SpringMVC通过视图解析器来完成)
            if (result instanceof String) {
                String viewName = (String) result;
                System.out.println("viewName=" + viewName);
                if (viewName.contains(":")) {//如果返回的String结果为 forward:/login_ok.jsp
                    // 或 redirect:/login_ok.jsp 的形式
                    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)) {//重定向
                        //注意这里的路径问题
                        viewPage = request.getContextPath() + viewPage;
                        response.sendRedirect(viewPage);
                    }
                } else {//如果两者都没有,默认为请求转发
                    request.getRequestDispatcher("/" + viewName)
                            .forward(request, response);
                }
            }//这里还可以拓展
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

(2)创建测试页面和测试方法

MonsterService 接口:

package com.li.service;

import com.li.entity.Monster;

import java.util.List;

/**
 * @author 李
 * @version 1.0
 */
public interface MonsterService {
    //增加方法,处理登录
    public boolean login(String name);
}

MonsterServiceImpl 实现类:

package com.li.service.impl;

import com.li.entity.Monster;
import com.li.myspringmvc.annotation.Service;
import com.li.service.MonsterService;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 李
 * @version 1.0
 * MonsterServiceImpl 作为一个Service对象注入容器
 */
@Service
public class MonsterServiceImpl implements MonsterService {
    @Override
    public boolean login(String name) {
        //模拟DB
        if ("白骨精".equals(name)) {
            return true;
        } else {
            return false;
        }
    }
}

MonsterController 控制器:

package com.li.controller;

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

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目