JSP 中类似 PHP 的输出缓冲(让子模板影响主模板)

问题描述 投票:0回答:4

在我的网站中,我有一个主 JSP 模板:

<html>
 <body>
  <nav>...</nav>
  <tiles:insertAttribute name="body" />
  <footer>...</footer>
 </body>
</html>

以及多个页面模板:

<p>This is content</p>

现在我希望页面模板能够定义一些Javascript和CSS包含,因此页面模板必须在主模板的

<head>
之前执行。

在 PHP 中,我可以为此使用输出缓冲:

<? ob_start()
   include $slave;
   $body = ob_get_clean(); ?>
<html>
 <head>
 <? foreach($javascripts as $script) ?>
     <script src="<?=$script?>" />
 <? endforeach ?>
 <body>
  <nav>...</nav>
  <?=$body?>
  <footer>...</footer>
 </body>
</html>

JSP中有类似的技术吗?或者还有另一种方式来实现我所需要的? 我在 Spring MVC 3 + Apache Tiles 中使用它

java jsp spring-mvc tiles2
4个回答
2
投票

1) 启用核心标签库

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

2) 抓取并打印内容

<c:set var="content">You grab content</c:set>
<c:out value="${content}" />

1
投票

您可以在图块定义中定义一个附加属性(默认为空),然后将该属性插入布局页面的标题部分。这就是 Tiles 应该如何工作的。

或者您可以使用 Sitemesh 而不是 Tiles,它会执行您的建议:它使用一个缓冲响应的过滤器,然后通过提取其一些元素并将它们放入模板中来装饰响应。

我想可以同时使用 Sitemesh 和 Tiles,但恕我直言,它会变得有点太复杂了。


0
投票

我找到了解决问题的另一种解决方案。

我扩展了我的主模板:

<head>
<tiles:insertAttribute name="head" defaultValue="" />
</head>

我有一个生成图块定义 XML 文件的脚本(已经有了)。如果子模板(例如

view.jsp
)需要额外的 CSS 或 Javascript,我将创建一个单独的文件
view_head.jsp
,其中包含正确的包含内容,并且脚本会将属性
head
设置到该文件。


0
投票

实际上还有另一种方法可以使用自定义 JspWriter 实现来实现此目的:

// Replace the default output by a buffered output
JspWriter out_default = out;
JspWriterStringBuffer out_buffer = new JspWriterStringBuffer();
out = out_buffer;

// all sub-templates which use "out" will now write to the custom buffer.
// call your custom code, include templates, whatever... here
<%@ include file="sample.jsp" %>

// restore the default output
out = out_default;

JspWriterStringBuffer需要重写相当多的默认函数,但最终实现非常简单。只需将所有内容写入类变量并添加 getter 即可:

import java.io.IOException;
import javax.servlet.jsp.JspWriter;

/**
 * Purpose of this class is to implement a dummy JspWriter that simply
 * writes added information to a class variable 
 * which can be queried using getBuffer().
 */
public class JspWriterStringBuffer extends JspWriter {
    String buffer = "";

    public JspWriterStringBuffer() {
        // Note: the chosen buffer size in this example is just random
        super(12345678, false);
    }

    public String getBuffer() {
        return buffer;
    }

    @Override
    public int getRemaining() {
        return bufferSize - buffer.length();
    }

    @Override
    public void clear() {
        buffer = "";
    }

    @Override
    public void clearBuffer() {
        buffer = "";
    }

    @Override
    public void close() {

    }

    @Override
    public void flush() {

    }

    @Override
    public void print(Object x) {
        buffer += x.toString();
    }

    @Override
    public void println(Object x) {
        print(x);
        println();
    }

    @Override
    public void print(String x) {
        buffer += x;
    }

    @Override
    public void println(String x) {
        print(x);
        println();
    }

    @Override
    public void print(char x) {
        buffer += x;
    }

    @Override
    public void println(char x) {
        print(x);
        println();
    }

    @Override
    public void print(char[] x) {
        buffer += x;
    }

    @Override
    public void println(char[] x) {
        print(x);
        println();
    }

    @Override
    public void print(double x) {
        buffer += x;
    }

    @Override
    public void println(double x) {
        print(x);
        println();
    }

    @Override
    public void print(float x) {
        buffer += x;
    }

    @Override
    public void println(float x) {
        print(x);
        println();
    }

    @Override
    public void print(long x) {
        buffer += x;
    }

    @Override
    public void println(long x) {
        print(x);
        println();
    }

    @Override
    public void print(int x) {
        buffer += x;
    }

    @Override
    public void println(int x) {
        print(x);
        println();
    }

    @Override
    public void print(boolean x) {
        buffer += Boolean.toString(x);
    }

    @Override
    public void println(boolean x) {
        print(x);
        println();
    }

    @Override
    public void println() {
        buffer += System.lineSeparator();
    }

    @Override
    public void newLine() {
        println();
    }

    @Override
    public void write(char[] chars, int i, int i1) throws IOException {
        for (int j = i; j <= i1; j++) {
            print(chars[j]);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.