8无脚本的JSP
8.1在JSP页面使用动作元素
<jsp:useBean id="person" class="foo.Person" scope="request" />
<jsp:getProperty name="person" property="name" />
如果useBean找不到一个叫person的bean就会自己创建这样一个类,来看看生成的servlet中的代码:
foo.Person person = null;
synchronized (request){
person=(foo.Person)_jspx_page_context.getAttribute("person",PageContext.REQUEST_SCOPE);
if(person == null){
person = new foo.Person();
_jspx_page_context.setAttribute("person",PageContext.REQUEST_SCOPE);
}
}
但是通过这个方式创建的bean是没有属性值的,我们需要使用另一个动作元素setProperty
<jsp:useBean id="person" class="foo.Person" scope="request" />
<jsp:setProperty name="person" property="name" value="Fred" />
但是这样的命令当已经存在一个bean后,会将该属性的值替换,而没有达到创建一个新的属性的目的。
为了达到这一目的,我们需要使用有体的useBean:
<jsp:useBean id="person" class="foo.Person" scope="request">
<jsp:setProperty name="person" property="name" value="Fred" />
</jsp:useBean>
这时执行中间设置属性的代码是有条件的执行的,只有当在指定scopr和id中没有这个bean才会在创建这个bean之后,执行setProperty代码
若存在这个的bean就不会执行这个代码了
再看看生成的servlet中的代码
foo.Person person = null;
synchronized (request){
person=(foo.Person)_jspx_page_context.getAttribute("person",PageContext.REQUEST_SCOPE);
if(person == null){
person = new foo.Person();
_jspx_page_context.setAttribute("person",PageContext.REQUEST_SCOPE);
org.apache.jasper.runtime.JspRuntimeLibrary.introspecthelper(_jspx_page_context.finAttribute("person"),"name","Fred",null,null.false);
}
}
8.2多态的bean引用
给useBean添加一个type属性
<jsp:useBean id="person" type="foo.Person" class="foo.Employee" scope="page" />
这样生成的servlet代码是:
foo.Person person = null;
if(person == null){
person = new foo.Employee();
...
}
Class必须是type的一个子类或是实现
若使用了type但是没有class,会出现2种情况:
指定的scope和id中已经存在这样的bean,不会报错
否则会报错bean person not found with scope
8.3 param属性
<html><body>
<form action="TestBean.jsp">
name:<input type="text" name="useName">
ID#:<input type="text" name="userID">
<input type="submit">
</form>
</body></html>
Testbean.jsp
<jsp:useBean id="person" type="foo.Person" class="foo.Emploee">
<jsp:setProperty name="person" property="name" param="userName" />
</jsp:useBean>
在Testbean页面中不用脚本就可以获取传递来的属性值。
更好的解决方式
确保表单输入的请求参数名与bean中的属性名相同,如果是这样你就不必再<jsp:setProperty>标记中指定param属性了。如果指定了property,但是没有指定value或是param,就是通知容器,要从右匹配名的请求参数中得到值。
若Employee中有2个属性,name和userID,则可以这样写
<jsp:useBean id="person" type="foo.Person" class="foo.Emploee">
<jsp:setProperty name="person" property="name" /> 这里什么都没有
</jsp:useBean>
还能更好的解决方式
确保表单输入的所有的请求参数名与bean中的属性名相同
<jsp:useBean id="person" type="foo.Person" class="foo.Emploee">
<jsp:setProperty name="person" property="*" /> 这里一个*号解决所有问题
</jsp:useBean>
8.3TLD的对应关系
有函数的类
package foo;
public class DiceRoller{
public static int rollDice(){
return (int)((Math.random()*6)+1);
}
}
标记库的描述文件 TLD
<?xml...>
<taglib xmlns=....>
<tlib-version>1.2</tlib-version>
<uri>DiceFunction</uri>
<function>
<name>rollIt</name>
<function-class>foo.DiceRoller</function-class>
<function-aignature>int rollDice()</function-aignature>
</function>
</taglib>
jsp页面
<%@ taglib prefix="mm" uri="DiceFunction"%>
<html><body>
${mm:rollIt()}
</html></body>
注意这三个文件中的对应关系