jsp页面硬编码是个很头疼的问题,工作这么多年,看到好多项目都有这种问题,这里介绍下如何防止页面硬编码吧
在Java程序中可以通过静态常量的方法来避免硬编码。如果JSP中允许使用Scriplet的话当然也可以直接使用常量了,不过现在JSP中一般不允许出现<%%>这样的代码,比如在JSTL中怎么办呢?我们不希望看到如下代码:
<c:if test=${state=='01'}>
</c:if>
下面介绍用JspTag的方式来处理:
第一步、在/WEB-INF/tld/下建立my-tag.tld描述文件:
注意:根据JSP2.1规范,tld文件不能存放在/WEB-INF/classes或者/WEB-INF/lib目录中,特别不能放在/WEB-INF/tags目录或子目录中,否则会出现错误:
exception:org.apache.jasper.JasperException: PWC6180: Unable to initializeTldLocationsCache
root cause:org.apache.jasper.JasperException: PWC6336: Illegal TLD path/WEB-INF/tags/fn.tld, must not start with “/WEB-INF/tags”
在Tomcat和Weblogic中不会出现该问题,GlassFish则严格遵照规范,可将tld文件放置在/WEB-INF/tld目录。
<?xml version="1.0" encoding="UTF-8" ?> <taglib xmlns=" http://java.sun.com/xml/ns/j2ee " xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance " xsi:schemaLocation=" http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd " version="2.0"> <description>my tag</description> <display-name>my tag</display-name> <tlib-version>1.0</tlib-version> <short-name>my-tag</short-name> <uri>/my-tag</uri> <tag> <!-- 在JSP中初始化MyConstant常量,以便JSTL中引用。 jsp中使用范例:<my-tag:MyConstant var="常量名称"/> 必填参数var:指定初始化MyConstant中某个变量,如果为空,则报异常 可选参数scope:变量作用范围,默认为page --> <description>MyConstant常量</description> <name>MyConstant</name> <tag-class>com.test.util.tag.MyConstantTag</tag-class> <body-content>JSP</body-content> <attribute> <description>必填参数var:指定初始化MyConstant中某个变量,为空则报异常</description> <name>var</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <description>变量作用范围(默认为page)</description> <name>scope</name> <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
第二步、创建JAVA处理代码 com.test.util.tag.MyConstantTag
它继承了TagSupport并重写doStartTag()方法,才使得JSP中可以直接使用java中的常量:
public class MyConstantTag extends TagSupport {
private static final long serialVersionUID = 3258417209566116146L;
private final Log log = LogFactory.getLog(MyConstantTag.class);
public String clazz = MyConstant.class.getName();
protected String scope = null;
protected String var = null;
public int doStartTag() throws JspException {
Class c = null;
int toScope = PageContext.PAGE_SCOPE;
if (scope != null) {
toScope = getScope(scope);
}
try {
c = Class.forName(clazz);
} catch (ClassNotFoundException cnf) {
log.error("ClassNotFound - maybe a typo?");
throw new JspException(cnf.getMessage());
}
try {
if (var == null || var.length() == 0) {
throw new JspException("常量参数var必须填写!");
} else {
try {
Object value = c.getField(var).get(this);
pageContext.setAttribute(c.getField(var).getName(), value, toScope);
} catch (NoSuchFieldException nsf) {
log.error(nsf.getMessage());
throw new JspException(nsf);
}
}
} catch (IllegalAccessException iae) {
log.error("Illegal Access Exception - maybe a classloader issue?");
throw new JspException(iae);
}
return (SKIP_BODY);
}
/**
* @jsp.attribute
*/
public void setScope(String scope) {
this.scope = scope;
}
public String getScope() {
return (this.scope);
}
/**
* @jsp.attribute
*/
public void setVar(String var) {
this.var = var;
}
public String getVar() {
return (this.var);
}
/**
* Release all allocated resources.
*/
public void release() {
super.release();
clazz = null;
scope = MyConstant.class.getName();
}
private static final Map scopes = new HashMap();
static {
scopes.put("page", new Integer(PageContext.PAGE_SCOPE));
scopes.put("request", new Integer(PageContext.REQUEST_SCOPE));
scopes.put("session", new Integer(PageContext.SESSION_SCOPE));
scopes.put("application", new Integer(PageContext.APPLICATION_SCOPE));
}
public int getScope(String scopeName) throws JspException {
Integer scope = (Integer) scopes.get(scopeName.toLowerCase());
if (scope == null) {
throw new JspException("Scope '" + scopeName + "' not a valid option");
}
return scope.intValue();
}
}
创建常量类MyConstant:
package cn.hshb.common;
public final class MyConstant {
public static String STATE_01 = "1";
}
第三步、在web.xml中配置<jsp-config/>:
<jsp-config> <taglib> <taglib-uri>/my-tag</taglib-uri> <taglib-location>/WEB-INF/tld/my-tag.tld </taglib-location> </taglib> </jsp-config>
第四部、JSP头部引入:
<%@ taglib prefix="my-tag" uri="/my-tag" %> <my-tag:MyConstant var="STATE_01"/>
现在用${STATE_01}便可使用常量。
再来看下与最初硬编码的区别:
<c:if test=${state==STATE_01}>
</c:if>