SpringMVC之源码分析--Controller(二)

大黑 2019-06-27

概述

上篇文章主要分析了Spring提供的Controller及抽象类AbstractController,本章继续分析其具体的几个实现类。

本系列文章是基于Spring5.0.5RELEASE。

ServletForwardingController

  • 作用

    ServletForwardingController实现的功能是将接收的用户请求转发给你一个命名的servlet去处理,该命名servlet需在部署描述(web.xml)文件中定义。

  • 源码

    由继承关系ServletForwardingController继承AbstractController抽象类,并实现模板方法handleRequestInternal,完成将接收的请求进行转发,源码如下:

    /**
     *实现父类模板方法
     */
    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
    
        ServletContext servletContext = getServletContext();
        Assert.state(servletContext != null, "No ServletContext");
        // 获取部署文件中定义的servlet,传入servelet name参数。
        RequestDispatcher rd = servletContext.getNamedDispatcher(this.servletName);
        if (rd == null) {
            throw new ServletException("No servlet with name '" + this.servletName + "' defined in web.xml");
        }
    
        // 判断是否是include请求
        if (useInclude(request, response)) {
            // 是include请求,继续使用include
            rd.include(request, response);
            if (logger.isDebugEnabled()) {
                logger.debug("Included servlet [" + this.servletName +
                        "] in ServletForwardingController '" + this.beanName + "'");
            }
        }
        else {
            // 非include请求,进行转发
            rd.forward(request, response);
            if (logger.isDebugEnabled()) {
                logger.debug("Forwarded to servlet [" + this.servletName +
                        "] in ServletForwardingController '" + this.beanName + "'");
            }
        }
    
        return null;
    }
  • 实战

    编写servlet,代码如下:

    public class ForwardServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.getWriter().write("hello ForwardServlet...");
        }
    }

    配置部署描述文件,代码如下:

    <servlet>
        <servlet-name>forwording</servlet-name>
        <servlet-class>com.github.dalianghe.controller.ForwardServlet</servlet-class>
      </servlet>

    配置Spring配置文件,代码如下:

    <bean name="/forwardToServlet" class="org.springframework.web.servlet.mvc.ServletForwardingController">
        <property name="servletName" value="forwording"/>
    </bean>
  • 测试

    编写完以上代码,启动系统并请求,地址:http://localhost:8086/forwardToServlet,请求将通过ServletForwardingController转发到Servlet进行处理,最终在界面如图:

    SpringMVC之源码分析--Controller(二)

ParameterizableViewController

  • 作用

    根据参数的逻辑视图名直接选择需要展示的视图,只支持GET、HEAD请求方法类型。

  • 源码

    核心处理方法源码如下:

    /**
     *处理请求
     */
    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        //获取配置的viewName属性
        String viewName = getViewName();
        
        ... ...
    
        // 把视图逻辑名设置到ModelAndView中
        if (getViewName() != null) {
            modelAndView.setViewName(viewName);
        }
        else {
            modelAndView.setView(getView());
        }
        return (isStatusOnly() ? null : modelAndView);
    }
  • 实战

    因为此部分使用jsp视图,故需引入jstl支持,在pom文件中添加依赖坐标,如下:

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

    在Spring配置文件中,添加相关配置,如下:

    <!-- jsp视图映射与视图解析 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <!-- 视图前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!-- 视图后缀 -->
        <property name="suffix" value=".jsp"/>
    </bean>
    <!-- 配置ParamterizableViewController -->
    <bean name="/helloJSP" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
        <property name="viewName" value="test"/>
    </bean>

    在WEB-INF下新建jsp文件夹及test.jsp文件,文件内容如下:

    <html>
        <head>
            <title>My Frist JSP</title>
        </head>
        <body>
            <h1>hello jsptest</h1>
        </body>
    </html>
  • 测试

    启动服务,进行测试,访问/helloJSP,结果如下:

    SpringMVC之源码分析--Controller(二)

    测试结果表明,我们并未编写Controller,通过配置接口实现通过Spring转发到视图。

UrlFilenameViewController

  • 作用

    作用与ParameterizableViewController一样,但功能强大很多,支持模式匹配。

  • 示例

    以下提供两种示例,可做为参考,如下:

    <!-- 可以匹配/test1/xxx,其中xxx为视图真实名称
        最终的查找路径为:/WEB-INF/jsp/xxx.jsp
                Spring 视图解析前缀+视图名称+视图解析后缀
     -->
    <bean name="/test1/*" class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
    <!-- 可以匹配/test1/xxx/yyy,xxx为目录,yyy为视图真实名称 -->
    <bean name="/index2/**" class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>

    本类不做演示了,有兴趣的可以自行验证,有问题可以留言或加入qq群反馈。

总结

本章主要分析并演示了Spring提供Controller接口的实现类,目前来说用的很多,有些我也不是很明白,有讲解错误的地方,还望指定,真心的希望能与大家一起进步。

最后创建了qq群方便大家交流,可扫描加入,同时也可加我qq:276420284,共同学习、共同进步,谢谢!

SpringMVC之源码分析--Controller(二)

相关推荐