小方的Java博客

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  27 随笔 :: 17 文章 :: 115 评论 :: 0 Trackbacks

2007年2月11日 #

我在做公司某个框架时有这么一个需求。每次调用dwr的方法前要检查用户是否已经登录,否则就不能执行并且退到首页。

当然了,做拦截器有很多方式,但经过研究发现DWR自带很多插件,其中就有一个调用处理的插件。具体做法如下。

在web.xml里的DWR配置中加入一个参数:
<init-param>
            
<param-name>
                org.directwebremoting.extend.Remoter
            
</param-name>
            
<param-value>com.xxx.base.framework.web.MyDWRRemoter</param-value>
        
</init-param>

然后自己创建这个实现类。
public class MyDWRRemoter extends DefaultRemoter
{

    
public Replies execute( Calls calls )
    
{
        HttpSession session 
= WebContextFactory.get().getSession();
        ISessionContainer sc 
= ( ISessionContainer ) session.getAttribute( ISessionContainer.SESSION_CONTAINER_KEY );

        
//session检查
        if ( sc == null || sc.getUserInfo() == null )
        
{
            logOut();
            
return super.execute( new Calls() );
        }

        
else
        
{
            IUserInfo userInfo 
= sc.getUserInfo();
            
if(!SecurityFactory.getInstance().isOnline( userInfo.getUserID(), session.getId() ))
            
{
                logOut();
                
return super.execute( new Calls() );
            }

        }

        
return super.execute( calls );
    }


    
private void logOut()
    
{
        WebContext wct 
= WebContextFactory.get();
        Util utilThis 
= new Util(wct.getScriptSession());
        utilThis.addScript( 
new ScriptBuffer("logOut()"));
    }

}

其中,检查用户是否登录,如果没有登录就返回一个空的super.execute( new Calls());, 不能返回null否则会报错。
检查通过就调用super.execute( calls );  其实calls里还能获得很多信息。

最后大家注意logOut方法,这里用到了DWR2.0新功能:DWR反向调用,就是DWR调用javascript,具体用法大家网上可以查到,需要配置的,我这里就不多说了。补充一下,addScript调用的是html里的function logOut().

这样的话,如果用户session超时,或被管理员踢掉,一旦他做任何dwr操作就会被强迫登出到首页了。
posted @ 2008-12-05 20:42 方佳玮 阅读(2874) | 评论 (3)编辑 收藏

很久以前看某本书整理的,忘了哪本了,现在贡献出来。

1)在select语句中使用条件逻辑

1select ename,sal,   
2       case when sal <= 2000 then 'UNDERPAID'  
3            when sal >= 4000 then 'OVERPAID'  
4            else 'OK'  
5       end as status   
6from emp   


ENAME SAL STATUS
---------- ---------- ---------
SMITH 800 UNDERPAID
ALLEN 1600 UNDERPAID
WARD 1250 UNDERPAID
JONES 2975 OK
MARTIN 1250 UNDERPAID
BLAKE 2850 OK
CLARK 2450 OK
SCOTT 3000 OK
KING 5000 OVERPAID
TURNER 1500 UNDERPAID
ADAMS 1100 UNDERPAID
JAMES 950 UNDERPAID

FORD 3000 OK
MILLER 1300 UNDERPAID

 

2)从表中随机返回n条记录

1select *   
2  from (   
3    select ename, job   
4    from emp   
5    order by dbms_random.value()   
6  )   
7  where rownum <= 5 

 

3)按照子串排序

比如要从EMP表中返回员工名字和职位,并且按照职位字段最后2个字符排序

1select ename,job   
2  from emp   
3order by substr(job,length(job)-2

ENAME JOB
---------- ---------
KING PRESIDENT
SMITH CLERK
ADAMS CLERK
JAMES CLERK
MILLER CLERK
JONES MANAGER
CLARK MANAGER
BLAKE MANAGER
ALLEN SALESMAN
MARTIN SALESMAN
WARD SALESMAN
TURNER SALESMAN
SCOTT ANALYST
FORD ANALYST

 

4)处理空值排序

当被排序的列存在空值,如果希望空值不影响现有排序

1select ename,sal,comm   
2   from emp   
3order by comm nulls last 

 

ENAME SAL COMM
------ ----- ---------
TURNER 1500 0
ALLEN 1600 300
WARD 1250 500
MARTIN 1250 1400
SMITH 800
JONES 2975
JAMES 950
MILLER 1300
FORD 3000
ADAMS 1100
BLAKE 2850
CLARK 2450
SCOTT 3000
KING 5000

1select ename,sal,comm   
2  from emp   
3order by comm desc nulls first 


ENAME SAL COMM
------ ----- ----------
SMITH 800
JONES 2975
CLARK 2450
BLAKE 2850
SCOTT 3000
KING 5000
JAMES 950
MILLER 1300
FORD 3000
ADAMS 1100
MARTIN 1250 1400
WARD 1250 500
ALLEN 1600 300
TURNER 1500 0

5)根据数据项的键排序

比如如果job是“SALESMAN”,根据COMM排序,否则根据SAL排序

1select ename,sal,job,comm   
2  from emp   
3 order by case when job = 'SALESMAN' then comm else sal end  


ENAME SAL JOB COMM
---------- ---------- --------- ----------
TURNER 1500 SALESMAN 0
ALLEN 1600 SALESMAN 300
WARD 1250 SALESMAN 500
SMITH 800 CLERK
JAMES 950 CLERK
ADAMS 1100 CLERK
MARTIN 1250 SALESMAN 1300
MILLER 1300 CLERK
CLARK 2450 MANAGER
BLAKE 2850 MANAGER
JONES 2975 MANAGER
SCOTT 3000 ANALYST
FORD 3000 ANALYST


 

6)从一个表中查找另一个表中没有的值

比如要从DEPT中查找在表EMP中不存在数据的所有部门(数据中,DEPTNO值为40的记录在表EMP中不存在)

1select deptno from dept   
2minus   
3select deptno from emp 


 

7)在运算和比较时使用null值

null不会等于和不等于任何值,null和自己都不等于。以下例子是当comm有null的情况下列出比“WARD”提成低的员工。 (coalesce函数将null转换为其他值)

1select ename,comm,coalesce(comm,0)   
2  from emp   
3where coalesce(comm,0< ( select comm   
4                                     from emp   
5                                    where ename = 'WARD' )


ENAME COMM COALESCE(COMM,0)
---------- ---------- ----------------
SMITH 0
ALLEN 300 300
JONES 0
BLAKE 0
CLARK 0
SCOTT 0
KING 0
TURNER 0 0
ADAMS 0
JAMES 0
FORD 0
MILLER 0

 

8)删除重复记录

对于名字重复的记录,保留一个

1delete from dupes   
2 where id not in ( select min(id)   
3                      from dupes   
4                     group by name ) 

 

9)合并记录
比如如下需求:
如果表EMP_COMMISSION中的某员工也存在于EMP表,那么更新comm为1000
如果以上员工已经更新到1000的员工,如果他们SAL少于2000,删除他们
否则,从表中提取该员工插入表EMP_COMMISSION

1merge into emp_commission ec   
2using (select * from emp) emp   
3    on (ec.empno=emp.empno)   
4 when matched then  
5       update set ec.comm = 1000   
6       delete where (sal < 2000)   
7 when not matched then  
8        insert (ec.empno,ec.ename,ec.deptno,ec.comm)   
9       values (emp.empno,emp.ename,emp.deptno,emp.comm)  

 

10)用sql生成sql

1select 'select count(*) from '||table_name||';' cnts   
2  from user_tables;   


(user_tables是oracle的元数据表之一)

CNTS
----------------------------------------
select count(*) from ANT;
select count(*) from BONUS;
select count(*) from DEMO1;
select count(*) from DEMO2;
select count(*) from DEPT;
select count(*) from DUMMY;
select count(*) from EMP;
select count(*) from EMP_SALES;
select count(*) from EMP_SCORE;
select count(*) from PROFESSOR;
select count(*) from T;
select count(*) from T1;
select count(*) from T2;
select count(*) from T3;
select count(*) from TEACH;
select count(*) from TEST;
select count(*) from TRX_LOG;
select count(*) from X;

 

11)计算字符在字符串里的出现次数

判断字符串里有多少个‘ , ’

1select (length('10,CLARK,MANAGER')-   
2  length(replace('10,CLARK,MANAGER',',','')))/length(',')   
3  as cnt   
4from t1   


先计算原字符串长度,再减去去掉逗号的长度,这个差再除以‘,’的长度

 

12)将数字和字母分离


原数据是:

DATA
---------------
SMITH800
ALLEN1600
WARD1250
JONES2975
MARTIN1250
BLAKE2850
CLARK2450
SCOTT3000
KING5000
TURNER1500
ADAMS1100
JAMES950
FORD3000
MILLER1300
 1select replace(   
 2  translate(data,'0123456789','0000000000'),'0') ename,   
 3  to_number(   
 4    replace(   
 5    translate(lower(data),   
 6      'abcdefghijklmnopqrstuvwxyz',   
 7      rpad('z',26,'z')),'z')) sal   
 8  from (   
 9    select ename||sal data from emp   
10 )   

ENAME SAL
---------- ----------
SMITH 800
ALLEN 1600
WARD 1250
JONES 2975
MARTIN 1250
BLAKE 2850
CLARK 2450
SCOTT 3000
KING 5000
TURNER 1500
ADAMS 1100
JAMES 950
FORD 3000
MILLER 1300

思路是很复杂的,比如先去除数字,是先把所有数字翻译为0,然后用replace去掉0.


 

13)根据表中的行创建分割列表


表中数据:
DEPTNO EMPS
------ ----------
10 CLARK
10 KING
10 MILLER
20 SMITH
20 ADAMS
20 FORD
20 SCOTT
20 JONES
30 ALLEN
30 BLAKE
30 MARTIN
30 JAMES
30 TURNER
30 WARD

 1select deptno,   
 2    ltrim(sys_connect_by_path(ename,','),',') emps   
 3  from (   
 4  select deptno,   
 5    ename,   
 6    row_number() over   
 7       (partition by deptno order by empno) rn,   
 8    count(*) over   
 9      (partition by deptno) cnt   
10  from emp   
11  )   
12  where level = cnt   
13  start with rn = 1   
14    connect by prior deptno = deptno and prior rn = rn-1 


查询结果
DEPTNO EMPS
------- ------------------------------------
10 CLARK,KING,MILLER
20 SMITH,JONES,SCOTT,ADAMS,FORD
30 ALLEN,WARD,MARTIN,BLAKE,TURNER,JAMES

 

14)按字母顺序排序

 1select old_name, new_name   
 2  from (select old_name, replace(sys_connect_by_path(c, ' '), ' ') new_name   
 3          from (select e.ename old_name,   
 4                       row_number() over(partition by e.ename order by substr(e.ename, iter.pos, 1)) rn,   
 5                       substr(e.ename, iter.pos, 1) c   
 6                  from emp e, (select rownum pos from emp) iter   
 7                 where iter.pos <= length(e.ename)   
 8                 order by 1) x   
 9         start with rn = 1   
10        connect by prior rn = rn - 1   
11               and prior old_name = old_name)   
12 where length(old_name) = length(new_name) 


You would like the result to be:

OLD_NAME NEW_NAME
---------- --------
ADAMS AADMS
ALLEN AELLN
BLAKE ABEKL
CLARK ACKLR
FORD DFOR
JAMES AEJMS
JONES EJNOS
KING GIKN
MARTIN AIMNRT
MILLER EILLMR
SCOTT COSTT
SMITH HIMST
TURNER ENRRTU
WARD ADRW

 

posted @ 2008-08-07 14:41 方佳玮 阅读(2708) | 评论 (6)编辑 收藏

答辩后,心理有很多话要说,真是很不爽,也为中国软件业的未来捏一把汗。如果此文让某些读者感觉不爽,就当没看过,在此先向你道歉。
 
本周5是我们计算机专业毕业设计答辩日,我提前4天来到学校,带着3月份早就完成的毕业设计。真是让我大吃一惊,很多同学竟然都下载或者花钱买了毕业设计或者找人帮忙做来交差,这个数量我估计至少有5成。我的一个好友,更是夸张,什么都没做,要我帮他在2天内搞定,我慌了,真把我当超人了,不过还好,由于她那个东西确实没什么内容,我赶了一下还是帮她搞定了,实在是没啥内容的毕业设计。最搞笑的是还有些同学。。。,由于不是自己做的东西,而且连代码也看不懂,运行出错都不知如何解决,只会找别人求助,还天真地说:奇怪,怎么不行呢?原来明明看到可以运行的。。。。 我要他自己去debug一下,结果,连开发工具也没用过,怎么在开发工具里跑一个工程debug也根本不会,我再次无话可说。
 
同学们啊,你们不是高中生,你们是重点大学计算机专业应届毕业生啊,怎么就像没读过大学一样,你们到底在4年里干了什么啊。
 
然后更让人心寒的是:答辩时,很多老师都自己什么也不会,或者只会皮毛,看着同学的毕业设计,除了问点需求问题,再也问不出任何技术问题了,最后就草草答辩完,给个分数就算过了。我在答辩时,也懒得把架构和技术应用来说了,实在是对牛弹琴。学生堕落,教师应付,学校乱搞扩招,公司高薪招不到人才,中国软件业的未来有何希望!
 
当然,还是有10%左右的学生很优秀,有些做了很不错的java ee程序,有些自己研究做了简易3D游戏引擎,还有些同学水平不怎么样,但通过自己努力独立完成了,虽然做得不怎么好,但学到很多东西,也是自己劳动汗水,但是这些同学太少太少。。。
posted @ 2007-06-18 15:43 方佳玮 阅读(1583) | 评论 (6)编辑 收藏

选自《Professional Javascript For Web Developers》

其它方式:对象冒充,call(),apply(),原型链都有不少缺点这里就不一一介绍了,想了解的可以去看一下这本著作的第4章节。

这种方法用对象冒充继承属性,用原型链继承方法,代码如下
function  ClassA(sColor){
    
this .color  =  sColor;
}

ClassA.prototype.sayColor 
=   function (){
    alert(
this .color);
}

function  ClassB(sColor, sName){
    ClassA.call(
this . sColor);
    
this .name  =  sName;
}

ClassB.prototype 
=   new  ClassA();

ClassB.prototype.sayName 
=   function (){
    alert(
this .name);
}

测试:
var  objA  =   new  ClassA( " red " );
var  objB  =   new  ClassB( " blue " " Nicholas " );
objA.sayColor(); 
// red
objB.sayColor();  // blue
objB.sayName();   // Nicholas

其它好方法,请参考zlnherit库和xbObjects
posted @ 2007-03-03 15:44 方佳玮 阅读(1350) | 评论 (0)编辑 收藏

1.有个大大提高性能的建议:

比如得到list 是5个班级,然后要得到5个班级的所有学生

垃圾办法:5次通过级联获得,等于执行5条sql语句

好办法:

this .getSession().createQuery(
        
" from User a,Clazz b where a.clazz=b and b in(:clazz) " )
 .setParameterList(
" clazz " , list)
 .list();

仅执行一条


2.还有个很实用的方法,如何通过hql语句返回多个po

List list  =   this .getSession().createQuery(
 
" from User a,Clazz b where a.clazz=b " ).list();

// 使用的时候:
Iterator it  =  list.iterator();
  
while (it.hasNext()){
 Object[] vo 
=  (Object[])it.next();
 User user 
=  (User)vo[ 0 ];
 Clazz clazz 
=  (Clazz)vo[ 1 ];
 System.out.println(user.getUserName() 
+   " , "   +  clazz.getClassName());



3.我们全部用一对一,多对一等。如果过滤有问题,有个办法

List students  =   this .getSession().createFilter(clazz.getStudents(), " where this.status='A' " ).list(); 
posted @ 2007-02-14 23:30 方佳玮 阅读(473) | 评论 (0)编辑 收藏

选自《Professional Javascript For Web Developers》

其它方式:工厂方式,构造函数方式,原型方式都各有各的大缺陷,这里就不一一介绍了,想了解的可以去看一下这本著作的第3章节。

1. 混合构造函数/原型方式

function  Car(sColor, iDoors, iMpg) {
  
this .color  =  sColor;
  
this .doors  =  iDoors;
  
this .mpg  =  iMpg;
  
this .drivers  =   new  Array(“Mike”, “Sue”);
}

Car.prototype.showColor 
=   function  () {
  alert(
this .color);
};

var  oCar1  =   new  Car(“red”,  4 23 );
var  oCar2  =   new  Car(“blue”,  3 25 );

oCar1.drivers.push(“Matt”);

alert(oCar1.drivers); 
// outputs “Mike,Sue,Matt”
alert(oCar2.drivers);  // outputs “Mike,Sue”

优点:具有其它方式的优点而没有其它方式的缺点
不足:封装性欠缺

2 . 动态原型方式

function  Car(sColor, iDoors, iMpg)  {
  
this .color  =  sColor;
  
this .doors  =  iDoors;
  
this .mpg  =  iMpg;
  
this .drivers  =   new  Array(“Mike”, “Sue”);

  
if  ( typeof  Car._initialized  ==  “undefined”)  {
    Car.prototype.showColor 
=   function  ()  {
      alert(
this .color);
    }
;

    Car._initialized 
=   true ;
  }

}


优点:封装性比上一个方式更好
不足:就是看上去奇怪一点,呵呵


总之,以上2种方式是目前最广泛使用的,尽量使用它们避免不必要的问题。

posted @ 2007-02-11 17:34 方佳玮 阅读(6146) | 评论 (1)编辑 收藏