解読する<br>ソース
<c:out>タブは、ページで属性値を出力するためのもので、<c:out>を使用する場合、JSPページでは、以下のように宣言されます.
<%@taglib prefix="c"uri=「http://java.sun.com/jsp/jstl/core「%>
このラベルのc.tldファイルでは、outラベルについて以下のように定義されています.
coreラベルライブラリの説明:
JSTL 1.1 core library JSTL core 1.1 c
outラベルの説明は以下の通りです.
<<>out org.apache.taglibs.standard.tag.tag.co re.OutTag //ラベルの処理類 value //属性に対応する名称は、上のクラスが提供するsetterと一致します. true //この属性を提供する必要があるかどうかを示します. <この属性値は運転時に決定できるという意味です. >default false true escapeXml false true
org.apache.taglibs.standard.tag.rt.co re.OutTagのソースコードは以下の通りです.
<%@taglib prefix="c"uri=「http://java.sun.com/jsp/jstl/core「%>
このラベルのc.tldファイルでは、outラベルについて以下のように定義されています.
coreラベルライブラリの説明:
outラベルの説明は以下の通りです.
<<>
org.apache.taglibs.standard.tag.rt.co re.OutTagのソースコードは以下の通りです.
package org.apache.taglibs.standard.tag.rt.core;
import org.apache.taglibs.standard.tag.common.core.OutSupport;
public class OutTag extends OutSupport {
// for tag attribute
public void setValue(Object value) { // value ( ),
this.value = value; //value , value
}
// for tag attribute
public void setDefault(String def) { //
this.def = def; //def , default
}
// for tag attribute
public void setEscapeXml(boolean escapeXml) { //
this.escapeXml = escapeXml; // , escapeXml
}
}
OutTag類はOutSupport類を継承しています.OutSupport類のソースは以下の通りです.package org.apache.taglibs.standard.tag.common.core;
import java.io.IOException;
import java.io.Reader;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class OutSupport extends BodyTagSupport {
protected Object value; // tag attribute
protected String def; // tag attribute
protected boolean escapeXml; // tag attribute
private boolean needBody; // non-space body needed?
public OutSupport() {
super();
init();
}
// resets local state
private void init() {
value = def = null;
escapeXml = true;
needBody = false;
}
// Releases any resources we may have (or inherit)
public void release() {
super.release();
init();
}
//
public int doStartTag() throws JspException {
needBody = false; // reset state related to 'default'
this.bodyContent = null;
try {
// print value if available; otherwise, try 'default'
if (value != null) { // value null
out(pageContext, escapeXml, value); // value
return SKIP_BODY; //
} else {
// if we don't have a 'default' attribute, just go to the body
if (def == null) { // value , def ( default )
needBody = true; //
return EVAL_BODY_BUFFERED;//
}
// if we do have 'default', print it
if (def != null) { // default
out(pageContext, escapeXml, def); // def
}
return SKIP_BODY; //
}
} catch (IOException ex) {
throw new JspException(ex.toString(), ex);
}
}
//
public int doEndTag() throws JspException {
try {
if (!needBody)
return EVAL_PAGE;
// trim and print out the body
if (bodyContent != null && bodyContent.getString() != null)
out(pageContext, escapeXml, bodyContent.getString().trim());
return EVAL_PAGE;
} catch (IOException ex) {
throw new JspException(ex.toString(), ex);
}
}
public static void out(PageContext pageContext,
boolean escapeXml,
Object obj) throws IOException {
JspWriter w = pageContext.getOut();//
if (!escapeXml) { //escapeXml false, xml
// write chars as is
if (obj instanceof Reader) { // Reader ,
Reader reader = (Reader)obj;
char[] buf = new char[4096];
int count;
while ((count=reader.read(buf, 0, 4096)) != -1) {
w.write(buf, 0, count); //
}
} else {
w.write(obj.toString()); // ,
}
} else { //escapeXml true, xml ( : < <,> > )
// escape XML chars
if (obj instanceof Reader) {
Reader reader = (Reader)obj;
char[] buf = new char[4096];
int count;
while ((count = reader.read(buf, 0, 4096)) != -1) {
writeEscapedXml(buf, count, w); //
}
} else {
String text = obj.toString();
writeEscapedXml(text.toCharArray(), text.length(), w); //
}
}
}
// xml (<,>,",',&)
private static void writeEscapedXml(char[] buffer, int length, JspWriter w) throws IOException{
int start = 0; //
for (int i = 0; i < length; i++) {
char c = buffer[i];
if (c <= Util.HIGHEST_SPECIAL) { // ASCII HIGHEST_SPECIAL=Ox3e, > ASCII
char[] escaped = Util.specialCharactersRepresentation[c]; //
if (escaped != null) {// ,
// add unescaped portion
if (start < i) { //
w.write(buffer,start,i-start);
}
// add escaped xml
w.write(escaped); //
start = i + 1; //
}
}
}
// add rest of unescaped portion
if (start < length) {
w.write(buffer,start,length-start);
}
}
}
例:<%
// Reader
String str = "Hello String";
request.setAttribute("str",str);
//Reader
Reader reader = new CharArrayReader("Hello Reader".toCharArray());
request.setAttribute("reader",reader);
%>
<c:out value="${requestScope.str}"/> //Hello String
<c:out value="${requestScope.reader}" /> //Hello Reader
<c:out value="${requestScope.str}" default="defalut value"/> //Hello String
<c:out value="${null}" default="default value"/> //default value
<c:out value="${null}" >default body content value</c:out> //default body content value
<c:out value="<b>Hello</b>"/> //<b>Hello</b>
<c:out value="<b>Hello</b>" escapeXml="true"/> //<b>Hello</b>
<c:out value="<b>Hello</b>" escapeXml="false"/> // Hello
<c:out value="${null}" escapeXml="true" default="<b>Hello</b>"/> //<b>Hello</b>
<c:out value="${null}" escapeXml="false" default="<b>Hello</b>"/> // Hello
<c:out value="${null}" escapeXml="false"><b>Hello</b></c:out>// Hello
<c:out value="${null}" escapeXml="true"><b>Hello</b></c:out>//<b>Hello</b>