ExtJs中出现this.ds.fields.get(i) is undefined错误解决方法
出现问题如题:依旧谷歌得:
原因:在Grid的列定义中一定要指定dataIndex属性,即使没有store中的对应上(比如一些附加字段)也要指定一个dataIndex,否则就会出现this.ds.fields.get(i) is undefined的错误。
解决方法:当然就是补上列定义中的dataIndex属性咯..
ExtJs中出现this.config[col] is undefined错误解决方法
问题如上,谷歌得:
原因 :
在Grid定义的时候对某列使用了autoExpandColumn属性,而这个属性所指定的是某列定义的id属性,
该列上没有指定id,所以出错了。
解决方法:
在被扩展的那些列指定id属性即可,id属性所指定的值当然要和autoExpandColumn所指定的一样啦。
关于字符串非空判断效率问题
做一个字符串非空的判断,我们经常如下这样写:
if(str == null || "".equals(str)){ //具体操作 }
这是一种很正常的写法,但是如果去比较字符串的长度是否为0的话,效率是更高的。贴个JDK的equals方法的源代码:
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = count; if (n == anotherString.count) { char v1[] = value; char v2[] = anotherString.value; int i = offset; int j = anotherString.offset; while (n-- != 0) { if (v1[i++] != v2[j++]) return false; } return true; } } return false; }
再来看看str.length()的方法,则是直接返回其大小。两个对比,很明显的length()方法要优化很多。
所以做字符串非空判断尽量写成如下方式:
if(str == null || str.length() == 0){ //具体操作 }
其实也可以用apache-common-lang包下StringUtils.isEmpty(String src);方法判断即可,里面的实现就是用长度来判断的。
经理透露,很多笔试面试题经常都会考这样的问题,如果你用equals来判断,那么在面试官的印象就要大大折扣啦。
Java主线程等待子线程执行完毕-CountDownLatch
想做的一个程序如题,主要是想统计子线程都执行完毕所用的时间,网上搜索到了CountDownLatch这个类,这个工具类可以理解为计数器。在这里用于表示正在运行的线程数,当一个子线程结束的时候,将这个计数器减一,最后在主线程的一个地方等待子线程全部执行完毕,再继续运行等待后面的程序。写了个Demo程序,如下:
//子线程 public class SubThread extends Thread{ //子线程记数器,记载着运行的线程数 private CountDownLatch runningThreadNum; public SubThread(CountDownLatch runningThreadNum){ this.runningThreadNum = runningThreadNum; } @Override public void run() { System.out.println(Thread.currentThread().getName()+"-start"); System.out.println(Thread.currentThread().getName()+"-do something"); System.out.println(Thread.currentThread().getName()+"-end"); runningThreadNum.countDown();//正在运行的线程数减一 } }
//Main主线程 public class MainThread { public static void main(String[] args) throws InterruptedException { long startTime = System.currentTimeMillis(); int threadNum = 5; //线程数 //定义正在运行的线程数 CountDownLatch runningThreadNum = new CountDownLatch(threadNum); System.out.println(Thread.currentThread().getName()+"-start"); //创建多个子线程 for (int i = 0; i < threadNum; i++) { new SubThread(runningThreadNum).start(); } //等待子线程都执行完了再执行主线程剩下的动作 runningThreadNum.await(); System.out.println(Thread.currentThread().getName()+"-end"); long endTime = System.currentTimeMillis(); System.out.println("runningTime:"+(endTime-startTime)); } }
main-start Thread-0-start Thread-0-do something Thread-0-end Thread-1-start Thread-1-do something Thread-1-end Thread-2-start Thread-2-do something Thread-2-end Thread-4-start Thread-3-start Thread-4-do something Thread-3-do something Thread-4-end Thread-3-end main-end runningTime:16
看到打印的结果,满足我现在的要求。笔记下~~
json-lib中关于Date转换的问题
前两天,关于使用json-lib工具包来将一个java对象序列化成json串,结果总是报如下错误:
net.sf.json.JSONException: java.lang.reflect.InvocationTargetException
得原因是因为Java对象中存在Date类型的对象无法进行解析,但是我又必须使用Date类型,还好json-lib提供了可扩展的接口JsonValueProcessor接口来让我们自定义的处理Json返回值的接口,看具体的对日期返回值的操作扩展:(为缩小篇幅,注释没那么规范),另外需要依赖的第三方包有如下:
commons-beanutils.jar commons-collections-3.1.jar commons-lang-2.1.jar commons-logging-1.1.1.jar ezmorph-1.0.3.jar json-lib-2.3-jdk15.jar |
//Date日期类型的Json值处理器,可自定义一些类的处理方式,是json提供的一个扩展接口 public class DateJsonValueProcessor implements JsonValueProcessor { private String format = "yyyy-MM-dd'T'HH:mm:ss"; private SimpleDateFormat sdf = new SimpleDateFormat(format); //处理数组的值 @Override public Object processArrayValue(Object value, JsonConfig jsonConfig) { return this.process(value); } //处理对象的值 @Override public Object processObjectValue(String key, Object value, JsonConfig jsonConfig) { return this.process(value); } //处理Date类型返回的Json数值 private Object process(Object value) { if (value == null) { return ""; } else if (value instanceof Date) return sdf.format((Date) value); else { return value.toString(); } } }
public class TestBean { private String name; private double price; //日期类型的时间 private Date time; //....此处省略setter和getter }
public class Test { //测试 public static void main(String[] args) { //初始化信息 TestBean testBean = new TestBean(); testBean.setName("1234"); testBean.setPrice(3.14145); testBean.setTime(new Date()); JsonValueProcessor jsonProcessor = new DateJsonValueProcessor(); JsonConfig jsonConfig = new JsonConfig(); //注册值处理器 jsonConfig.registerJsonValueProcessor(Date.class, jsonProcessor); String json = JSONSerializer.toJSON(testBean , jsonConfig).toString(); System.out.println(json); } }
结果符合我的要求如下:
{"name":"1234","price":3.14145,"time":"2010-11-09T19:46:29"}
ExtJs提交表单页面总回调failure解决方法
记得这个问题搞了一个多小时,真悲剧...
原因:回调success或failure是根据返回来的参数的json串中的"success"的值来决定的
例如返回:{"success":true}则调用success,如果返回{"success":false}则调用failure,因此在与Strust2中的Action中加入属性boolean success即可,并且需将其序列化为名字为"success",如下:
@JSON(name = "success") public boolean isSuccess() { return success; }
Action可通过设定success的属性值来控制是返回success或failure
javaEE中ClassNotFoundException小结
小小的总结一下:
1.ClassNotFoundException: javax.persistence.Entity
解决方法:加入Hibernate文件夹下的ejb3-persistence.jar即可
2.java.lang.ClassNotFoundException: javax.transaction.TransactionManager
解决方法:
引入如下几个包:
javaee.jar
jsf-api.jar
jsf-impl.jar
jstl-1.2.jar
jta.jar
很郁闷的是MyEclipse已经有了这几个包了,我用了笨方法,把这几个包复制出来,自个建个包目录然后引入工程即可。
ExtJs ComboBox提交值的问题
前不久做的一个登录框,下拉选择框是选择登录的角色,本来设定name='userBean.role',但是后台Action打印发现,得到的总是页面上的显示值,这显然不是我想要的,谷歌发现:
只要想得到真实设定的值,只需要把属性换成hiddenName即可,即hiddenName='userBean.role'
Could not find template in cache 错误的解决方法
今天,做Strust2的东东,启动发现报如下错误:
Could not find template in cache, creating new one的错误
百度之得解决方法,可以在Action的地方写入如下代码:(我是在BaseAction中的构造函数写入)
public BaseAction(){ try { freemarker.log.Logger.selectLoggerLibrary(freemarker.log.Logger.LIBRARY_NONE); logger.debug("加载[freemarker]成功"); } catch (ClassNotFoundException e) { logger.error("未找到类",e); } }
而后问题就消失了..
Strust2的json插件
最近在研究前端的交互部分,涉及到Struts2中使用json插件,总结下近日来看的一些材料和一些理解。以下这段摘自网上:
Json是一种轻量级的数据交换格式,JSon插件提供了一种名为json的ActionResultType 。一旦为Action指定了该结果处理类型,JSON插件就会自动将Action里的数据序列化成JSON格式的数据,并返回给客户端物理视图的JavaScript。简单的说,JSON插件允许我们JavaScript中异步的调用Action,而且Action不需要指定视图来显示Action的信息显示。而是由JSON插件来负责具体将Action里面具体的信息返回给调用页面。 |
其中使用方法中需要注意的几点:
1.要使用json插件就要在strust配置文件中的包继承关系改成json-default,如:
<package name="json" namespace="/json" extends="json-default">
2.选择序列化的结果可在strust中配置,可选择配置示例如下:
<!-- 序列化所有以get开头的方法 --> <result type="json" name="user"></result> <!-- 只序列化包含user.id属性 --> <result type="json" name="user"> <param name="includeProperties">user\.id</param> </result> <!-- 不序列化user对象的任何属性 --> <result type="json" name="list"> <param name="excludeProperties">user</param> </result> <!-- 只序列化根对象中的user --> <result type="json"> <param name="root">user</param> </result> <!-- 不序列化父类中的属性对象--> <result type="json"> <param name="ignoreHierarchy">false</param> </result>
3.对一些属性的特殊处理可在action代码中去特殊的序列化,如:
[3.1]默认情况下以get方法开头的都会序列化,如果不想序列化,在action中的方法要打上注解
@JSON(serialize=false)
[3.2]如果在属性get方法上面加@JSON(name="newName"),则返回的json数据中名称是指定的新名称
[3.3]@JSON(format ="yyyy-MM-dd'T'HH:mm:ss")设置用于格式化输出、解析日期表单域的格式。
[3.4]@JSON(deserialize=true)设置是否反序列化该属性