Struts秘籍之第1段:第2.3式:在JSP中使用常数

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.

 

你可能感兴趣的:(Struts秘籍之第1段:第2.3式:在JSP中使用常数)