こんにちは。kkです。
タイトル通りですが、例えばこんな場面を想定します。
・表示するデータをどこかから取得
・改行が含まれている
・XSS対策でエスケープ処理を行う
jstlのc:outだと、エスケープと同時に出力するので改行をbrに置換できず、先に置換するとエスケープされてしまいます。
サーバ側でエスケープ処理を行い、改行をbrタグに置換した上で画面へ渡す場合、画面側がサーバの処理を意識する必要があります。(c:out等で出力すると結局brタグもエスケープされる)
fn:splitで改行毎に分割し、個々にc:outしつつbrを入れていく…というのも考えられますが、下記のような問題(仕様)もありちょっとかっこ悪いです。
[Java]JSTLで改行でのsplit()ができない問題 そこで、jstlのc:outのような感覚で、簡易に使えるカスタムタグがあると便利かなーと思い、作成してみました。 処理内容についてはコード内のコメントを参照してください。 ここでは、jstlライブラリ内のOutSupportを使用しています。
- NewLineToBRTag.java
- NewLineToBRTag.tld
[xml] <?xml version="1.0" encoding="UTF-8" ?> <taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1"> <tlib-version>1.0</tlib-version> <short-name>br</short-name> <tag> <name>newLineToBr</name> <tag-class>jp.co.opentone.tag.NewLineToBRTag</tag-class> <body-content>empty</body-content> <attribute> <name>value</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>escapeXml</name> <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib> [/xml]
使えるようにするため、web.xmlに追加します。
- web.xml
[xml] <jsp-config> <taglib> <taglib-uri>http://opentone.co.jp/sample/tag/NewLineToBR</taglib-uri> <taglib-location>/WEB-INF/tags/NewLineToBRTag.tld</taglib-location> </taglib> </jsp-config> [/xml]
ちゃんと出来てますね。
テスト用に書いたコードはこちら。
※例によって、以前作成したSpringのサンプルプロジェクトの流用
→SpringIDEで始めるSpringMVCプロジェクト
- HomeController.java
[java] @Controller public class HomeController { private static final Logger logger = LoggerFactory.getLogger(HomeController.class); private static final String CR = "\r"; private static final String LF = "\n"; private static final String CRLF = "\r\n"; /** * Simply selects the home view to render by returning its name. */ @RequestMapping(value = "/", method = RequestMethod.GET) public String home(Locale locale, Model model) { logger.info("Welcome home! The client locale is {}.", locale); Date date = new Date(); DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale); String formattedDate = dateFormat.format(date); // 改行を含む文字列の作成 String value = "CR改行" + CR + "LF改行" + LF + "CRLF改行" + CRLF + "<i>最後の行</i>"; model.addAttribute("serverTime", formattedDate ); model.addAttribute("testNewLineValue", value ); return "home"; } } [/java]
- home.jsp
[html] <%@ page pageEncoding="UTF-8" %> <%@ page session="false" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://opentone.co.jp/sample/tag/NewLineToBR" prefix="br" %> <html> <head> <title>Home</title> </head> <body> <h1> Hello world! </h1> <P> The time on the server is ${serverTime}. </P> <h2>【改行を含む文字列表示】</h2> <P> ${testNewLineValue} </P> <h2>【br変換テスト】</h2> <P><br:newLineToBr value="${testNewLineValue}"/></P> </body> </html> [/html]
1行ですっきり書けました。(名前長いけど…)