0

ここで説明されているように、Spring MVC で Freemarker テンプレートローダーをラップして、html ページでデフォルトのエスケープを行います。

したがって、java.io.Reader からのコンテンツを自分の文字列でラップする必要があります。それを読み取ったり、文字列に変換したり、自分自身を実装したりしないでください。一般的な共通ライブラリにWrappingReaderまたは com.google.common.io.MultiReader (公開されていない) に似たクラスはありますか?

私の実装:

import com.google.common.io.CharStreams;
import com.google.common.io.InputSupplier;

...

private final TemplateLoader delegate;

@Autowired
public HtmlEscapingTemplateLoader(ResourceLoader resourceLoader)
{
    delegate = new SpringTemplateLoader(resourceLoader, "/WEB-INF/templates/");
}

@Override
public Reader getReader(Object templateSource, String encoding) throws IOException
{
    // collecting readers
    Reader prologue = new StringReader("<#escape x as x?html>");
    Reader originalReader = delegate.getReader(templateSource, encoding);
    Reader epilogue = new StringReader("</#escape>");

    // concatenating readers
    return merge(prologue, originalReader, epilogue);
}


protected Reader merge(Reader prologue, Reader originalReader, Reader epilogue) throws IOException
{
    return CharStreams.join(
            Arrays.asList(new ReaderSupplier(prologue), new ReaderSupplier(originalReader), new ReaderSupplier(
                    epilogue))).getInput();
}

private static class ReaderSupplier
        implements InputSupplier<Reader>
{

    private final Reader reader;

    public ReaderSupplier(Reader reader)
    {
        this.reader = reader;
    }

    @Override
    public Reader getInput() throws IOException
    {
        return reader;
    }

}

私が使用する CharStreams は、@com.google.common.annotations.Beta としてマークされています。では、CharStreams を使用せずに、より確実な方法で書き直すことはできますか?

4

2 に答える 2

1

グアバの寄稿者はこちら。...わかった。

@Beta「完全にテストされていない」または「広く使用されていない」という意味ではありません。 これが意味する唯一のことは、API をフリーズする準備ができているかどうか確信が持てないということです。これは、ライブラリを開発している場合、または後で Guava のバージョンをアップグレードする予定がある場合にのみ問題になります。(また、正直なところ、API とCharStreams同じくらい安定しています...)@Beta

インターフェイスの要点全体を無効にするクラスを持つべきではありません。この特定のケースでは、s を渡す代わりに、s を渡す必要があります。この特定のケースでは、 は sを生成するan を返すため、このユース ケースに完全に適合します。ReaderSupplierInputSupplierReaderInputSupplier<Reader>CharStreams.newReaderSupplier(String)InputSupplierStringReader

いずれにせよ、私の完全な実装は次のようになります。

static final String prologue = "<#escape x as x?html>";
static final String epilogue = "</#escape>";

// ideally you shouldn't be passing around Readers at all
// the point of InputSupplier, etc. is that you should never get direct access
// to the Reader directly, so you don't have to track whether it's closed or not
public InputSupplier<Reader> getReaderSupplier(
    final Object templateSource, final String encoding) {
  return CharStreams.join(
    CharStreams.newReaderSupplier(prologue),
    new InputSupplier<Reader>() {
      public Reader getInput() {
        return delegate.getReader(templateSource, encoding);
      }
    },
    CharStreams.newReaderSupplier(epilogue));
 }
于 2012-07-19T14:06:28.597 に答える