有三种实现方式:
第一种:实现Controller接口
定义一个控制器实现Controller接口
package com.laoxu.controller.mvc;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloDemo1Controller implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("hello");
return modelAndView;
}
}
将该控制器加入到spring ioc容器中
在view目录下创建hello.jsp
<%--
Created by IntelliJ IDEA.
User: lenovo
Date: 2021/8/7
Time: 18:41
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>hello jsp</title>
</head>
<body>
<h1>hello spring mvc</h1>
</body>
</html>
访问:http://localhost:8080/hello
HelloDemo1Controller实现了Controller接口,并且以/hello为name加入到ioc容器中,其中modelAndView.setViewName("hello"); 设置视图名称,渲染时会根据视图解析器去渲染页面,加上视图解析器配置的前缀和后缀即 /view/hello.jsp
DispatcherServlet源码分析:
1.获取HandlerExecutionChain 处理器执行链
查看HandlerExecutionChain类,可以看到类中包含了handler
2、获取处理器映射HandlerMapping
遍历所有的handlerMappings查找处理映射器
可以看到此种方式获取到的处理器映射为BeanNameUrlHandlerMapping
3、获取处理器适配器HandlerAdapter
遍历所有的handlerAdapters查找处理器适配器,并且每个都调用一遍ha.supports(handler)方法进行校验是否支持此适配器
最后找到支持的适配器为SimplecontrollerHandlerAdapter
4、获取模型和视图ModelAndView
可以看到之前获取到的是SimplecontrollerHandlerAdapter
重点来了!!!直接根据我们实现Controller的控制器进行强制转换,得到我们写的HelloDemo1Controller,并进行调用handleRequest方法
package com.laoxu.controller.mvc;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloDemo1Controller implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("hello");
return modelAndView;
}
}
5、将ModelAndView传给ViewResolver
可以看到ModelAndView.view为我们自定义设置的hello
视图解析器ViewResolver进行解析
解析得到View对象org. springframework.web.servlet.view.Jstlview
6、渲染View
判断视图是要include还是forward,这里是forward渲染到前端
forward和include的区别就是
- forward拿目标页面代替原有页面,
- include则拿目标页面插入原有页面。
第二种:使用注解
package com.laoxu.controller.mvc;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloDemo2Controller {
@RequestMapping(value = "hello2", method = RequestMethod.GET)
public String hello2() {
return "hello2";
}
}
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloDemo2Controller {
@RequestMapping(value = "hello2", method = RequestMethod.GET)
public String hello2() {
return "hello2";
}
}
- 获取处理器映射HandlerMapping
遍历所有的handlerMappings查找处理映射器
可以看到此种方式获取到的处理器映射为RequestMappingHandlerMapping
- 获取处理器适配器HandlerAdapter
遍历所有的handlerAdapters查找处理器适配器,并且每个都调用一遍ha.supports(handler)方法进行校验是否支持此适配器
最后找到支持的适配器为RequestMappingHandlerAdapter
- 获取模型和视图ModelAndView
第三种:实现HttpRequestHandler接口
package com.laoxu.controller.mvc;
import org.springframework.web.HttpRequestHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class HelloDemo3Controller implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
httpServletRequest.getRequestDispatcher("/views/hello.jsp").forward(httpServletRequest, httpServletResponse);
}
}
- 将HelloDemo3Controller加入到ioc容器
- 获取处理器映射HandlerMapping
遍历所有的handlerMappings查找处理映射器
可以看到此种方式获取到的处理器映射为BeanNameUrlHandlerMapping
- 获取处理器适配器HandlerAdapter
遍历所有的handlerAdapters查找处理器适配器,并且每个都调用一遍ha.supports(handler)方法进行校验是否支持此适配器
最后找到支持的适配器为 HttprequestHandlerAdapter
- 获取模型和视图ModelAndView
重点来了!!!直接根据我们实现HttpRequestHandler的控制器进行强制转换,得到我们写的HelloDemo3Controller,并进行调用handleRequest方法
访问:http://localhost:8080/hello3