velocity对set 类型的支持 map get输出问题分析
2012-08-08 21:08
316 查看
今天使用velocity在java后台渲染一个map<Long,String>对象到vm模板上,通过get(111)获取不到map的对象的值分析。
这是velocity1.6.4的处理,以后版本是不是解决了这个问题可以再查,个人认为在vm文件支持跟java一样加个L表示long之类的处理应该不难。
具体代码如下:
后台java生成设置代码
vm文件输出代码:
打印输出如下:
可以看到使用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处理整数型的转换的:
请看init方法,会尝试先把整数转换成Integer类型,转换失败再尝试转换成Long,再转换失败再转换成BigInteger,所以101肯定先转换成Integer成功了。
而且velocity没有语法直接直接设置类型为Long型。
同样对于浮点型也一样:
ASTFloatingPointLiteral.java类
先尝试转换成Float,失败再转换成Double,再失败再转换成BigDecimal。
velocity语法也没有设置为double型的设置。
所以就会出现上面那个case了,$map.get(101) map存的是long跟string的键值对,用int型取肯定取不到,因为long跟int的hashcode不一样,这个可以查看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的处理。
相关文章推荐
- velocity对set 类型的支持 map get输出问题分析
- velocity对set 类型的支持 map get输出问题分析
- Redis之数据Set和Get类型不一致问题
- 关于javaBean中boolean类型变量的set和get注入后传到前端JS中的问题
- 关于set或map的key使用自定义类型的问题
- 通过封装编写Book类。要求:类具有私有属性书名title、页数pageNum、类型type(默认为计算机类),并为这三个属性分别编写set和get方法。其中,页数不能少于200页,否则输出错误信息,
- 关于set或map的key使用自定义类型的问题
- JavaEE中用response向客户端输出中文数据乱码问题分析
- 使用Java sound播放音频文件出现“文件类型不支持”报错的原因分析
- java:Conllection(List,set,get,map,subList)使用
- C++ 二级指针、函数指针与数组复合类型的问题分析
- 关于windows下redis频繁get 和set相同值遇到的问题
- Java Switch支持的类型问题
- 使用Java反射机制将Map转换为Java对象,支持Boolean、Date类型
- SetTextSize(),getTextSize()单位问题
- C#中类型分析中的常见问题 Type
- 解决Apache CXF 不支持传递java.sql.Timestamp和java.util.HashMap类型问题
- Java集合的Set、List、Map异同分析
- request.getParameterMap()出现的问题
- 百度地图:[BMMapViewManager getCMapControlWithMapView:]闪退问题如何解决?