新年新项目,过完年以后进入新项目,这个项目是一个招投标的项目对于这个项目目前的总结是:人少活多工期紧,每天加班到9点,甚至这两周连周六都奉献给项目组了。不过在这个项目里还是学习了一些东西,这次要写的创建taglib就是其中一个内容。
百度一下查找taglib的相关内容,发现有高手总结创建taglig的作用和步骤,言简意赅
1、JSP标签技术始于JSP1.1
2、作用:代码复用;JSP页面简洁
3、四个步骤:
A、创建实现标签功能的JAVA类(Bean或Servlet)
B、创建标签库的描述文件
C、web.xml中添加标签库说明
D、JSP页面中添加标签库说明,及使用标签
4、标签可以访问的数据范围类型:application;session;request;page.
创建taglib就是为了能代码重复使用,一次完成只要引用直接完成功能。不过在创建taglib的时候还遇到一些问题。一会在跟大家说。
创建taglib,以及引用taglib大概分为3个步骤:.
1.创建标签的处理类
2.创建标签库描述文件
3.在JSP文件中引入标签库,然后插入标签,例如:<pims:approveRecord/>
创建标签处理类要常见一个后缀为tld的xml文件然后写两个类,两个类分别继承Component和ComponentTagSupport。
首先创建一个tld文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>2.2.3</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>tangs</short-name>
<uri>/tangs</uri>
<display-name>pims i18n tangs</display-name>
<tag>
<name>approeveComment</name>
<tag-class>com.ibm.pims.framework.server.tags.comment.CommentTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>id</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
<tag-class>com.ibm.pims.framework.server.tags.approverecord.ApproveRecordTag</tag-class>这里是调用taglib要访问的java类,一定要是继承ComponentTagSupport的java类,否则你就等着报错吧!
attribute中required表示该属性是是否必须输入的,如果是true你不输入那就不好意思,在你访问页面的时候就会报错,错误也简单好解决就是提示你的标签有问题
先创建第一个java类:
Component是struts下的一个接口
首先生成get和set方法 ALT+Shift +S 快速生成
package com.ibm.pims.framework.server.tags.comment;
import java.io.Writer;
import org.apache.struts2.components.Component;
import com.opensymphony.xwork2.util.ValueStack;
public class CommentComponent extends Component {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public CommentComponent(ValueStack stack) {
super(stack);
}
@Override
public boolean start(Writer writer){
try{
StringBuffer input = new StringBuffer();
input.append("<div class=\"m_tab_tit\"><div class=\"m_tab_tit_td1\"></div><div class=\"m_tab_tit_td2\">审批意见</div>" +
"<div class=\"m_tab_tit_td4\"></div><div class=\"m_tab_tit_td5\" title=\"收起\"></div></div><div class=\"m_tab_div0\">" +
"<table cellspacing=\"0\" cellpadding=\"0\" class=\"m_tab_cont04 tab_shadow\"><tr><th><textarea name=\""+id+"\" " +
"id=\""+ id +"\" " +
"class=\"inp05\"></textarea></th>" +
"</tr><tr><td><input type=\"button\" name=\"approveButton\" id=\"approveButton\" value=\"同意\" class=\"btn01\"/>" +
"<input type=\"button\" name=\"rejectButton\" id=\"rejectButton\" value=\"拒绝\" class=\"btn01\"/></td></tr></table></div>");
writer.write( input.toString() );
}catch(Exception e){
throw new RuntimeException( "Construct <tangs:button /> error" );
}
return super.start(writer);
}
}
这个类里面一定要有
public ApproveRecordComponent(ValueStack stack){
super(stack);
}
同时start就是要把你想输出的内容通过java代码拼接出来
在写一个java类继承
package com.ibm.pims.framework.server.tags.comment;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.views.jsp.ComponentTagSupport;
import com.opensymphony.xwork2.util.ValueStack;
public class CommentTag extends ComponentTagSupport {
/**
*
*/
private static final long serialVersionUID = -6129157604108002975L;
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public Component getBean(ValueStack arg0, HttpServletRequest arg1,
HttpServletResponse arg2) {
// TODO Auto-generated method stub
return new CommentComponent(arg0);
}
@Override
protected void populateParams() {
super.populateParams();
CommentComponent commentComponent = (CommentComponent)getComponent();
commentComponent.setId(id);
}
}
同样get和set方法不要落下。tagsupport必须要有的方法:
@Override
public Component getBean(ValueStack arg0,HttpServletRequest req, HttpServletResponse resp){
return new ApproveRecordComponent(arg0);
}
@Override
protected void populateParams() {
super.populateParams();
ApproveRecordComponent approveRecordCompent =(ApproveRecordComponent)getComponent();
approveRecordCompent.setBizTypeNum(bizTypeNum);
approveRecordCompent.setFormId(formId);
approveRecordCompent.setOrgId(orgId);
approveRecordCompent.setTableId(tableId);
approveRecordCompent.setTaskStatus(taskStatus);
approveRecordCompent.setApproveStatus(approveStatus);
}
这两个方法是和和compnent类交互用的。
当然在start方法里面如果你只替换部分内容的话还可以读取配置文件,读取配置文件
String template = readTemplate(this.getClass().getResource("").getPath() +"approver.template");
private String readTemplate(String tplPath){
StringBuffer sb = new StringBuffer();
try{
BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(tplPath),"UTF-8"));
String line = "";
while((line = br.readLine()) != null){
sb.append(line + enter); // 加一个换行符
}
br.close();
}catch(Exception e){
e.printStackTrace();
}
return sb.toString();
}
通过readTemplate方法可以读取到配置文件中的内容然后在通过replace方法进行替换要替换的部分,比如我要替换配置文件中的{tableId}就可以使用下面的语句template=template.replace("${tableId}", tableIdString);
我模板中的 ${tableId}
<div class="shtit02">${hiddenInput}<img src="../images/btn049.png" />审查记录</div>
${tableId}
<div style="clear:both;width:100%;"></div>
替换模板一定不要忘记读取的文件一定要等于替换后的文件,这样保证你的模板都是最新的。
开始的时候说我在写taglib的时候遇到一个问题,这个问题就是我在模板中配置了jqgrid,想通过replace方法替换一些jqgrid的必要属性然后jqgrid在进行ajax请求,但是后来发下替换完成以后即使jqgrid的url正确他也不会访问,自己分析原因是jqgrid在 window.ready的时候去访问url,但是我的taglib是在window.onload的时候去调用所以即使替换了jqgrid的url他也不会访问。这是我没有考虑清楚页面加载先后顺序造成的错误。可以通过(http://www.cnblogs.com/mofish/archive/2011/05/09/2041052.html)这篇文章了解一下onload和ready的加载前后
如果我们想要这种访问url的可以写一个js文件,把taglib的传入的值放入隐藏域中,通过读取隐藏域的值去设置参数,这样在标签读取的时候就可以加载了。
有图有真相我把我的一个简单的taglib效果图展示一下:
通过<pims:approeveComment id="approvalComments" />
这就是<pims:approeveComment id="approvalComments" />的效果
复杂点的效果:
当然这个也是一句话搞定的,不过越复杂的东西你就越要考虑清楚,这样封装起来才不会漏洞百出。
创建taglib我就讲这么多,taglib就是为了封装一些公用的方法让代码能复用,如果谁有公共的方法可以使用一下。