初识springmvc之核心组件详解(二)

一、springmvc核心组件详解

1.1、HandlerMapping处理器映射器

  • 主要作用:给前端控制器返回一个HandlerExecutionChain 对象(包含一个Handler (后端控制器)对象、多个HandlerInterceptor 拦截器)对象。
1、BeanNameUrlHandlerMapping
<!—beanName Url映射器 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

将后端处理器(控制器)bean的id或name作为请求的url;是springmvc处理器映射器的默认配置值

2、SimpleUrlHandlerMapping
 <!--注册自定义处理器-->
    <bean id="indexController" name="/index.action" class="com.chuan.hello.controller.MyController"/>

    <!--配置处理器映射器-->
    <!--<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>-->

    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/index1.action">indexController</prop>
                <prop key="/index2.action">indexController</prop>
            </props>
        </property>
         <!-- order值越小,映射处理器优先级越高 -->
		<property name="order" value="1"></property>
   </bean>

SimpleUrlHandlerMapping处理器映射器可以定义多个url映射到一个后端控制器
order的值表示映射处理器的优先级,值越小处理器优先级越高;值不能为零和负数,如果为零或者负数则表示当前处理器没有设置order值,该处理器映射器的优先级最低。

1.2、HandlerAdapter处理器适配器

1、SimpleControllerHandlerAdapter简单控制器处理器适配器

配置如下:

<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />

如果使用此适配器,那么后端控制器都必须实现org.springframework.web.servlet.mvc.Controller接口

2、HttpRequestHandlerAdapterHTTP请求处理器适配器

配置如下:

<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>

controller实现如下:

publicclass MyHandler implements HttpRequestHandler {

    @Override
    public void handleRequest(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        request.setAttribute("msg", "HelloWorld!");
        request.getRequestDispatcher("/WEB-INF/jsp/home.jsp").forward(request, response);
    }
}

注意:
1)使用HttpRequestHandlerAdapterHTTP请求处理器适配器,则后端控制器必须实现org.springframework.web.HttpRequestHandler接口
2)从代码可知此后端控制器不返回ModelAndView了,只能通过request和response进行相应的请求响应

1.3、controller后端控制器

1、AbstractController
  • 最简单的控制器,一个类只能处理一个请求,实现抽象类中的handleRequestInternal方法
public class UserController extends AbstractController  {
    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg","hello word!!!");
        modelAndView.setViewName("home");
        return modelAndView;
    }
}
  • AbstractController 实现了controller接口,是controller接口的子类
public abstract class AbstractController extends WebContentGenerator implements Controller {
    private boolean synchronizeOnSession;

    public AbstractController() {
        this(true);
    }

    public AbstractController(boolean restrictDefaultSupportedMethods) {
        super(restrictDefaultSupportedMethods);
        this.synchronizeOnSession = false;
    }

  • 设置处理器的请求方式
<bean id="homeController" class="com.chuan.hello.controller.UserController">
        <property name="supportedMethods" value="POST"/>
    </bean>

这样设置以后,该处理器将不会处理get方式的请求。

2、MultiActionController
  • 可以将多个请求处理方法放入一个控制器(controller类)中。
public class PeopleController extends MultiActionController {

      public ModelAndView doFirst(HttpServletRequest request, HttpServletResponse response){
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("msg","hello doFirst!!!");
            modelAndView.setViewName("home");
            return modelAndView;
      }

      public ModelAndView doSecond(HttpServletRequest request, HttpServletResponse response){
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("msg","hello doSecond!!!");
            modelAndView.setViewName("home");
            return modelAndView;
      }

}
  • springmvc.xml配置
 <!--注册自定义处理器-->
    <bean id="indexController" class="com.chuan.hello.controller.MyController"/>

    <bean id="homeController" class="com.chuan.hello.controller.UserController">
        <property name="supportedMethods" value="POST"/>
    </bean>

    <bean id="peopleController" class="com.chuan.hello.controller.PeopleController"/>

    <!--配置处理器映射器-->
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="urlMap">
            <map>
                <entry key="/index1.action" value="indexController"/>
                <entry key="/index2.action" value="indexController"/>
                <entry key="/home.action" value="homeController"/>
                <entry key="/*.action" value="peopleController"/>
            </map>
        </property>
    </bean>
  • 测试结果
    在这里插入图片描述
    在这里插入图片描述

  • 为什么通过访问MultiActionController 实现类中的 方法名+.action 的路径能够直接处理相应的请求
    点开MultiActionController 的源码进行分析:

public class MultiActionController extends AbstractController implements LastModified {
   public final void setMethodNameResolver(MethodNameResolver methodNameResolver) {
        this.methodNameResolver = methodNameResolver;
    }

    public final MethodNameResolver getMethodNameResolver() {
        return this.methodNameResolver;
    }

MultiActionController 默认使用了MethodNameResolver ,方法名解析器的作用是决定URL到Controller.method()的映射,比如URI 为http://localhost:8080/hello/doSecond.action对应的就是PeopleController 类中的doSecond方法; springmvc 中默认的方法名解析器InternalPathMethodNameResolver

  • PropertiesMethodNameResolver:根据请求URL匹配method
    springmvc.xml中的配置
 <bean id="peopleController" class="com.chuan.hello.controller.PeopleController">
        <!--注册propertiesMethodNameResolver方法名解析器-->
        <property name="methodNameResolver" ref="propertiesMethodNameResolver"/>
    </bean>

    <!--配置处理器映射器-->
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="urlMap">
            <map>
                <entry key="/index1.action" value="indexController"/>
                <entry key="/index2.action" value="indexController"/>
                <entry key="/home.action" value="homeController"/>
                <entry key="/*.action" value="peopleController"/>
            </map>
        </property>
    </bean>

    <!--配置方法名解析器-->
    <bean id="propertiesMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
        <property name="mappings">
            <props>
                <prop key="/my_first.action" >doFirst</prop>
                <prop key="/my_second.action" >doSecond</prop>
            </props>
        </property>
    </bean>

测试结果:
在这里插入图片描述

  • ParameterMethodNameResolver:根据请求参数匹配method
    spring.xml:
<bean id="peopleController" class="com.chuan.hello.controller.PeopleController">
        <!--注册parameterMethodNameResolver方法名解析器-->
        <property name="methodNameResolver" ref="parameterMethodNameResolver"/>
    </bean>

    <!--配置处理器映射器-->
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="urlMap">
            <map>
                <entry key="/index1.action" value="indexController"/>
                <entry key="/index2.action" value="indexController"/>
                <entry key="/home.action" value="homeController"/>
                <entry key="/*.action" value="peopleController"/>
            </map>
        </property>
    </bean>

    <!--配置方法名解析器-->
    <bean id="parameterMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
        <!-- 指定参数key映射方法,即xxx?method=sb,执行Controller的sb() -->
        <property name="paramName" value="method"/>
    </bean>

paramName是设置方法请求URL的参数名,如下图,请求路径中参数method的值对应的就是controller中的doFirst方法
注意:paramName如果不设置,则其默认的value值为action,则下图的请求路径变为:http://localhost:8080/hello/dofirst.action?action=doFirst
测试结果:
在这里插入图片描述

1.4、视图解析器

  • springmvc默认的视图解析器:InternalResourceViewResolver内部资源视图解析器;InternalResourceViewResolver用于将提供的URI解析为实际URI,允许映射网页与请求。
1、BeanNameViewResolver
  • 定义:根据视图bean的名字解析当前的视图
  • springmvc.xml配置:
<bean id="testController" class="com.chuan.hello.controller.TestController"/>

    <!--配置处理器映射器-->
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="urlMap">
            <map>
                <entry key="/index1.action" value="indexController"/>
                <entry key="/index2.action" value="indexController"/>
                <entry key="/home.action" value="homeController"/>
                <entry key="/*.action" value="peopleController"/>
                <entry key="/test.action" value="testController"/>
            </map>
        </property>
    </bean>

    <!--配置内部资源视图-->
    <bean id="home" class="org.springframework.web.servlet.view.JstlView">
        <property name="url" value="/WEB-INF/jsp/home.jsp"/>
    </bean>

    <!--配置外部资源视图:天猫-->
    <bean id="tmall" class="org.springframework.web.servlet.view.RedirectView">
        <property name="url" value="http://jx.tmall.com/"/>
    </bean>

    <!--配置外部资源视图:京东-->
    <bean id="jd" class="org.springframework.web.servlet.view.RedirectView">
        <property name="url" value="www.jd.com"/>
    </bean>
  • TestController处理器
public class TestController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        return new ModelAndView("tmall");
    }
}
  • 测试 http://localhost:8080/hello/test.action
    在这里插入图片描述
  • 404找不到资源原因:
    id名为tmall的视图属于外部路径资源,而springmvc默认的视图解析器InternalResourceViewResolver为内部资源视图解析器,无法解析外部资源的视图请求。
  • 解决方案:在springmvc.xml配置中加入BeanNameViewResolver的配置
    <!--配置视图解析器-->
    <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
2、XmlViewResolver: xml文件视图解析器
  • 自定义一个myViews.xml文件,并将上述例子中的三个视图拷贝到此文件中
 <!--配置内部资源视图-->
    <bean id="home" class="org.springframework.web.servlet.view.JstlView">
        <property name="url" value="/WEB-INF/jsp/home.jsp"/>
    </bean>

    <!--配置外部资源视图:天猫-->
    <bean id="tmall" class="org.springframework.web.servlet.view.RedirectView">
        <property name="url" value="http://jx.tmall.com/"/>
    </bean>

    <!--配置外部资源视图:京东-->
    <bean id="jd" class="org.springframework.web.servlet.view.RedirectView">
        <property name="url" value="www.jd.com"/>
    </bean>
  • springmvc.xml配置
 <bean id="testController" class="com.chuan.hello.controller.TestController"/>

    <!--配置处理器映射器-->
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="urlMap">
            <map>
                <entry key="/index1.action" value="indexController"/>
                <entry key="/index2.action" value="indexController"/>
                <entry key="/home.action" value="homeController"/>
                <entry key="/*.action" value="peopleController"/>
                <entry key="/test.action" value="testController"/>
            </map>
        </property>
    </bean>

    <!--配置视图解析器-->
    <bean class="org.springframework.web.servlet.view.XmlViewResolver">
        <!--注册要解析的xml视图文件-->
        <property name="location" value="classpath:myViews.xml"/>
    </bean>

location:注册要解析的xml视图文件

  • 测试
    在这里插入图片描述
3、ResourceBundleViewResolver: 配置文件视图解析器
  • 自定义views.properties
tmall.(class)=org.springframework.web.servlet.view.RedirectView
tmall.url=http://jx.tmall.com/
jd.(class)=org.springframework.web.servlet.view.RedirectView
jd.url=www.jd.com
home.(class)=org.springframework.web.servlet.view.JstlView
home.url=/WEB-INF/jsp/home.jsp
  • springmvc 配置
 <bean id="testController" class="com.chuan.hello.controller.TestController"/>

    <!--配置处理器映射器-->
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="urlMap">
            <map>
                <entry key="/index1.action" value="indexController"/>
                <entry key="/index2.action" value="indexController"/>
                <entry key="/home.action" value="homeController"/>
                <entry key="/*.action" value="peopleController"/>
                <entry key="/test.action" value="testController"/>
            </map>
        </property>
    </bean>

    <!--配置视图解析器-->
    <bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
        <property name="basename" value="views"/>
    </bean>
  • 测试结果
    在这里插入图片描述
4、视图解析器优先级
  • 使用场景:多个视图解析器共存
  • 自定义OrderController
public class OrderController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        return new ModelAndView("orderView");
    }
}
  • springmvc.xml配置文件
  <bean id="orderController" class="com.chuan.hello.controller.OrderController"/>

    <!--配置处理器映射器-->
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="urlMap">
            <map>
                <entry key="/order.action" value="orderController"/>
            </map>
        </property>
    </bean>

    <!--配置外部资源视图:京东-->
    <bean id="orderView" class="org.springframework.web.servlet.view.RedirectView">
        <property name="url" value="www.jd.com"/>
    </bean>

    <!--配置视图解析器-->
    <!--注册配置文件视图解析器:ResourceBundleViewResolver-->
    <bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
        <property name="basename" value="views"/>
    </bean>

    <!--注册xml文件视图解析器:XmlViewResolver-->
    <bean class="org.springframework.web.servlet.view.XmlViewResolver">
        <!--注册要解析的xml视图文件-->
        <property name="location" value="classpath:myViews.xml"/>
    </bean>

    <!--注册BeanNameViewResolver视图解析器-->
    <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>

如上所示BeanNameViewResolver对应的是京东的url地址

  • myViews.xml配置
<!--配置内部资源视图-->
    <bean id="orderView" class="org.springframework.web.servlet.view.JstlView">
        <property name="url" value="/WEB-INF/jsp/home.jsp"/>
    </bean>

如上所示XmlViewResolver对应的是内部资源home.jsp的url地址

  • views.properties配置
orderView.(class)=org.springframework.web.servlet.view.RedirectView
orderView.url=http://jx.tmall.com/

如上所示ResourceBundleViewResolver对应的是内部资源天猫的url地址

  • 测试: http://localhost:8080/hello/order.action
    在这里插入图片描述
    测试结果表明在不设置order的值得情况下,ResourceBundleViewResolver视图解析器的优先级别最高;
    为什么ResourceBundleViewResolver的优先级最高?
    因为在springmvc.xml文件中ResourceBundleViewResolver最先配置;
    默认情况下在视图解析器的order值未设定时,视图解析器的优先级由springmvc配置文件中各个视图解析器的配置顺序决定。

    • 给上述三个视图解析器设置order值

<!--注册配置文件视图解析器:ResourceBundleViewResolver-->
    <bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
        <property name="basename" value="views"/>
        <property name="order" value="5"/>
    </bean>

    <!--注册xml文件视图解析器:XmlViewResolver-->
    <bean class="org.springframework.web.servlet.view.XmlViewResolver">
        <!--注册要解析的xml视图文件-->
        <property name="location" value="classpath:myViews.xml"/>
        <property name="order" value="1"/>
    </bean>

    <!--注册BeanNameViewResolver视图解析器-->
    <bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
        <property name="order" value="3"/>
    </bean>
  • 再次测试: http://localhost:8080/hello/order.action
    返回的是工程内部的视图home.jsp,即此时优先级最高的是XmlViewResolver
  • 总结:order的值表示映射处理器的优先级,值越小处理器优先级越高; 值不能为零和负数,如果为零或者负数则表示当前处理器没有设置order值,则该处理器映射器的优先级最低。

1.5、DispatcherServlet.properties配置文件

1、DispatcherServlet.properties源码
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver

org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
	org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
	org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver

org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator

org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping

org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
	org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
2、配置文件详解

DispatcherServlet.properties是springmvc默认加载的配置文件,里面声明了springmvc核心组件的默认值,
HandlerMapping处理器映射器的默认值为BeanNameUrlHandlerMappingRequestMappingHandlerMapping
视图解析器的默认值就是InternalResourceViewResolver
处理器适配器的默认值是HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、RequestMappingHandlerAdapter

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值