解决velocity-tools-2.0中ViewTool接口被废除的情况

该问题请参考:

http://www.oschina.net/question/100267_20922


先把该帖子上的内容本分转过来,然后加上自己的解决方法


tsl0922说:“

初学Velocity,想写个VelocityTool类实现以相对路径方式嵌入动态页面,思路大致与http://www.oschina.net/code/snippet_12_694中一样,因为新版中init(Object arg0)方法已经Deprecated了,换用configure(Map props)(见http://velocity.apache.org/tools/devel/upgrading.html最下面和http://velocity.apache.org/tools/devel/creatingtools.html),代码如下: 

import java.util.Map;
	 
import org.apache.velocity.VelocityContext;
import org.apache.velocity.tools.view.ViewContext;
	 
	public class VelocityTool {
	 
	    protected VelocityContext velocity;
	 
	    public void configure(Map props) {
	        Object obj = props.get("velocityContext");
	        if (obj instanceof ViewContext) {
	            ViewContext viewContext = (ViewContext) obj;
	            velocity = (VelocityContext) viewContext.getVelocityContext();
	        }
	    }
	 
	    public String cur_templete() {
	        return velocity.getCurrentTemplateName();
	    }
	 
	}

经测试

public class VelocityTools {
	private ViewContext context;

	protected HttpServletRequest request;

	public VelocityTools() {
		System.out.println("sssssssssssssssssssssssssssssssssssss");
	}

	public void configure(Map<?, ?> props) {
		Object obj = props.get("velocityContext");
		if (obj instanceof ViewContext) {
			context = (ViewContext) obj;
			request = context.getRequest();
		}

	}

	public void init(Object arg0) {
		System.out.println("init");
		// scope: request or session
		if (arg0 instanceof ViewContext) {
			System.out.println("vvvvvvvvvvvvvvvcccccccccccccccccccc");
		}
		// scope: application
		else if (arg0 instanceof ServletContext) {
			System.out.println("sssssssssssssssssssscccccccccccccccccccc");
		}
	}
}

虽然ViewTool接口被去掉了,但是可以添加上方法:

public void init(Object arg0) 
会自动执行的。


下面这段代码在apache的官网上有解释,英文不好,单仔细一看就明白了。

连接时相关问题的链接

http://velocity.apache.org/tools/devel/creatingtools.html

把apache官网上的话复制一下。

If you want to allow your tool to be configured, you have two options:

  • add a public setter for each property
  • add a public void configure(Map props) method
You can, of course, do both, but if you do so keep in mind that the specific setters will be called before the configure() method. The application of configuration properties to specific setters is done usingorg.apache.commons.beanutils.PropertyUtils from the Commons-BeanUtils project, so the rules follow the typical bean property conventions.

public VelocityTools() {
		System.out.println("do constructor VelocityTools");
	}

	public void configure(Map<?, ?> props) {
		Object obj = props.get("velocityContext");
		if (obj instanceof ViewContext) {
			context = (ViewContext) obj;
			request = context.getRequest();
		}

	}
取到的实例是个ChainedContext类型,但是他集成了ViewContext 直接使用 

obj instanceof ViewContext
就可以了。这点不会报错的。

属性:deprecationSupportMode 默认是ture值。

而方法setDeprecationSupportMode(boolean support) 不赞成使用了

在createContext()方法中创建context的类型一定是ChainedContext

VelocityView.java

……    
private boolean deprecationSupportMode = true;

……

  @Deprecated
    protected final void setDeprecationSupportMode(boolean support)
    {
        if (deprecationSupportMode != support)
        {
            this.deprecationSupportMode = support;
            debug("deprecationSupportMode is now %s", (support ? "on" : "off"));
        }
    }

……
    /**
     * <p>Creates and returns an initialized Velocity context.</p>
     *
     * A new context of class {@link ViewToolContext} is created and
     * initialized.
     *
     * @param request servlet request from client
     * @param response servlet reponse to client
     */
    @Override
    public ViewToolContext createContext(HttpServletRequest request,
                                         HttpServletResponse response)
    {
        ViewToolContext ctx;
        if (this.deprecationSupportMode)
        {
            ctx = new ChainedContext(velocity, request, response, servletContext);
        }
        else
        {
            ctx = new ViewToolContext(velocity, request, response, servletContext);
        }
        prepareContext(ctx, request);
        return ctx;
    }
在OldToolInfo.java中使用反射获取init方法是否存在

protected Method getInit()
    {
        if (this.init == null)
        {
            try
            {
                // try to get an init(Object) method
                this.init =
                    getToolClass().getMethod("init", new Class[]{ Object.class });
            }
            catch (NoSuchMethodException nsme)
            {
                // ignore
            }
        }
        return this.init;
    }


附上代码清单

package org.apache.velocity.tools;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import java.lang.reflect.Method;
import java.util.Map;
import org.apache.velocity.tools.ToolContext;

/**
 * Manages old tools which still use the deprecated init() method.
 *
 * @author Nathan Bubna
 * @version $Id: OldToolInfo.java 674 2012-05-30 05:11:51Z liu_peng $
 */
public class OldToolInfo extends ToolInfo
{
    private static final long serialVersionUID = -4062162635847288761L;
    public static final String INIT_METHOD_NAME = "init";

    private transient Method init;

    /**
     * Creates a new instance using the minimum required info
     * necessary for a tool.
     */
    public OldToolInfo(String key, Class clazz)
    {
        super(key, clazz);
    }

    protected Method getInit()
    {
        if (this.init == null)
        {
            try
            {
                // try to get an init(Object) method
                this.init =
                    getToolClass().getMethod("init", new Class[]{ Object.class });
            }
            catch (NoSuchMethodException nsme)
            {
                // ignore
            }
        }
        return this.init;
    }

    /**
     * 
     *
     * @param clazz the java.lang.Class of the tool
     */
    @Override
    public void setClass(Class clazz)
    {
        super.setClass(clazz);

        // clear any existing init method
        this.init = null;
    }


    @Override
    protected void configure(Object tool, Map<String,Object> configuration)
    {
        // have specific setters and configure(Map) called first
        super.configure(tool, configuration);

        Method init = getInit();
        if (init != null)
        {
            // ctx should, in all cases where a tool has such a method,
            // actually be a View(Tool)Context, but we don't want to link
            // to that class here, so as not to pollute the generic jar
            Object ctx = configuration.get(ToolContext.CONTEXT_KEY);
            if (ctx != null)
            {
                invoke(init, tool, ctx);
            }
        }
    }

}



阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页