回顾原生的Web应用
SpringMvc
-
ContextLoaderListener做了什么
-
DispatcherServlet创建一个子容器
-
mvc配置文件中需要声明的bean
-
HandlerMapping
-
HandlerAdapter
-
ViewResolver
回顾原生的Servlet

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<!-- 全局的配置参数,listener filter servlet 都可以获取参数 可以定义多个 -->
<context-param>
<param-name>Encoding</param-name>
<param-value>UTF-8</param-value>
</context-param>
<!-- 过滤器 可以定义多个-->
<filter>
<filter-name>filter1</filter-name>
<filter-class>filter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>filter1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 监听器可以定义多个 -->
<listener>
<listener-class>listener.MyListener</listener-class>
</listener>
<!-- servlet可以定义多个 -->
<servlet>
<servlet-name>success</servlet-name>
<servlet-class>servlet.UserServlet</servlet-class>
<init-param>
<param-name>key1</param-name>
<param-value>value1</param-value>
</init-param>
<!-- 初始化加载顺序,会调用servlet的init方法 -->
<load-on-startup>2</load-on-startup>
</servlet>
<servlet>
<servlet-name>success2</servlet-name>
<servlet-class>servlet.UserServlet2</servlet-class>
<init-param>
<param-name>key1</param-name>
<param-value>value1</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- servlet映射,跟每一个Servlet对应 -->
<servlet-mapping>
<servlet-name>success</servlet-name>
<url-pattern>/success</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>success2</servlet-name>
<url-pattern>/success2</url-pattern>
</servlet-mapping>
</web-app>
全局参数
web容器启动后,会创建一个ServletContext上下文对象,在web.xml中配置<context-param>会被上下文对象存储,任何可以获取ServletContext上下文的地方都可以调用getInitParameter("key");获取初始化参数,属于全局范围。
listener

package listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("glistener1 init");
ServletContext servletContext = servletContextEvent.getServletContext();
String value = servletContext.getInitParameter("Encoding");
System.out.println("当前设置编码" + value);
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("listener1 dest");
}
}
listener监听器分为三类,分别监听ServletContext域,HttpSession域,ServletRequest域。每一类又分成监听域对象的创建、销毁和域对象内的属性的变化。在web.xml中可以定义多个监听器。同类型的监听器按照加载顺序执行。
以上代码片段创建了一个servletContextListener用来监听Servlet上下文的创建和销毁。
filter

package filter;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-02-06 17:35
* @notify
* @version 1.0
*/
import javax.servlet.*;
import java.io.IOException;
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("filter1 init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
ServletContext servletContext = servletRequest.getServletContext();
String encoding = servletContext.getInitParameter("Encoding");
servletRequest.setCharacterEncoding(encoding);
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
System.out.println("filter1 destory");
}
}
filter过滤器,在xml中通过<filter>和<filter-mapping>定义,两个为一组在mapping中定义要过滤的路径,匹配路径的都会进入filter。在filter类中有三个方法。分别是初始化(init),销毁(destroy)。doFilter,每一个匹配路径符合的都会进入doFilter(),如果方法内部业务逻辑正确,则可以使用FilterChain.doFilter(req,resp);表示放行。多个filter会组成过滤器链,当一个第一个放行后,则进入第二个。全部通过则会到达servlet,一个不通过,则不通过。
servlet

package servlet;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-02-06 12:33
* @notify
* @version 1.0
*/
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
public class UserServlet extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("servlet1");
super.init();
}
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("success");
out.close();
}
}
servlet服务,同样的在web.xml中通过<servlet>和<servlet-mapping>,每一个servletClass需要实现HttpServlet,类HttpServlet默认实现了各种请求方式的实现。我们需要根据自身需要覆盖对应的请求方式。配置<load-on-startup>1</load-on-startup>代表该Servlet的加载顺序,ServletContext创建后,会对设置了该标签的Servlet进行初始化,负值不初始化,值越小越先被初始化。所谓初始化就是调用Servlet的init()
SpringMvc
ContextLoaderListener做了什么
在这里我们跟踪源码,主要找到listener创建ApplicationContext和创建过程中在哪里加载的配置文件。

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationconfig.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
首先我们在web.xml配置了一个监听器ContextLoaderListener,另外配置了全局参数contextConfigLocation

public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
public ContextLoaderListener() {
}
public ContextLoaderListener(WebApplicationContext context) {
super(context);
}
public void contextInitialized(ServletContextEvent event) {
this.initWebApplicationContext(event.getServletContext());
}
public void contextDestroyed(ServletContextEvent event) {
this.closeWebApplicationContext(event.getServletContext());
ContextCleanupListener.cleanupAttributes(event.getServletContext());
}
}
在全局配置参数的value中我指向了一个Spring配置文件,并且添加了一个bean。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="pojo.Person" id="person"></bean>
</beans>
该ContextLoaderListener实现了ServletContextListener,那他的功能就是监听ServletContext创建和销毁。其次,它继承了ContextLoader,该类是Spring的类。我们先来看看contextInitialized()方法在ServletContext创建时都做了什么。










DispatcherServlet创建一个子容器

<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:component-scan base-package="com.datang"/>
</beans>
在这里我们跟踪源码,查看DispatcherServlet创建子容器的,和加载配置文件的源码。前边我们说过,Servlet初始化会调用init()方法。而DispatcherServlet也继承自HttpServlet。






















mvc配置文件中需要声明的bean
HandlerMapping(处理器映射器):HandlerMapping的作用就是解析请求链接,然后根据请求链接找到执行这个请求的类(HandlerMapping所说的handler,也就是我们写的Controller或是Action)。
HandlerAdapter(处理器适配器):HandlerAdapter的作用是,执行handlerMapping找到的处理器。
ViewResolver(视图解析器):Controller处理完毕根据返回的逻辑视图,找到物理视图。
HandlerExceptionResolver:异常处理器,如果出现了异常由该类接手。
LocaleResolver:客户端转换器,获取客户端的语言环境和时区转换。
ThemeResolver:视图样式表,不知道干啥的,下边会说到。
FlashMapManager:管理重定向。
MultipartResolver:多部件解析。
以上bean都需要在mvc的配置文件中配置,是很麻烦的,但是,如果我们不配置默认使用DispatcherServlet.properties中的配置。注意!这个配置文件中,没有MultipartResolver。

HandlerMapping
HandlerMapping的作用就是解析请求链接,然后根据请求链接找到执行这个请求的类(HandlerMapping所说的handler,也就是我们写的Controller或是Action)。
BeanNameUrlHandlerMapping
BeanNameUrlHandlerMapping处理器映射器,处理器必须实现Controller接口,并且将该类配置成bean,bean的id需要是/开头,标识它是一个处理器。

package com.datang.controller;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-02-07 17:44
* @notify
* @version 1.0
*/
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 BeanNameUrlHandlerMappingController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
System.out.println("我是根据BeanNameUrlHandlerMapping找到的controller,但是显然的,我是错误的,因为我返回的是null");
return null;
}
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean id="/beannameurlhandlermappingcontroller"
class="com.datang.controller.BeanNameUrlHandlerMappingController"></bean>
<context:component-scan base-package="com.datang"/>
</beans>

RequestMappingHandlerMapping
RequestMappingHandlerMapping处理器映射器,需要使用@Controller注册bean然后对方法上带有@RequestMapping注解的方法,注册为处理器映射器。

package com.datang.controller;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-02-07 18:04
* @notify
* @version 1.0
*/
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class RequestMappingHandlerMappingController {
@RequestMapping(value = "requestmappinghandlermappingcontroller",method = RequestMethod.GET)
public ModelAndView handler() {
System.out.println("我是根据RequestMappingHandlerMapping找到的controller,但是显然的,我是错误的,因为我返回的是null");
return null;
}
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- 根据beanName找到处理器 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean id="/beannameurlhandlermappingcontroller"
class="com.datang.controller.BeanNameUrlHandlerMappingController"></bean>
<!-- 根据@RequestMapping 找到处理器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<context:component-scan base-package="com.datang"/>
</beans>

HandlerAdapter
HandlerAdapter的作用是,执行handlerMapping找到的处理器。处理器有多种,显然的每一种的处理器所执行的方法都不一样。比如上边的两种,继承自Controller的处理器方法固定的是handleRequest()而使用@RequestMapping注解的则方法名不同。所以处理器适配器的存在是有必要的。
SimpleControllerHandlerAdapter
SimpleControllerHandlerAdapter这个处理器适配器是配合BeanNameUrlHandlerMapping处理器映射器使用的。定义了SimpleControllerHandlerAdapter便不会有其他的适配器。这里请求beannameurlhandlermappingcontroller会成功,但是请求requestmappinghandlermappingcontroller是不成功的。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- 根据beanName找到处理器 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean id="/beannameurlhandlermappingcontroller"
class="com.datang.controller.BeanNameUrlHandlerMappingController"></bean>
<!-- 根据@RequestMapping 找到处理器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!-- 配合BeanNameUrlHandlerMapping使用 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<context:component-scan base-package="com.datang"/>
</beans>


RequestMappingHandlerAdapter
RequestMappingHandlerAdapter这个处理器适配器是配合RequestMappingHandlerMapping处理器映射器使用的。这次就可以正确访问requestmappinghandlermappingcontroller。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- 根据beanName找到处理器 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean id="/beannameurlhandlermappingcontroller"
class="com.datang.controller.BeanNameUrlHandlerMappingController"></bean>
<!-- 根据@RequestMapping 找到处理器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!-- 配合BeanNameUrlHandlerMapping使用 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!-- 配合RequestMappingHandlerMapping使用 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<context:component-scan base-package="com.datang"/>
</beans>

ViewResolver
InternalResourceViewResolver
根据Controller返回的逻辑视图名,寻找物理视图。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- 根据beanName找到处理器 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean id="/beannameurlhandlermappingcontroller"
class="com.datang.controller.BeanNameUrlHandlerMappingController"></bean>
<!-- 根据@RequestMapping 找到处理器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!-- 配合BeanNameUrlHandlerMapping使用 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!-- 配合RequestMappingHandlerMapping使用 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<!-- 视图解析器,配置视图的前缀和后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsps/"/>
<property name="suffix" value=".jsp"/>
</bean>
<context:component-scan base-package="com.datang"/>
</beans>

package com.datang.controller;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-02-07 21:09
* @notify
* @version 1.0
*/
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class ReturnJsp {
@RequestMapping(value = "returnjsp", method = RequestMethod.GET)
public String handler() {
return "page1";
}
}

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>我是page1</h1>
</body>
</html>

定义多个视图解析器(源码解析)
我们可以定义多个视图解析器,属性order规定视图解析器的优先级。DispatcherServlet试图从所有的视图解析器中匹配视图,如果匹配成功则不继续匹配。那么就让我们来碰碰壁吧。可以看出第二个路径出错了,问题就在于,它好像根本没有走我们的第二个视图解析器呀!看源码吧。(不想看源码,直接看解决办法。)

package com.datang.controller;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-02-07 21:09
* @notify
* @version 1.0
*/
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.InternalResourceView;
@Controller
public class ReturnJsp {
@RequestMapping(value = "returnjsp", method = RequestMethod.GET)
public String handler() {
return "page1";
}
@RequestMapping(value = "returnjsp2", method = RequestMethod.GET)
public String handler2() {
return "page2";
}
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- 根据beanName找到处理器 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean id="/beannameurlhandlermappingcontroller"
class="com.datang.controller.BeanNameUrlHandlerMappingController"></bean>
<!-- 根据@RequestMapping 找到处理器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!-- 配合BeanNameUrlHandlerMapping使用 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!-- 配合RequestMappingHandlerMapping使用 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<!-- 视图解析器,配置视图的前缀和后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsps/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="1"/>
</bean>
<!-- 第二个视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsps2/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="2"/>
</bean>
<context:component-scan base-package="com.datang"/>
</beans>



入口类,就从DispatcherServlet开始(因为我已经debug了好久才找到从这么看最直观!!!)
















<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- 根据beanName找到处理器 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean id="/beannameurlhandlermappingcontroller"
class="com.datang.controller.BeanNameUrlHandlerMappingController"></bean>
<!-- 根据@RequestMapping 找到处理器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!-- 配合BeanNameUrlHandlerMapping使用 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!-- 配合RequestMappingHandlerMapping使用 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<!-- 视图解析器,配置视图的前缀和后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 使用自己的viewClass -->
<property name="viewClass" value="com.datang.view.MyInternalResourceView"/>
<property name="prefix" value="/WEB-INF/jsps/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="1"/>
</bean>
<!-- 第二个视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 使用自己的viewClass -->
<property name="viewClass" value="com.datang.view.MyInternalResourceView"/>
<property name="prefix" value="/WEB-INF/jsps2/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="2"/>
</bean>
<context:component-scan base-package="com.datang"/>
</beans>

package com.datang.view;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-02-08 14:49
* @notify
* @version 1.0
*/
import org.springframework.web.servlet.view.InternalResourceView;
import java.io.File;
import java.util.Locale;
public class MyInternalResourceView extends InternalResourceView {
@Override
public boolean checkResource(Locale locale) throws Exception {
//这里,super.getUrl就是prefix+viewName+suffix
File file = new File(this.getServletContext().getRealPath("/") + super.getUrl());
// 判断该页面是否存在
return file.exists();
}
}





来源:https://www.cnblogs.com/zumengjie/p/12269916.html
