spring mvc

1 篇文章 0 订阅
1 篇文章 0 订阅

spring mvc 调用流程

在这里插入图片描述

springmvc handler和Adapter的关系

  • 下面只是一个示意关系,并不是一一对应的关系
handlerMappinghandlerAdapter描述
ControllerSimpleControllerHandlerAdapter标准控制器,返回ModelAndView
HttpRequestHandlerHttpRequestHandlerAdapter处理业务不返回ModelAndView
ServletSimpleServletHandlerAdapterservlet的处理方式
HandlerMethodRequestMappingHandlerAdapter@requestMapping对应方法处理
  • handlerMapping继承关系图
    handlerMapping
  • handlerAdapter 继承关系图
    handlerAdapter
SimpleUrlHandlerMapping的xml配置
  • 由于在DispatcherServlet.properties中默认没有配置SimpleUrlHandlerMapping所以这里需要在xml文件中配置
  • xml配置内容如下:
<bean id="helloController" class="com.demo.mvc.controller.HelloController"/>
//处理url类型的
    <bean
            class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/hello">helloController</prop>
            </props>
        </property>
    </bean>
    //公共的视图解析配置
    <bean  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/page/" />
        <property name="suffix" value=".jsp" />
        <property name="viewClass"
                  value="org.springframework.web.servlet.view.JstlView" />
    </bean>
  • Controller类中,HelloController需要实现Controller接口,也就是能够使Controller满足是controller满足
BeanNameUrlHandlerMapping的配置
  • 在xml中直接配置映射
<bean id="/beanName.do"
          class="com.demo.mvc.controller.BeanNameHandler"/>
  • Controller中实现的Adapter,可以实现Contoller或者HttpRequestHandlerHttpServlet,例如:
public class BeanNameHandler implements HttpRequestHandler 
RequestMappingHandlerMapping和RequestMappingHandlerAdapter的使用
  • 以上的处理url中一个Controller只能处理一个url,但是在RequestMappingHandlerMapping通过注解的方式可以实现同一个Controller可以处理多个url,
//xml的配置
<context:component-scan base-package="com.demo.mvc.controller"/>
//Controller类的配置
@Controller
@RequestMapping("/say")
public class RequestMappingController {

    @RequestMapping("/hello")
    @ResponseBody
    /**
    这里如果需要返回视图返回的类型需要设置为ModelAndView,如果返回的json,可以配置@ResponseBody注解,否则如果返回String不加@ResponseBody注解会出现内部forward,出现找不到适配器的错误
    */
    public String sayHello() {
        return "你好";
    }
}

View

  • adapter处理完成之后,通过org.springframework.web.servlet.DispatcherServlet#render方法来处理视图

在这里插入图片描述

HandlerExceptionResolver 异常处理

  • 在spring mvc中需要配置
    • 实现接口HandlerExceptionResolver
    • 在xml文件中配置实现的类
  • 在spring boot中配置公共的异常处理类
@RestControllerAdvice
public class GlobalException {
    @ExceptionHandler(value = BusinessException.class)
    @ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
    public String myException(HttpServletRequest request) {
        System.out.println(request.getContextPath());
        return "服务器内部异常";
    }
}

HandlerInterceptor 拦截器

  • 拦截器和filter的区别
    • filter是servlet提供的功能,拦截器是spring提供的功能
    • filter不能使用spring的对象,而拦截器可以使用spring中的对象
    • filter是在请求之前进行过滤,而拦截器可以在请求前后都可以进行处理
  • spring mvc的实现方式
    • 实现接口HandlerInterceptor
    • 在xml中配置实现的类
<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.demo.mvc.controller.MyInterceptor">
            </bean>
        </mvc:interceptor>
    </mvc:interceptors>
  • 在spring-boot中的实现
/**
实现WebMvcConfigurer可以添加拦截器,增加返回的消息的处理等功能

*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private MyInterceptor myInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor).addPathPatterns("/*");
    }
}
  • 拦截器是在获取HandlerMapping的时候加入拦截器的

注解功能实现的原理( mvc:annotation-driven/)

  • 接口NamespaceHandler的实现MvcNamespaceHandler会加载AnnotationDrivenBeanDefinitionParser来加载mapping和adapter,springmvc默认的用了BeanNameUrlHandlerMapping以及SimpleControllerHandlerAdapterHttpRequestHandlerAdapter两个适配器

上下文注入

  • 在spring mvc启动的过程中,会初始化servelt的时候会加载init方法,这个时候会把spring的上下文注入进来,并且会初始化springmvc相关的类
protected WebApplicationContext createWebApplicationContext(@Nullable ApplicationContext parent) {
		//设置为父上下文
		wac.setParent(parent);
		String configLocation = getContextConfigLocation();
		if (configLocation != null) {
			wac.setConfigLocation(configLocation);
		}
		//初始化mvc的上下文
		configureAndRefreshWebApplicationContext(wac);
		return wac;
	}
  • 上下文最终保存在FrameworkServlet的方法initWebApplicationContext中,属性名为:
//保存的属性名前缀,最终在后面加上dispather,做为context的key
public static final String SERVLET_CONTEXT_PREFIX = FrameworkServlet.class.getName() + ".CONTEXT.";

protected WebApplicationContext initWebApplicationContext() {
		WebApplicationContext rootContext =
				

		if (this.publishContext) {
			// Publish the context as a servlet context attribute.
			String attrName = getServletContextAttributeName();
			getServletContext().setAttribute(attrName, wac);
		}

		return wac;
	}
  • 这里的上下文和org.springframework.web.context.ContextLoaderListener的区别
    • ContextLoaderListener会把spring的上面设置到servletContext的root属性中去`servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
    • FrameServletinitWebApplicationContext的方法中会设置父上下文为spring的上下文,而且会加载spring mvc本身的上下文信息
      `

HttpMethodMapping加载

  • 在servlet的init方法调用的时候会注册url跟handler关系到HttpMethod中去,在调用的时候通过反射的方式来调用相关的方法
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值