zoukankan      html  css  js  c++  java
  • velocity对set 类型的支持 map get输出问题分析

    今天使用velocity在java后台渲染一个map<Long,String>对象到vm模板上,通过get(111)获取不到map的对象的值分析。


    这是velocity1.6.4的处理,以后版本是不是解决了这个问题可以再查,个人认为在vm文件支持跟java一样加个L表示long之类的处理应该不难。



     

    具体代码如下:

     

    后台java生成设置代码

    Map<Long,String> map = new HashMap<Long,String>();
             map.put(101L,"aaa");
             map.put(102L,"bbb");
             context.put("longMap",map);
             
             Map<Integer,String> intMap = new HashMap<Integer,String>();
             intMap.put(101,"aaa");
             intMap.put(102,"bbb");
             context.put("intMap",intMap);

    vm文件输出代码:

    #foreach($item in $longMap.entrySet())
       $item.key $item.value
    #end
    
    
    $longMap.get(101)
    
    
    
    #foreach($item in $intMap.entrySet())
       $item.key $item.value
    #end
    
    $intMap.get(101)

    打印输出如下:

    102 bbb 101 aaa $longMap.get(101) 102 bbb 101 aaa aaa 

    可以看到使用Map<Long,String>的map类型,通过$longMap.get(101)获取不到值,而使用Map<Integer,String>类型的map,通过$intMap.get(101)能够正常取到值aaa,而通过entrySet来遍历都没有问题,为什么会这样呢?

     

     

    那就查看velocity的源码,查看这块的处理了,

     

    最终是在velocity中通过#set($a=101)或者直接使用$intMap.get(101)是,会把101生成存储到一个变量中,而变量的类型当然根据这个值来了,不过101当然处理成整数型,而'aaa'则处理成字符串,101.1处理成浮点型。

     

    但是整数型有short,int,long,BigInteger,浮点型有float,double,BigDecimal等,那么怎么处理值的类型了。

     

    请看velocity的下面两个类就知道了:

     

    ASTIntegerLiteral.java处理整数型的转换的:

    public class ASTIntegerLiteral extends SimpleNode
    {
    
        // This may be of type Integer, Long or BigInteger
        private Number value = null;
    
        /**
         * @param id
         */
        public ASTIntegerLiteral(int id)
        {
            super(id);
        }
    
        /**
         * @param p
         * @param id
         */
        public ASTIntegerLiteral(Parser p, int id)
        {
            super(p, id);
        }
    
    
        /**
         * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object)
         */
        public Object jjtAccept(ParserVisitor visitor, Object data)
        {
            return visitor.visit(this, data);
        }
    
        /**
         * @see org.apache.velocity.runtime.parser.node.SimpleNode#init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object)
         */
        public Object init( InternalContextAdapter context, Object data)
            throws TemplateInitException
        {
            /*
             *  init the tree correctly
             */
    
            super.init( context, data );
    
            /**
             * Determine the size of the item and make it an Integer, Long, or BigInteger as appropriate.
             */
             String str = getFirstToken().image;
             try
             {
                 value = new Integer( str );
             }
             catch ( NumberFormatException E1 )
             {
                try
                {
    
                    value = new Long( str );
    
                }
                catch ( NumberFormatException E2 )
                {
    
                    // if there's still an Exception it will propogate out
                    value = new BigInteger( str );
                }
            }
    
            return data;
        }
    
        /**
         * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter)
         */
        public Object value( InternalContextAdapter context)
        {
            return value;
        }
    
    }

    请看init方法,会尝试先把整数转换成Integer类型,转换失败再尝试转换成Long,再转换失败再转换成BigInteger,所以101肯定先转换成Integer成功了。

     

    而且velocity没有语法直接直接设置类型为Long型。

     

    同样对于浮点型也一样:

    ASTFloatingPointLiteral.java类

    public class ASTFloatingPointLiteral extends SimpleNode
    {
    
        // This may be of type Double or BigDecimal
        private Number value = null;
    
        /**
         * @param id
         */
        public ASTFloatingPointLiteral(int id)
        {
            super(id);
        }
    
        /**
         * @param p
         * @param id
         */
        public ASTFloatingPointLiteral(Parser p, int id)
        {
            super(p, id);
        }
    
    
        /**
         * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object)
         */
        public Object jjtAccept(ParserVisitor visitor, Object data)
        {
            return visitor.visit(this, data);
        }
    
        /**
         *  Initialization method - doesn't do much but do the object
         *  creation.  We only need to do it once.
         * @param context
         * @param data
         * @return The data object.
         * @throws TemplateInitException
         */
        public Object init( InternalContextAdapter context, Object data)
            throws TemplateInitException
        {
            /*
             *  init the tree correctly
             */
    
            super.init( context, data );
    
            /**
             * Determine the size of the item and make it a Double or BigDecimal as appropriate.
             */
             String str = getFirstToken().image;
             try
             {
                 value = new Double( str );
    
             } catch ( NumberFormatException E1 )
             {
    
                // if there's still an Exception it will propogate out
                value = new BigDecimal( str );
    
            }
    
            return data;
        }
    
        /**
         * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter)
         */
        public Object value( InternalContextAdapter context)
        {
            return value;
        }
    
    
    }
    

     先尝试转换成Float,失败再转换成Double,再失败再转换成BigDecimal。

    velocity语法也没有设置为double型的设置。

     

    所以就会出现上面那个case了,$map.get(101) map存的是long跟string的键值对,用int型取肯定取不到,因为long跟int的hashcode不一样,这个可以查看map的处理。


  • 相关阅读:
    Python 数据分析中金融数据的来源库和简单操作
    Python 数据分析中常用的可视化工具
    Pandas 时间序列处理
    Ubuntu 下使用 python3 制作读取 QR 码
    Ubuntu中找不到pip3命令的解决方法
    Ubuntu 中查找软件安装的位置
    将文件进行分类整理
    树的遍历
    Junit4知识梳理
    springboot中controller的使用
  • 原文地址:https://www.cnblogs.com/secbook/p/2655147.html
Copyright © 2011-2022 走看看