◎筱米加步枪◎.Blog

Happy coding

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)设置是否反序列化该属性