`
maria3905
  • 浏览: 22765 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

freemarker中的directive

 
阅读更多

//加载自定义标签,主要是在html的模班页面使用,在freemarkerUtil中的initCfg()方法中

freemarkerCfg.setSharedVariable("demo", new DemoDirective());

//客服

 

freemarkerCfg.setSharedVariable("custList", new CustServiceDirective());

public class CustServiceDirective extends BaseDirective implements TemplateDirectiveModel{
	private StoreCustServiceService storeCustServiceService;
	public CustServiceDirective(){
		init("storeCustServiceService");//主要是用于调用service中的逻辑处理方法
	}
	@Override
	public void execute(Environment env, Map params, TemplateModel[] loopVars,
			TemplateDirectiveBody body) throws TemplateException, IOException {
		StoreCustService storeCustService=new StoreCustService();
		String traAgId = getParam(params, "traAgId");//获取参数的操作
		if (traAgId != null) {
			storeCustService.setTraAgId(Integer.parseInt(traAgId));
		}
		String status= getParam(params, "status");
		if(status!=null){
			storeCustService.setStatus(Integer.parseInt(status));
		}
		Writer out=env.getOut();
		if(body!=null){
			//设置循环变量
			if(loopVars !=null && loopVars.length>0){
				List custList=storeCustServiceService.findCustList(storeCustService," sequence ", "true".equals(getParam(params,"cache"))?true:false);//获取到需要的list
				if(custList!=null && custList.size()>0){//循环输出
					for (int i = 0; i<custList.size(); i++) {
						loopVars[0]=new BeanModel(custList.get(i), new BeansWrapper());
						if(loopVars.length>1){
							loopVars[1]=new SimpleNumber(i);
						}
						body.render(out);
					}
					
				}
			}
		}
		
		
	}
	

}

 继承的BaseDirective的写法

/**
 * <p>
 * Description: 自定义标签共同的功能
 * </p>
 */
public class BaseDirective extends Base {

	/**
	 * 获得参数
	 * 
	 * @param params
	 * @param name
	 * @return
	 */
	public String getParam(Map params, String name) {
		String value = "";
		if (params.get(name) != null
				&& params.get(name).toString().length() > 0) {
			value = params.get(name).toString();
		}
		return value;
	}

	/**
	 * 获得参数并传递默认值
	 * 
	 * @param params
	 * @param name
	 * @param defaultValue
	 * @return
	 */
	public String getParam(Map params, String name, String defaultValue) {
		String value = defaultValue;
		if (params.get(name) != null
				&& params.get(name).toString().length() > 0) {
			value = params.get(name).toString();
		}
		return value;
	}

	/**
	 * 获得int参数并传递默认值
	 * 
	 * @param params
	 * @param name
	 * @param defaultValue
	 * @return
	 */
	public int getParamInt(Map params, String name, int defaultValue) {
		int value = defaultValue;
		if (params.get(name) != null
				&& params.get(name).toString().length() > 0) {
			try {
				value = Integer.parseInt(params.get(name).toString());
			} catch (Exception e) {
			}
		}
		return value;
	}

	/**
	 * 获得数据
	 * 
	 * @param params
	 * @param name
	 * @return
	 * @throws TemplateModelException
	 */
	public String getData(Environment env, String name)
			throws TemplateModelException {
		String value = "";
		if (env.getDataModel().get(name) != null
				&& env.getDataModel().get(name).toString().length() > 0) {
			value = env.getDataModel().get(name).toString();
		}
		return value;
	}

	/**
	 * 获得数据并传递默认值
	 * 
	 * @param params
	 * @param name
	 * @param defaultValue
	 * @return
	 * @throws TemplateModelException
	 */
	public String getData(Environment env, String name, String defaultValue)
			throws TemplateModelException {
		String value = defaultValue;
		if (env.getDataModel().get(name) != null
				&& env.getDataModel().get(name).toString().length() > 0) {
			value = env.getDataModel().get(name).toString();
		}
		return value;
	}
}

 在html页面的应用

<@custList traAgId="${traAgId}" status="1";cuList>//status是参数,cuList是循环变量
				<li>
				<#if cuList.gender??>
					<#if cuList.gender== 1>
						<div class="avatar"><img width="65" height="66" src="../img/ta/men_100X100.jpg"></div>
					<#elseif cuList.gender== 2>
						<div class="avatar"><img width="65" height="66" src="../img/ta/woman_100X100.jpg"></div>
					</#if>
				</#if>
					
						<p class="s14">${cuList.realName}</p>
					<div class="i_onlinecs_btnc c_b">
					
					
					<a href="tencent://message/?uin=${cuList.qq}&site=www.xx.com&menu=yes" target="_blank" rel="nofollow">
					<img src="http://wpa.qq.com/pa?p=1:${cuList.qq}:4" border="0" align="bottom" class="pic"></a>
					</div>
				</li>
			</@custList>

 还有一种循环方法

if(body!=null){
			//设置循环变量
			if(loopVars !=null && loopVars.length>0){
				List<TravelAgency> travelList=travelAgencyService.find(travelAgency, order,limit);
				loopVars[0]=new ArrayModel(travelList.toArray(), new BeansWrapper());
				body.render(out);
						
				}
			}

 在html中就是,这种写法能判断是否有值,可以针对这个做处理

<@travelList cityCode="${cityCode}" limit="0,10";traList>
					<#if traList?exists && traList?size != 0>
						<#list traList as trList>
						<dl>
							<dd><a href="${contextPath}www/store.do?traAgCode=${trList.traAgCode?default('')}">${trList.companyInfo.companyName!""}</a></dd>
						</dl>
						</#list>
					<#else>
						<dl>
							<dd>暂时没有旅行社添加!</dd>
						</dl>
						
					</#if>
					</@travelList>

 还有一种多参数的做法

效果如图

 

//多个循环变量的情况以及涉及到freemarker的分页做法
public class TailPageDirective  extends  BaseDirective implements TemplateDirectiveModel{
	public TailPageDirective(){
		init("tailProService");
	}
	@Override
	public void execute(Environment env, Map params, TemplateModel[] loopVars,
			TemplateDirectiveBody body) throws TemplateException, IOException {
		if(body!=null){
			//设置循环变量
			if(loopVars !=null && loopVars.length>0){
				String orderby=getParam(params, "orderby"," used desc");
				//显示数量
				int row=getParamInt(params, "row", 10);//给参数的默认值
				//标题长度
				int titleLen=getParamInt(params, "titleLen",0);
				//当前第几页
				int page=getParamInt(params, "page", 1);

				String action=getParam(params, "action");
				
				HashMap<String, String> paramMap=new HashMap<String, String>();
				if(tailPromotion==null){
					tailPromotion=new TailPromotion();
				}
				
				String cityCode = getParam(params, "cityCode");
				if (StringUtil.isNotEmpty(cityCode)) {
					tailPromotion.setDepartCityCode(cityCode);
				}
				
				
				tailPromotion.setTrStatus(0);
				tailPromotion.setStatus(Byte.valueOf("3"));
				String transportMeans=getParam(params, "transportMeans");//获取的是标签内传递的参数
//env.getDataModel().get("transportMeans")获取的是地址栏中的参数				if(env.getDataModel().get("transportMeans")!=null && env.getDataModel().get("transportMeans").toString()!=""){
					transportMeans=env.getDataModel().get("transportMeans").toString();
					tailPromotion.setTransportMeans(transportMeans);
					paramMap.put("transportMeans", transportMeans);
					action=action+"&transportMeans="+transportMeans;
				}else if(StringUtils.isNotEmpty(transportMeans)){
					tailPromotion.setTransportMeans(transportMeans);
					
					paramMap.put("transportMeans", transportMeans);
					
					action=action+"&transportMeans="+transportMeans;
					
				}
				
				//升降序的做法
				String order =" sequence ";
				String sequence=getParam(params, "sequence");
				if(env.getDataModel().get("sequence")!=null && env.getDataModel().get("sequence").toString()!=""){
					
					sequence =env.getDataModel().get("sequence").toString();
					
					if("1".equals(sequence)){
						
						order=" lowest_price desc ";
					
					}else if("2".equals(sequence)){
					
						order=" lowest_price ";
					
					}
					
					paramMap.put("sequence", sequence);
					
					action=action+"&sequence="+sequence;
				
				}else if(StringUtils.isNotEmpty(sequence)){
					
					if("1".equals(sequence)){
						
						order=" lowest_price desc ";
					
					}else if("2".equals(sequence)){
					
						order=" lowest_price ";
					
					}
					paramMap.put("sequence", sequence);
					
					action=action+"&sequence="+sequence;
					
				}
				int count=tailProService.countByExample(tailPromotion);
				FreemarkerPager pager=new FreemarkerPager();//分页的做法
				pager.setCurrPage(page);
				pager.setTotalCount(count);
				pager.setPageSize(row);
				pager.setAction(action);
				paramMap.put("tcount", String.valueOf(count));
				pager.setParams(paramMap);
				
				List<TailPromotion> trpList=tailProService.findTP(tailPromotion,orderby,page, row);
				//这个是ajax的做法
				TreeMap<Integer, Integer> daysMap=new TreeMap<Integer, Integer>();//旅游天数
				HashMap trPropertyMap=new HashMap();//团的属性
				TreeMap<Integer, String> priceMap=new TreeMap<Integer, String>();//价格
				if(trpList!=null && trpList.size()>0){
					for(int i=0;i<trpList.size();i++){
						Integer day=trpList.get(i).getTourDays();
						if(day!=null && day!=0){
							daysMap.put(day,day);
						}
						Byte trPro=trpList.get(i).getTrProperty();
						if(trPro!=null){
							trPropertyMap.put(trPro, trPro);
						}
						Integer lowPrice=trpList.get(i).getLowestPrice();
						if(lowPrice!=null && lowPrice!=0){
							if(lowPrice<100){
								priceMap.put(100, "100元以下");
							}else if(lowPrice>100 && lowPrice<=300){
								priceMap.put(300, "100-300元");
							}else if(lowPrice>300 && lowPrice<=500){
								priceMap.put(500, "300-500元");
							}
						}
						
						
						
					}
				}
				
				//搜索条件 放到map里面
				Map<String,Map> sMap=new HashMap<String,Map>();
				
				sMap.put("daysMap", daysMap);
				
				sMap.put("trPropertyMap", trPropertyMap);
				
				sMap.put("priceMap", priceMap);
				
				
				if(loopVars.length==1){
					loopVars[0]=new MapModel(sMap,new BeansWrapper());
				}else if(loopVars.length==3){
					loopVars[0]=new ArrayModel(trpList.toArray(),new BeansWrapper()); 
					loopVars[1]=new BeanModel(pager,new BeansWrapper()); 
					loopVars[2]=new MapModel(sMap,new BeansWrapper());
				}

				body.render(env.getOut()); 
				
			}
	
		}
	}
	
	
	
}

 在html页面中

<@tailPage  row='10' page='${page!1}' istheme='0' proType="1" cityCode="${cityCode?if_exists}" action='${contextPath}zhoubian.do?cityCode=${cityCode}&cityName=${cityName}&templetPath=index_zb_wd_so.html'  ;trpList,pager,sMap><!-- 含有多个循环变量的-->
	<!--  搜索区  -->
	<div class="dec_box">
			<#if sMap.get('daysMap')?size != 0>
			<#assign daysMap = sMap.get('daysMap')>   
			<dl>
				<dt>行程天数:</dt>
				<dd> 
					<#list daysMap.keySet() as key>
					<a href="${contextPath}zhoubian.do?cityCode=${cityCode}&cityName=${cityName}&templetPath=index_zb_wd_so.html&days=${key}<#if (price??)>&price=${price}</#if><#if (topicLabels??)>&topicLabels=${topicLabels}</#if><#if (sequence??)>&sequence=${sequence}</#if><#if (ptaNames??)>&ptaNames=${ptaNames}</#if><#if (trProperty??  && trProperty!='')>&trProperty=${trProperty}</#if><#if (transportMeans?? && transportMeans!='')>&transportMeans=${transportMeans}</#if>" class="<#if ((days!'') == key?string)>active</#if>" >${key}日游</a>
					</#list>
				</dd>
			</dl>
			</#if>
			<#if sMap.get('priceMap')?size != 0>
			<#assign priceMap = sMap.get('priceMap')> 
			<dl>
				<dt>价格范围:</dt>
				<dd>
					<#list priceMap.keySet() as key>
						<a href="${contextPath}zhoubian.do?cityCode=${cityCode}&cityName=${cityName}&templetPath=index_zb_wd_so.html&price=${key?c}<#if (days??)>&days=${days}</#if><#if (topicLabels??)>&topicLabels=${topicLabels}</#if><#if (sequence??)>&sequence=${sequence}</#if><#if (ptaNames??)>&ptaNames=${ptaNames}</#if><#if (trProperty??  && trProperty!='')>&trProperty=${trProperty}</#if><#if (transportMeans?? && transportMeans!='')>&transportMeans=${transportMeans}</#if>" class="<#if ((price!'') == key?c)>active</#if>" >${priceMap.get(key)}</a>
					</#list>
				</dd>
			</dl>
			</#if>
		
		</div>

	</div>
	
	
	<div class="search_sum">
		<strong class="s18 c_c">${cityName?if_exists}<#if (ptaNames??)>到${ptaNames}旅游 </#if> <#if (days??)>${days}日游</#if></strong> 
			共找到 <strong id="tCount" class="c_o"></strong> 条线路</div>

</div>


<div class="d_wrap selfclear">

	<div class="d_r">

		
		
	
	<div class="d_m dec_m">
	
		<!-- 搜索结果 -->
		<div class="dec_box selfclear">
			
			<div class="search_sort">
				<span class="active">默认排序</span>
				<span>
					<a href="${contextPath}zhoubian.do?cityCode=${cityCode}&cityName=${cityName}&templetPath=index_zb_wd_so.html&sequence=1<#if (topicLabels??)>&topicLabels=${topicLabels}</#if><#if (days??)>&days=${days}</#if><#if (price??)>&price=${price}</#if><#if (sequence??)>&sequence=${sequence}</#if><#if (ptaNames??)>&ptaNames=${ptaNames}</#if><#if (trProperty??  && trProperty!='')>&trProperty=${trProperty}</#if><#if (transportMeans?? && transportMeans!='')>&transportMeans=${transportMeans}</#if>">价格 <em class="icon_sort up"></em></a>&nbsp; 
					<a href="${contextPath}zhoubian.do?cityCode=${cityCode}&cityName=${cityName}&templetPath=index_zb_wd_so.html&sequence=2<#if (topicLabels??)>&topicLabels=${topicLabels}</#if><#if (days??)>&days=${days}</#if><#if (price??)>&price=${price}</#if><#if (sequence??)>&sequence=${sequence}</#if><#if (ptaNames??)>&ptaNames=${ptaNames}</#if><#if (trProperty??  && trProperty!='')>&trProperty=${trProperty}</#if><#if (transportMeans?? && transportMeans!='')>&transportMeans=${transportMeans}</#if>">价格<em class="icon_sort down"></em></a>
				</span>
				<form name="form1" method="post" action="" >
					<script type="text/javascript">
					function form1Submit(){
						var action="${contextPath}zhoubian.do?cityCode=${cityCode}&cityName=${cityName}&templetPath=index_zb_wd_so.html&sequence=1<#if (topicLabels??)>&topicLabels=${topicLabels}</#if><#if (days??)>&days=${days}</#if><#if (price??)>&price=${price}</#if><#if (sequence??)>&sequence=${sequence}</#if><#if (ptaNames??)>&ptaNames=${ptaNames}</#if>";
						
						var trProperty=$.trim($("#trProperty").val());
						
						if(trProperty!=''){
							
							action=action+"&trProperty="+trProperty;
						
						}else{}
						
						var transportMeans=$.trim($("#transportMeans").val());
						
						if(transportMeans!=''){
							
							action=action+"&transportMeans="+transportMeans;
						
						}else{}
						
						form1.action=action;
						
						form1.submit();
					}
					</script>
				<span>&nbsp;
					<select name="trProperty" id="trProperty" onchange="javascript:form1Submit();"> 
						<option value=''>出游方式</option>
						<option value='1' <#if ((trProperty!'') == '1')>selected="selected"</#if> >跟团游</option>
						<option value='2' <#if ((trProperty!'') == '2')>selected="selected"</#if> >自由行</option>
						<option value='3' <#if ((trProperty!'') == '3')>selected="selected"</#if> >自驾游</option>
						<option value='4' <#if ((trProperty!'') == '4')>selected="selected"</#if> >独立包团</option>
					</select>
				</span>
				<span>&nbsp;
					<select name="transportMeans" id="transportMeans"  onchange="javascript:form1Submit();">
						<option value=''>交通工具</option>
						<option value="飞机" <#if ((transportMeans!'') == '飞机')>selected="selected"</#if>>飞机</option>
	                    <option value="火车" <#if ((transportMeans!'') == '火车')>selected="selected"</#if>>火车</option>
	                    <option value="汽车" <#if ((transportMeans!'') == '汽车')>selected="selected"</#if>>汽车</option>
	                    <option value="轮船" <#if ((transportMeans!'') == '轮船')>selected="selected"</#if>>轮船</option>
	                    <option value="动车" <#if ((transportMeans!'') == '动车')>selected="selected"</#if>>动车</option>
	                    <option value="高铁" <#if ((transportMeans!'') == '高铁')>selected="selected"</#if>>高铁</option>
					</select>
				</span>
				</form>
			</div>

			<div class="search_c" style="display:block">
					<#list trpList as tour>
					<div class="search_route_c">
							<div class="g_pic"><a href="${tour.url!''}" target="_blank"><img src="${tour.picturePath!'/img/ta/whitelogo.jpg'}"></a></div>
							<div class="search_route_op">
								¥<strong class="s24 c_c">${tour.lowestPrice!''}</strong>起
								<a href="${tour.url!''}" target="_blank"><div class="search_c_goto">去看看</div></a>
							</div>
							<h3><a href="${tour.url!''}"  target="_blank" class="c_c">${tour.trName!''}</a></h3>
							<p><span class="c_lgray">行程概览: </span><span class="c_o">${tour.passedTourAttrNames!'暂无行程'}</span></p>
							<p><span class="c_lgray">往返交通: </span><span class="dec_mr">${tour.transportMeans!''}</span><span class="c_lgray">服务承诺:</span>
								<#if (tour.extracomsuption??)>
								<span class="c_g">
									<#if (tour.extracomsuption == 1)>
										无购物无自费
									<#elseif (tour.extracomsuption == 2)>
										无购物有自费
									<#elseif (tour.extracomsuption == 3)>
										有购物无自费
									<#elseif (tour.extracomsuption == 4)>
										有购物有自费
									</#if>
								</span>
								</#if>
								</p>
							<p>${tour.companyName!''}</p>
					</div>
					</#list>
			</div>
			
			<div class="search_c">
				<div class="g_loading"></div>
			</div>

		</div>
		<div class="g_page">
			${pager.formPageStr}
		</div>
	</div>
</@tailPage>

 

  • 大小: 11.2 KB
分享到:
评论

相关推荐

    超强freemarker使用总结,有示例有讲解,可做快速查询手册!!

    Freemarker 的核心优势在于其简单易学且功能强大,能够很好地满足 Web 开发中的页面展示需求。 #### 二、Freemarker 组成部分 Freemarker 的模板文件主要由四个部分组成: 1. **文本**:直接输出的内容,这部分与...

    freemarker源码.rar

    7. **自定义功能扩展**:Freemarker允许开发人员通过自定义`Directive`、`Function`、`TemplateMethodModelEx`等接口扩展其功能,例如添加新的模板指令或函数。 8. **与其他框架的集成**:虽然Freemarker可以独立...

    freemarker中文API手册.zip_API

    Freemarker是一个强大的模板引擎,常用于Java web开发中生成动态HTML或者其他文本格式的输出。它的核心设计理念是将数据模型与展示逻辑分离,使得开发者可以专注于业务数据的处理,而设计师则可以专心于页面布局和...

    FreeMarker模板基本语法

    在FreeMarker中,可以通过两种方式引用变量: 1. **普通变量引用**:`${expr}` 用于输出变量的原始值。 2. **格式化变量引用**:`#{expr;format}` 用于对变量进行格式化输出。 ##### 4.1 普通变量引用 普通变量...

    Struts2与FreeMarker模板

    然后在FreeMarker模板中,可以通过`#assign`指令将模型属性赋值给模板变量,并使用`#foreach`循环和条件判断等指令来渲染页面。例如: ```ftl &lt;title&gt;Struts2 & FreeMarker Demo ${message} ``` #### ...

    apache-freemarker-2.3.27-incubating-bin.tar.gz

    在"apache-freemarker-2.3.27-incubating-bin.tar.gz"这个压缩包中,包含了FreeMarker 2.3.27版本的源代码、库文件和其他相关资源。 FreeMarker的工作原理是,它根据预先定义好的模板(.ftl文件)和数据模型来生成...

    FreeMarker学习资料

    在 FreeMarker 中,FTL 标签用于执行指令,其用法与 HTML 标签类似,主要包括三种形式: 1. **开始标签**: `&lt;#directive_name parameter&gt;` —— 如 `&lt;#list animals as animal&gt;`。 2. **结束标签**: `&lt;/#directive_...

    FreeMarker手册

    "添加自定义的directive"指的是FreeMarker允许用户自定义模板指令,以扩展其功能。自定义指令可以封装复杂的逻辑,使模板更加简洁。通过`&lt;@myDirective ...&gt;`的形式调用自定义指令,其中`myDirective`是自定义指令的...

    java freemarker 语法

    Freemarker 是一个功能强大且灵活的模板引擎,在 Java Web 开发中被广泛应用。通过掌握上述的基本语法及高级特性,开发者可以轻松地使用 Freemarker 创建出动态且丰富的网页内容。此外,Freemarker 还提供了丰富的...

    Freemarker使用

    插值是Freemarker中一个关键概念,用于将数据模型中的数据嵌入到模板中。主要有两种类型: - **通用插值**:`${expr}`,用于输出各种类型的数据。具体格式如下: - 字符串值:直接输出。 - 数字值:按照默认格式...

    freemarker总结

    使用import指令导入库到模板中,Freemarker会为导入的库创建新的名字空间,并可以通过import指令中指定的散列变量访问库中的变量: ${my.mail} ${mail} 输出结果: &lt;p&gt;Copyright (C) 1999-2002 ...

    freemarker 语法基础(转).

    在 FreeMarker 中,FTL 标签被用来执行指令。它们与 HTML 标签非常相似,主要包括三种类型: 1. **开始标签**:`&lt;#directive_name parameter&gt;`。 2. **结束标签**:`&lt;/#directive_name&gt;`。 3. **空标签**:`&lt;#...

    freemark 概述 教程 5分钟入门 pdf

    动态元素通过特定的语法(${expression} 或 #{directive})来引用数据模型中的数据。 2. **数据模型(Data Model)**:数据模型是Freemarker模板所使用的数据源,通常由应用程序提供,可以包含各种数据类型,如字符...

    freemark学习文档

    在Freemarker中,命令符号是模板语言的核心组成部分之一,它们用于执行各种操作,如条件判断、循环迭代等。下面是一些常用的命令符号及其解释: - **`is_collection`**:判断给定的对象是否是一个集合。 - **`keys`...

    springboot+jsp+thymeleaf项目源码

    %&gt;`)、脚本元素(如`&lt;scriptlet&gt;`, `&lt;expression&gt;`, `&lt;directive&gt;`)和普通HTML组成。 3. **JSP标签库**:项目可能使用自定义标签库,如JSTL(JavaServer Pages Standard Tag Library),它提供了用于处理常见任务...

    jsp学习详细资料(含有正则表达式)

    5. **模板引擎**:一些模板引擎如FreeMarker或Velocity,它们的配置或模板语法中也支持正则表达式,用于动态内容的处理。 这个压缩包很可能包含JSP的基本教程、实例代码、正则表达式的使用指南,甚至可能有实战项目...

    20个JSP网页开发例子

    基础的JSP页面通常包含`&lt;jsp:directive.page&gt;`指令(定义页面属性)、`&lt;jsp:expression&gt;`(用于输出Java表达式的结果)和`&lt;jsp:scriptlet&gt;`(插入Java代码片段)。 2. **JSP内置对象** JSP提供了九个内置对象,...

    基于jsp的博客系统

    - **JSP指令**:如`&lt;%@ page %&gt;`, `&lt;%@ include %&gt;`, `&lt;jsp:directive&gt;`,用于设置页面属性或包含其他文件。 - **JSP动作**:如`&lt;jsp:useBean&gt;`, `&lt;jsp:setProperty&gt;`, `&lt;jsp:getProperty&gt;`,用于管理JavaBean对象。...

    JSP做的个人博客系统

    - JSP指令:`&lt;%@ directive %&gt;`,如`page`、`include`和`taglib`,用于设置页面属性或引入外部资源。 - JSP动作:`&lt;jsp:action&gt;`,如`useBean`、`setProperty`等,用于操作JavaBean或其他组件。 2. **构建博客...

Global site tag (gtag.js) - Google Analytics