| Version 7 (modified by wuyuanbo, 9 years ago) (diff) |
|---|
1.java类中EnvUtils使用优化
在servlet处理请求时,EnvFilter中会调用EnvUtils.getEnv()实例化Env,并对实例属性进行设置,这些都是必要步骤,在使用EnvUtils.getEnv()时如果跳过这些步骤,调用env中一些需要用到request、response、servletContext属性的方法时会出现NullPointerException错误。
//evn过滤器代码 org.gelivable.web.EnvFilter : 62
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
......
Env env = EnvUtils.getEnv();
envMap.put(env, "");
try {
//设置了env的属性
env.setRequest((HttpServletRequest) request);
env.setResponse((HttpServletResponse) response);
env.setServletContext(servletContext);
request.setAttribute("env", env);
chain.doFilter(request, response);
}
......
}
在聚超值项目中,entity类(service偶尔也会出现)中经常会用env获取service或dao类实例的代码。
public class User {
......
public UserPurchasingInfo getInfo() {
......
UserPurchasingInfo info = EnvUtils.getEnv().getBean(GeliDao.class).find(UserPurchasingInfo.class, this.userId);
//或者 UserPurchasingInfo info = EnvUtils.getEnv().getBean(UserPurchasingInfoService.class).find(this.userId);
......
}
......
}
这种代码至少在三种情况运行用会出现NullPointerException错误:
1.在单元测试中运行。
2.不依赖于servlet的定时任务中运行。
3.在处理servlet的请求时,通过代码发起的新线程中简单的调用EnvUtils.getEnv().getBean(xxx.class)获取某个类的实例会和1、2点一样出现错误。
原因
1、2点的错误原因比较明显,原因是在代码执行的时候没有经过过滤器,EnvUtils?.getEnv()只是把Env实例化了,env对象里的servletContext属性是空的,没有进行设置,调用的时候就报空指针异常了。
第3点报错的原因是因为EnvUtils.getEnv()用到了线程单例(代码如下),当线程第一次调用时threadLocal会实例一个Env对象,之后这个线程再调用都只返回这个对象,而且只能被这个线程调用,当在处理请求过程中如果新启了线程再调用EnvUtils.getEnv()时,threadLocal就会新实例一个Env对象,这个实例和1、2一样,没有设置env里的servletContext属性,调用env.getBean(xxx.class)的时候就会报空指针异常。
public class EnvUtils {
public static Env getEnv() {
return threadLocal.get();
}
public static void removeEnv() {
threadLocal.remove();
}
//通过EnvUtils获取的Env实例是线程单例的,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
private static final ThreadLocal<Env> threadLocal = new ThreadLocal<Env>() {
@Override
protected Env initialValue() {
return new Env();
}
};
}
优化方法
将非Controller的java类中的EnvUtils.getEnv().getBean(GeliDao?.class)改为GeliUtils.getDao(),
将EnvUtils.getEnv().getBean(xxxService.class)改为SpringCtxUtils.getBean(xxxService.class)。(SpringCtxUtils在cn.pconline.best.util目录下)
2.异常处理优化
项目中经常有异常被捕获后没有日志也没有打印,如果在程序执行过程中出现问题,不容定位到。
private String getMoreTopicText(long topicId, int type) {
try {
......
} catch (Exception e) {
}
return "";
}
![(please configure the [header_logo] section in trac.ini)](http://www1.pconline.com.cn/hr/2009/global/images/logo.gif)