Spring MVC framework: exception handling, operation process, and spring integration

Exception handling

Spring MVC handles program exceptions through HandlerExceptionResolver, including Handler mapping, data binding, and exceptions that occur when the target method is executed.

The implementation class of HandlerExceptionResolver provided by SpringMVC Let's
look at one of the implementation classes

DefaultHandlerExceptionResolver

Just take a look at the processing method inside, the return value is ModelAndView.
Insert picture description here
We can also customize the exception handling, which is configured in the mvc configuration file.

	<!-- prop的key写异常类型的全限类名,prop的值就是一个视图名称,出现对应异常要跳转的页面
		而且会将异常信息默认放在request作用域里面,在页面可以${
    
    exception}进行取值
	 -->
	<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
		<property name="exceptionMappings">
			<props>
				<prop key="java.lang.NullPointerException">error</prop>
			</props>
		</property>
	</bean>

Run process

Insert picture description here

1)	用户向服务器发送请求,请求被SpringMVC 前端控制器 DispatcherServlet捕获;
2)	DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI):
判断请求URI对应的映射
①	不存在:
再判断是否配置了mvc:default-servlet-handler:
如果没配置,则控制台报映射查找不到,客户端展示404错误
如果有配置,则执行目标资源(一般为静态资源,如:JS,CSS,HTML)
②	存在:
执行下面流程
3)	根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;
4)	DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。
5)	如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法【正向】
6)	提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)方法,处理请求。在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
①	HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
②	数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
③	数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
④	数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
7)	Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
8)	此时将开始执行拦截器的postHandle(...)方法【逆向】
9)	根据返回的ModelAndView(此时会判断是否存在异常:如果存在异常,则执行HandlerExceptionResolver进行异常处理)选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet,根据Model和View,来渲染视图
10)	在返回给客户端时需要执行拦截器的AfterCompletion方法【逆向】
11)	将渲染结果返回给客户端

Spring and SpringMVC integration

Reasons for integration

If it is not integrated, the problem that arises:
not integrated, then all the components that spring needs to manage are handed over to springmvc to manage
this is not impossible, but this way springmvc manages too many things, commonly used spring transactions, data sources, mybatis The object of this kind of springmvc is too messy, so it is integrated

Where to integrate in springmvc

When mvc writes the control layer, it needs to automatically assemble the things in the service layer, and the things in the service and dao layers are managed by the spring container, so the conclusion is that spring must be integrated and loaded when the entire project starts. Okay,
so what is the method to load when the project starts?
The loading order of the web is: finally the servlet is loaded for the first visit, and the last one is loaded when the project starts, and then the first one is the filter, and then the listener
is in front Choose between and listener, but the filter will create a new object every time it is accessed, but the spring container does not need to create so many, only one needs to be created.
So we choose listener (listening event)
in the servletContext when the project starts When it will be created, then we will write a listener to monitor the life cycle of the servletContext, and create a spring container when it is created.
For example

package com.listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringListener implements ServletContextListener 
{
    
    
    public SpringListener() 
    {
    
    
    	
    }
    public void contextDestroyed(ServletContextEvent arg0)  
    {
    
    
    	
    }

    public void contextInitialized(ServletContextEvent sce)  
    {
    
    
    	ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
    	/*
    	 * 有时候我们的bean不是在配置文件里面配置好就行,虽然会自动装配
    	 * 但是有时候我们还需要在手动获得bean对象来操作
    	 * 所以将ac放在request作用域里面,就能获取了
    	 */
    	ServletContext servletContext = sce.getServletContext();
    	servletContext.setAttribute("ac", ac);
    }
}

Then configure it in web.xml

  <!-- 
  		如果只加了listener这个标签加载别人写好的ContextLoaderListener
  		那么就会去默认的位置去加载,就是WEB-INF下面的applicationContext.xml
  		那么想配置contextConfigLocation这个参数,可以利用<context-param>标签
  		这个是servletcontext的参数设置,项目启动时就会加载这个标签,是最先加载的
   -->
  <listener>
  		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
  		<param-name>contextConfigLocation</param-name>
  		<param-value>classpath:spring.xml</param-value>
  </context-param>

You can also use hints to create

   <!-- needed for ContextLoaderListener -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring.xml</param-value>
	</context-param>

	<!-- Bootstraps the root web application context before servlet initialization -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

Guess you like

Origin blog.csdn.net/qq_43416157/article/details/106691555