likes
comments
collection
share

InternalResourceView 实现服务器端(SSI)渲染与转发技术

作者站长头像
站长
· 阅读数 24

InternalResourceView来实现SSI功能(Server Side Includes, SSI)是一种将一个文件的内容包含到另一个文件的机制。本次通过一个内容管理系统(CMS)的案例,探讨动态地合并和渲染页面。

类结构设计

InternalResourceView  实现服务器端(SSI)渲染与转发技术

业务说明:

内容管理系统允许编辑者创建和维护网页内容。为了提高内容的可重用性和一致性,编辑者希望能够在不同页面中包含共有的部分,如页眉、页脚或导航菜单。

核心技术:

  1. 服务器端包含(SSI) :一种将一个源文件的内容包含到另一个源文件的技术。
  2. InternalResourceView:Spring MVC中的一个视图,用于渲染服务器内部资源,如JSP页面。
  3. JSP:JavaServer Pages,一种动态网页技术,允许在HTML中嵌入Java代码。

工作流程图:

InternalResourceView  实现服务器端(SSI)渲染与转发技术

核心代码:

1. Spring MVC配置(Java配置方式):

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.View;
    import org.springframework.web.servlet.view.InternalResourceView;

    @Configuration
    public class WebConfig {

        @Bean
        public View internalResourceView() {
            return new InternalResourceView();
        }
    }

2. JSP页面(包含SSI):

    <!DOCTYPE html>
    <html>
    <head>
        <title>Dynamic Page</title>
        <!-- 包含共有的头部资源 -->
        <%@ include file="header.jsp" %>
    </head>
    <body>
        <h1>${pageTitle}</h1>
        <!-- 页面主要内容 -->
        <p>${pageContent}</p>
        <!-- 包含共有的底部资源 -->
        <%@ include file="footer.jsp" %>
    </body>
    </html>

3. 控制器:

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.servlet.ModelAndView;

    @Controller
    public class PageController {

        @GetMapping("/page")
        public ModelAndView getPage() {
            ModelAndView modelAndView = new ModelAndView("dynamicPage");
            modelAndView.addObject("pageTitle", "Sample Page");
            modelAndView.addObject("pageContent", "This is a sample page content.");
            return modelAndView;
        }
    }

4. InternalResourceView 实现转发核心代码

protected void renderMergedOutputModel(
        Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
    // 将模型对象作为请求属性公开,这样在渲染视图时可以访问这些数据。
    exposeModelAsRequestAttributes(model, request);

    // 如果有辅助工具,也作为请求属性公开。
    exposeHelpers(request);

    // 准备用于渲染的请求分发器的路径,这通常是一个JSP页面的路径。
    String dispatcherPath = prepareForRendering(request, response);

    // 获取目标资源的RequestDispatcher,这通常是一个JSP页面。
    RequestDispatcher rd = getRequestDispatcher(request, dispatcherPath);
    if (rd == null) {
        // 如果无法获取RequestDispatcher,抛出异常。
        throw new ServletException("Could not get RequestDispatcher for [" + getUrl() +
                "]: Check that the corresponding file exists within your web application archive!");
    }

    // 判断是否已经是包含请求或响应已经被提交。
    // 如果是,则使用include来包含视图,否则使用forward来转发请求。
    if (useInclude(request, response)) {
        response.setContentType(getContentType()); // 设置响应的Content-Type。
        if (logger.isDebugEnabled()) {
            logger.debug("Including [" + getUrl() + "]");
        }
        // 使用RequestDispatcher的include方法将模型数据包含到客户端请求中。
        rd.include(request, response);
    }
    else {
        // 如果不是包含请求,使用forward方法将请求转发到视图。
        // 注意:被转发的资源应该自己确定内容类型。
        if (logger.isDebugEnabled()) {
            logger.debug("Forwarding to [" + getUrl() + "]");
        }
        rd.forward(request, response);
    }
}

优点:

  1. 提高内容重用性:通过SSI,共有的页面部分可以在多个页面中重用,减少了代码重复。
  2. 简化页面维护:更新共有部分时,只需修改一个文件,所有引用该部分的页面都会自动更新。
  3. 动态内容生成:SSI可以在服务器端动态地将内容插入到页面中,提高了内容的灵活性。
  4. 与Spring MVC的无缝集成InternalResourceView与Spring MVC集成,简化了配置和使用。
转载自:https://juejin.cn/post/7385776238789083145
评论
请登录