在JSP页面中使用自定义标记调用javabean的方法

不知道大家在调用JavaBean的方法时,是不是像我一样感觉很是不爽?
看下面这段代码:
<jsp:useBean id="memberBean" class="org.jforum.bbean.MemberBean" scope="session">
</jsp:useBean>
<c:choose>
    <c:when test="${param.Submit=='注 销'}">
        <% memberBean.loginOut(); %>
        <c:redirect url="index.jsp" />
    </c:when>
    <c:when test="${param.Submit=='登 录'}">
        <% memberBean.login(request.getParameter("username"), request.getParameter("password")); %>
        <c:if test="${memberBean.logined}">
            <c:redirect url="index.jsp" />
        </c:if>
    </c:when>
</c:choose>

<% memberBean.login(request.getParameter("username"), request.getParameter("password")); %>
自己写出来,都觉得很费力!
但是还有更糟的:
<ul>
            <c:forEach items="${categoryBean.categoryList}" var="category">
                <li>${ category.name }</li>
                <ul>
                    <c:forEach items="<%= categoryBean.getSubCategoryList((Category)pageContext.getAttribute("category")) %>" var="subCategory">
                        <li>
                            <a href="category.jsp?id=${ subCategory.id }">${ subCategory.name }</a><br />
                            ${ subCategory.description }
                        </li>
                    </c:forEach>
                </ul>
            </c:forEach>
        </ul>

大家都看到了:<% %>中想要使用标签库定义的对象真是痛苦!
我只是恨JSP2没有调用javabean方法的标签!!!(该死的JSP,总有一天要淘汰你。)
但是想想要通过反射调用bean的方法应该也不是什么难事,就自己翻参考书写了两个标签解决了这个问题!
现将成果公布一下,和大家分享!
主要的标记处理代码:Call.java
/*
 * Call.java
 *
 * Created on June 11, 2007, 12:03 PM
 */

package learnjsp2.tags;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.JspException;
import org.apache.taglibs.standard.lang.jstl.Coercions;
import org.apache.taglibs.standard.lang.jstl.ELException;

/**
 *
 * @author  zsun
 * @version
 */

public class Call extends SimpleTagSupport implements DynamicAttributes, StrictTypeParams  {
    
    /**
     * Initialization of bean property.
     */
    private java.lang.Object bean;
    
    /**
     * Initialization of method property.
     */
    private java.lang.String method;
    
    /**
     * Initialization of var property.
     */
    private java.lang.String var = null;
    
    /**
     * Initialization of scope property.
     */
    private int scope = PageContext.PAGE_SCOPE;
    private List dynamicAttrValues = new ArrayList();
    private List typeList = null;
    
    /**Called by the container to invoke this tag.
     * The implementation of this method is provided by the tag library developer,
     * and handles all tag processing, body iteration, etc.
     */
    public void doTag() throws JspException {
        JspWriter out=getJspContext().getOut();
        try {
            JspFragment f=getJspBody();
            if (f != null) f.invoke(out);
        } catch (java.io.IOException ex) {
            throw new JspException(ex.getMessage());
        }
        
        Class cls = bean.getClass();
        Method[] methods = cls.getMethods();
        Method m = null;
        Class[] paramTypes = null;
        
        search: for (int i = 0; i < methods.length; i++ ) {
            Method t = methods[i];
            paramTypes = t.getParameterTypes();
            if (t.getName().equals(method) &&
                    paramTypes.length == dynamicAttrValues.size()) {
                if (typeList != null)
                    for (int j = 0; j < paramTypes.length; j++)
                        if (!paramTypes[j].getName().equals(typeList.get(j)))
                            continue search;
                m = t;
                break;
            }
        }
        if (m == null)
            throw new JspException("JavaBean Object hasn't no method named '" + method + "'");
        
        try {
            Object coercedValues[] = new Object[paramTypes.length];
            Iterator paramIterator = dynamicAttrValues.iterator();
            for (int i = 0; i < paramTypes.length; i++) {
                Object paramValue = paramIterator.next();
                Class paramClass = paramTypes[i];
                System.out.println(paramClass);
                if (paramValue == null || paramValue.getClass() != paramClass)
                    try {
                        paramValue = Coercions.coerce(paramValue, paramClass, null);
                    } catch (ELException e) {
                        throw new JspException(e.getMessage(), e.getRootCause());
                    }
                coercedValues[i] = paramValue;
            }
            Object returnVal = m.invoke(bean, coercedValues);
            if (var != null)
                if (returnVal != null)
                    getJspContext().setAttribute(var, returnVal, scope);
                else
                    getJspContext().removeAttribute(var, scope);
            
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new JspException("Call method is Error!");
        }
        
    }
    
    /**
     * Setter for the bean attribute.
     */
    public void setBean(java.lang.Object value) throws JspException {
        if (value == null)
            throw new JspException("Null 'bean' attribute in 'Call' tag");
        this.bean = value;
    }
    
    /**
     * Setter for the method attribute.
     */
    public void setMethod(java.lang.String value) throws JspException {
        if (value == null)
            throw new JspException("Null 'method' attribute in 'Call' tag");
        this.method = value;
    }
    
    /**
     * Setter for the var attribute.
     */
    public void setVar(java.lang.String value) throws JspException {
        if (value == null)
            throw new JspException("Null 'var' attribute in 'Call' tag");
        this.var = value;
    }
    
    /**
     * Setter for the scope attribute.
     */
    public void setScope(java.lang.String value) {
        if (value.equalsIgnoreCase("page"))
            scope = PageContext.PAGE_SCOPE;
        else if (value.equalsIgnoreCase("request"))
            scope = PageContext.REQUEST_SCOPE;
        else if (value.equalsIgnoreCase("session"))
            scope = PageContext.SESSION_SCOPE;
        else if (value.equalsIgnoreCase("application"))
            scope = PageContext.APPLICATION_SCOPE;
    }
    
    public void setDynamicAttribute(String uri, String localName, Object value) throws JspException {
        dynamicAttrValues.add(value);
    }

    public void addStrictTypeParameter(String type, Object value) {
        if (typeList == null)
            typeList = new ArrayList();
        typeList.add(type);
        dynamicAttrValues.add(value);
    }
}

定义父子标签协作接口:StrictTypeParams.java
/*
 * StrictTypeParams.java
 *
 * Created on June 14, 2007, 9:35 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package learnjsp2.tags;

/**
 *
 * @author zsun
 */
public interface StrictTypeParams {
    void addStrictTypeParameter(String type, Object value);
}

参数标记:ParamTag.java
package learnjsp2.tags;
/*
 * ParamTag.java
 *
 * Created on June 14, 2007, 10:35 AM
 */

import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.JspException;

/**
 *
 * @author  zsun
 * @version
 */

public class ParamTag extends SimpleTagSupport {

    /**
     * Initialization of class property.
     */
    private java.lang.String _class;
    
    /**Called by the container to invoke this tag.
     * The implementation of this method is provided by the tag library developer,
     * and handles all tag processing, body iteration, etc.
     */
    public void doTag() throws JspException {
        StrictTypeParams parent = (StrictTypeParams)findAncestorWithClass(this, StrictTypeParams.class);
        if (parent == null) {
            throw new JspException("The Param tag is not enclosed by a supported tag type");
        }
        parent.addStrictTypeParameter(this._class, this.value);
        
    }
    /**
     * Initialization of value property.
     */
    private java.lang.Object value;
    /**
     * Setter for the class attribute.
     */
    public void setParamclass(java.lang.String value) {
        this._class = value;
    }
    /**
     * Setter for the value attribute.
     */
    public void setValue(java.lang.Object value) {
        this.value = value;
    }
}

部署描述符:
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.0" 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 web-jsptaglibrary_2_0.xsd">
  <tlib-version>1.0</tlib-version>
  <short-name>utils</short-name>
  <uri>/WEB-INF/tlds/utils</uri>
  <tag>
    <name>Call</name>
    <tag-class>learnjsp2.tags.Call</tag-class>
    <body-content>scriptless</body-content>
    <attribute>
      <name>bean</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
      <type>java.lang.Object</type>
    </attribute>
    <attribute>
      <name>method</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
      <type>java.lang.String</type>
    </attribute>
    <attribute>
      <name>var</name>
      <rtexprvalue>true</rtexprvalue>
      <type>java.lang.String</type>
    </attribute>
    <attribute>
      <name>scope</name>
      <rtexprvalue>true</rtexprvalue>
      <type>java.lang.String</type>
    </attribute>
    <dynamic-attributes>true</dynamic-attributes>
  </tag>
  <tag>
    <name>Param</name>
    <tag-class>learnjsp2.tags.ParamTag</tag-class>
    <body-content>empty</body-content>
    <attribute>
      <name>paramclass</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
      <type>java.lang.String</type>
    </attribute>
    <attribute>
      <name>value</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
      <type>java.lang.Object</type>
    </attribute>
  </tag>
</taglib>


你可能感兴趣的:(java,apache,bean,jsp,servlet)