解决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 using org.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);
            }
        }
    }

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

欧米优

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值