铁手剑谱

上善若水
数据加载中……
Struts秘籍之第1段:第2.3式:在JSP中使用常数

第2.3式. 在JSP中使用常数

问题

不通过scriptlets, 你想要在JSP中使用Java类中定义的应用常数public static字段。

动作要领

使用Jakarta Taglibs的unstandard标签库提供的bind标签来创建包含常数字段的JSTL变量:

<%@ taglib uri="http://jakarta.apache.org/taglibs/unstandard-1.0" prefix="un" %>
<un:bind var="constantValue"
        type
="com.foo.MyClass"
       field
="SOME_CONSTANT"/>
<bean:write name="constantValue"/>


<%@ taglib uri="http://jakarta.apache.org/taglibs/unstandard-1.0" prefix="un" %><un:bind var="constantValue"type="com.foo.MyClass"field="SOME_CONSTANT"/><bean:write name="constantValue"/>

 

动作变化

大多数团队都费力地通过使用publicstatic字段(常数)来避免在Java类中使用硬编码的字符串。不幸的是,不过是 Struts 还是 JSP都没有提供相应的手段来在JSP中不借助scriptlet 而使用这些常数,如:

<%= com.foo.MyClass.SOME_CONSTANT %>


但是有许多开发团队禁止,或者至少不赞成在JSP中使用scriptlet 。

Scriptlets (<% . . . %>) 和运行时表达式(<%= . . . %>) 都直接在JSP中置入Java代码。它们不是与生俱来的恶人,但是它们因为使得你的页面中混合HTML,JSP和Java代码变得纷繁复杂,从而使开发效率大大降低。需要找到一种方法来避免使用scriptlets你将发现JSTL的引入就是为了解决这个可怕的scriptlet的问题。

这种方法通过使用定制JSP标签来提供一种方式来解决这个窘境,即使用un:bind标签。该标签是unstandard标签库的一部分,unstandard标签库则是Jakarta Taglibs中的一个组件。unstandard标签库包含已经用于或者正在考虑用于标准标签库的标签。标准标签库是JSTL 规范的Jakarta Taglibs 的实现。

unstandard标签库可以从下面的地方下载:http://cvs.apache.org/builds/jakarta-taglibs-sandbox/nightly/projects/unstandard/. 为了使用这个库,你需要将unstandard.jar和unstandard.tld文件拷贝到应用的WEB-INF/lib目录。

un:bind标签提供了一种方法来创建JSP页面上下文变量,它一般引用java类中的一个字段。字段可以是实例变量或者静态变量。良好设计的Java 类一般都不会将实例变量暴露为公共字段,而大多数都将静态变量暴露为公共字段。

你可以创建一个使用Struts提供的静态字段的简单JSP页面来看看这种方法是否可行。从Struts 1.1开始, Struts 所用的常数都放在org.apache.struts.Globals类中。这些常数的值指定了各种存储在请求、会话、应用上下文中的Struts相关实体的关键字值。Example 2-5 中的JSP页面使用了un:bind标签来显示这些值:

Example 2-5. 使用bind 标签来访问Struts全局常数

 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://jakarta.apache.org/taglibs/unstandard-1.0" prefix="un" %>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<html>
<head>
  
<title>Struts Cookbook - Chapter 4 : Using Bind</title>
</head>
<body>
  
<un:bind var="servletKey"
          type
="org.apache.struts.Globals"
         field
="SERVLET_KEY"/>
  
<p>
  Field name: SERVLET_KEY
<br />
  Field value: 
<bean:write name="servletKey"/>< br />
  Attribute Value: 
<c:out value="${applicationScope[servletKey]}"/>< br />
  
</p>
</body>
</html>

此页面使用un:bind来从Struts Globals类中获取SERVLET_KEY字段的值。SERVLET_KEY字段的值被用于servlet 上下文属性关键字,在其下存储了为Struts controller servlet 定义的映射(如. /action/*或*.do)。

在你需要以一种特殊的方式访问常数时,un:bind标签是一个不错的选择。但是它还是有些麻烦,因为你需要首先使用un:bind标签来创建变量,然后使用bean:write或者c:out标签来显示值。假定JSP显示Globals类中的所有常数,而这足有17 个之多。许多应用严重依赖于常数并且可能有很多类,每一个类都包含很多字段。对每一个字段都使用一个单独的标签是多么的麻烦。

你可以使用一种替代方法,虽然需要一些额外的Java 代码,它可以将常数绑定到一个JavaBean 的一个Map属性之中。你可以将这个bean 存储在servlet 上下文中。然后就可以通过bean:write和c:out标签直接访问这些值了。Example 2-6中的Constants类定义了一个包含Struts Globals类中的常数的map属性的JavaBean 。Example 2-7 中的ConstantsPlugin则将Constants的一个实例载入到servlet context中。

Example 2-6. 包含Struts全局常数的JavaBean

 

package com.oreilly.strutsckbk.ch04;

import java.util.HashMap;
import java.util.Map;

import org.apache.struts.Globals;

public class Constants {
    
private Map strutsGlobals;
    
    
public Constants( ) {
        strutsGlobals 
= new HashMap( );
        strutsGlobals.put( 
"ACTION_SERVLET_KEY"
                           Globals.ACTION_SERVLET_KEY );
        strutsGlobals.put( 
"SERVLET_KEY", Globals.SERVLET_KEY );
    }

    
    
public Map getStrutsGlobals( ) {
        
return strutsGlobals;
    }

    
public void setStrutsGlobals(Map strutsGlobals) {
        
this.strutsGlobals = strutsGlobals;
    }

}

 

Example 2-7. 将常数载入到servlet context中的插件

 

package com.oreilly.strutsckbk.ch04;

import javax.servlet.ServletException;

import org.apache.struts.action.ActionServlet;
import org.apache.struts.action.PlugIn;
import org.apache.struts.config.ModuleConfig;

public class ConstantsPlugin implements PlugIn {
    
public void destroy( ) {
    }

    
public void init(ActionServlet servlet, ModuleConfig module)
            throws ServletException 
{
        Constants constants 
= new Constants( );
        servlet.getServletContext( ).setAttribute(
"Constants", constants);
    }

}

Example 2-8 (globals_test.jsp) 则展示了一个访问和显示ConstantsPlugin载入的常数的JSP页面。第一个常数使用Struts bean:write标签,第二个则使用JSTL c:out标签。

Example 2-8. 使用Struts 和JSTL访问常数

 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<html>
<head>
  
<title>Struts Cookbook - Chapter 4 : Accessing Constants</title>
</head>
<body>
  
<p>
  Field name: ACTION_SERVLET_KEY
<br />
  Field value: 
<bean:write name="Constants" 
                       property
="strutsGlobals(ACTION_SERVLET_KEY)"/><br />
  
</p>
  
<p>
  Field name: SERVLET_KEY
<br />
  Field value: 
<c:out value="${Constants.strutsGlobals.SERVLET_KEY}"/><br />
  
</p>
</body>
</html>

这种方式的最大缺点是你必须手动创建持有常数值的map。如果类中添加了新的常数,你必须修改Constants类的源代码以便能够获取它。

相关招式

关于Jakarta Taglibs 项目的详细信息可以访问http://jakarta.apache.org/taglibs.

第5.4式提供了如何从Struts 和JSTL访问map的方法。

Struts plug-ins 我们在第2.1式讨论过。

Kris Schneider 建立了一个类似于Example 2-6中的Constants类,使用反射来访问特定类的公开静态字段。源代码可以从归档的struts-user mailing list 中找到:http://marc.theaimsgroup.com/?l=struts-user&m=108929374300664&w=2.

 

posted on 2005-05-12 11:01 铁手 阅读(2566) 评论(1)  编辑  收藏 所属分类: JavaStruts系列

评论

# Struts 秘籍(CookBook)[TrackBack] 2005-11-12 18:29 阿泠

本系列源改编自O'Reily的Strus Cookbook
[引用提示]阿泠引用了该文章, 地址: http://blog.donews.com/inclear/archive/2005/11/12/624363.aspx
  回复  更多评论    

只有注册用户登录后才能发表评论。


网站导航: