??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
]]>
w上的衣服没注意及时配合气候,得瑟感冒了,今天本来惛_Ҏ(gu)钟v床写写早惛_的代码,可一觉醒来已l八点了Q哎
L开始肆虐,伙Q该ȝw体了! 阅读全文
]]>
牢骚完毕来说说目前的J2EE做法。既然涉及到程Q那不免那两种QWFMC和BPELQ我们选择BPELQ原因是IBM支持BPELQ不要问我两U东襉KU更优秀Q我会告诉你Q你搞清楚了也没意义Q用户只怿IBM?br /> 既然用BPELQIBM的Websphere Process Server首当其冲Q项目组C几百万的软g和服务就开始开发了Q说实话QWPS真的是一个很好的SOA解决Ҏ(gu)Q但我个为绝对不适合中国政府、国企的程开发,因ؓ他无法很好的解决人工节点的问题,哪怕是引入了human taskQ于是我们又自己装了一层小的流E引擎,当然我所要说的重点不是这个,而是我们在wps中所需要的JCA方式l定的组件的实现方式QEJB+Spring+HibernateQ做好的EJB包可以以EJB Bind的Java component形式打入wps的assembly里,在bpel process中referenceq来可以了。下面我们主要说说EJB的实现?br /> ׃wps有个特点是在流E实例结束后删除其自带数据库中的所有实例数据,所以我们必d程的最后一部将数据记录在我们自q业务库中来,我们开发的EJB实Cq个功能?br />首先是业务逻辑Q业务逻辑分成三个包,ejb、face、pojoQ其中ejb是组件的本地接口Qface是组件的功能性接口,pojo是具体实现类?br /> 具体逻辑代码不脓(chung)了,贴一个我写的例子Q?br /> face中的功能接口Q?/p>
package
com.ideal.core.biz.face;
2
3
import
java.rmi.RemoteException;
4
5
public
interface
SimpleService
6
{
7
public
String sayHello(String message)throws Exception;
8
}
9
ejb中本地接口:package com.ideal.core.biz.ejb;
2
3import javax.ejb.EJBLocalObject;
4import com.ideal.core.biz.face.SimpleService;
5
6public interface SimpleLocal
7 extends EJBLocalObject, SimpleService
8{
9 public String sayHello(String message) throws Exception;
10}
11package com.ideal.core.biz.ejb;
2
3import javax.ejb.SessionBean;
4import javax.ejb.SessionContext;
5import javax.ejb.CreateException;
6import com.ideal.core.biz.face.SimpleService;
7import org.springframework.ejb.support.AbstractStatelessSessionBean;
8import java.rmi.RemoteException;
9
10public class SimpleBean
11 extends AbstractStatelessSessionBean
12 implements SimpleService
13{
14 SessionContext sessionContext;
15 private SimpleService m_simple_service;
16
17 public void onEjbCreate() throws CreateException
18
{
19 m_simple_service = (SimpleService) getBeanFactory().getBean("SimpleService");
20 }
21
22 public String sayHello(String message) throws Exception
23
{
String message = "";
try {
message = m_simple_service.sayHello(message);
}
catch (Exception ex)
{
this.sessionContext.setRollbackOnly();
throw new EJBException();
}
24 return message;
25 }
26}
27package com.ideal.core.biz.pojo;
2
3import com.ideal.core.biz.face.SimpleService;
4
5public class SimpleServiceImpl implements SimpleService
6{
7 IUserInfoDAO user_dao;
8 public SimpleServiceImpl()
9
{
10 }
11 public String sayHello(String message) throws Exception
12
{
13 Userinfo user = new Userinfo();
14 user.setName("2");
15 user.setPassword("2");
16 user.setUserid("2");
17 user_dao.saveUser(user);
18 user.setPassword("asddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd");
19 user_dao.saveUser(user);
20 return "hello," + message + "!";
21 }
22}
23
]]>
]]>
接着上文来说Q上文所讨论的权限设计是一条思\Q但既然是web应用Q少不了数据库的支持Q本文我们来讨论一下数据库的设计。(以下x及思\仅仅代表本h拙见Q?br /> 说到权限的数据库设计Q必先理清权限中几种实体及其关系Q此部分惛_有过设计权限l验的同仁都知道怎么设计了,|上摆渡一下也是一裤衩子一裤衩子的Q我们就在最q_直观的数据库关系的基上来建立权限。下面是我的几个表(所有的表都带有一个pk_id,作ؓ表的自动生成的唯一主键Q:
用户?T_UserInfo)Q?br />/**//*==============================================================*/
2/**//* Table: T_UserInfo */
3/**//*==============================================================*/
4create table T_UserInfo
5(
6 pk_id NUMBER not null,
7 name VARCHAR2(20),
8 sex BOOLEAN,
9 age int,
10 emp_num NUMBER,
11 polity int,
12 unit VARCHAR2(50),
13 department VARCHAR2(20),
14 specialty int,
15 position VARCHAR2(10),
16 offtel VARCHAR2(20),
17 famtel VARCHAR2(20),
18 post_state VARCHAR2(10),
19 remark VARCHAR2(100),
20 constraint PK_T_USERINFO primary key (pk_id)
21);
/**//*==============================================================*/
2/**//* Table: T_RoleInfo */
3/**//*==============================================================*/
4create table T_RoleInfo
5(
6 pk_id number not null,
7 role_name VARCHAR2(20),
8 role_desc VARCHAR2(100),
9 parent_role_id NUMBER,
10 constraint PK_T_ROLEINFO primary key (pk_id)
11);
/**//*==============================================================*/
2/**//* Table: T_ResourceInfo */
3/**//*==============================================================*/
4create table T_ResourceInfo
5(
6 pk_id NUMBER not null,
7 module_name VARCHAR2(20),
8 module_code VARCHAR2(10),
9 module_desc VARCHAR2(100),
10 privilege_name VARCHAR2(10),
11 privilege_code CHAR,
12 privilege_desc VARCHAR2(100),
13 constraint PK_T_RESOURCEINFO primary key (pk_id)
14);
15
例如角色aҎ(gu)据库表T_UserInfo有添加与删除的权限则该表应该按照如下配置Q?br />module_nameQh员信息;
module_codeQT_UserInfo
privilege_nameQ添加与删除
privilege_codeQ?
q里我们假设的是2?ơ方为添加权限,2?ơ方为添加权限,2?ơ方为删除权限,2?ơ方为更新权限,则拥有添加与删除权限应该ؓ2?ơ方+2?ơ方=6Q其?的几ơ方代表什么含义我们可以另外开个数据库表来配置Q或者xml文gQ此处我们忽略这些步骤。当然如果你的权限较多,譬如你还希望aq个角色对h员信息表有上传得权限Q我们可以将上传权限定义ؓ2?ơ方Q?6Q?6?6q制Cؓ10Q记录在数据库里的Ş式应该ؓ0x10如果a角色拥有d、删除、更新、上传权限,则a的权值应该ؓ2?ơ方+2?ơ方+2?ơ方+2?ơ方=30,?6q制来表C就应该?x1EQ记?6q制数据Q你不用担心位数不够?br />剩余的就是几张关p表了:
人员角色关系?T_R_User_Role)Q?br />/**//*==============================================================*/
2/**//* Table: T_R_user_role */
3/**//*==============================================================*/
4create table T_R_user_role
5(
6 pk_id NUMBER not null,
7 user_id NUMBER,
8 role_id NUMBER,
9 constraint PK_T_R_USER_ROLE primary key (pk_id)
10);
11/**//*==============================================================*/
2/**//* Table: T_R_role_resource */
3/**//*==============================================================*/
4create table T_R_role_resource
5(
6 pk_id NUMBER not null,
7 role_id NUMBER,
8 res_id NUMBER,
9 constraint PK_T_R_ROLE_RESOURCE primary key (pk_id)
10);
11
]]>
现在目开展v来了Q虽然目前我已经有了Ҏ(gu)限控制的一套方案,q且实施成了我的可重用框架代码,虽然目前的权限也是基于众星捧月的AOP思想Q但我至今对权限设计仍有两个疑惑Q?
疑惑一Q很多同行提出方案,惌在底层就截取用户权限Q控制用户对Ҏ(gu)或者类的访问。这样做的好处在于可以将pȝ功能与业务逻辑松散耦合Qƈ且实现简单,l构清晰Q三两个advisor、filterQ或者acegip搞定Q但在webE序中体现出了他的劣势,当我们将用户的访问拒l在业务逻辑之外的时候,我们此时是否应该抛出异常提示用户Q一旦提C用h有相应的权限Q我认ؓ对于用户来说Q这׃是一个perfect practice。由此得出,我们Ҏ(gu)׃应该让用户做此次操作Q而控制用h作的源头是界面Q也是_在界面上我们应该对用户的权限元?如添加按钮、功能菜单等)q行控制。此Ӟ一对矛监ևCQ要控制界面上Ş形色色的元素只有两种办法Q一Q将权限与你的界面结合v来设计,q将q背AOP的思想Q也使得pȝ控制模块的重用性大大下降,二,我们借鉴primeton的想法,权限控制的理念抽取出来Q单独做成一套权限系l,解决你所有的需要权限控制的pȝ需求,q样也有令h头痛的问题,你的所有想用它来控制权限的pȝQ必ȝ面上l一风格。或许这L方式对商业webpȝ是合适的Q毕竟需要你大刀阔斧个性化的地方不多,但我们却很难保证在未来几q内商业webpȝ的风g改变。再者,开发这么一个系l也不是一y而就的事Q在q个问题上一直让我困惑不巌Ӏ?/p>
疑惑二:大多应用的权限判定是Z权限字符串的Q但存储在数据库中的权限字符串能够判定的权限q不多,在我们这ơ项目中Q我引用了基于二q制?421权限判定法则Q我深深的感觉到权限字符串的弱势Q这使我惌v了中国古老一套数学理?“盈不术”,递增序列的魅力在我眼前滑q,
首先我来解释一下盈余不理论:有十只盒子,W一个盒子里放一个盘子,W二个盒子里放两只,W三个盒子里攑֛只,W四个盒子里攑օ只……第?ji)个盒子里?56只,W十个盒子放512只,即第N只箱子里?^(N-1)只盘子,一?023只。那么命题如下:?023q个数字之内QQ何一个数目都可以p十只盒子里的几只l合相加而成。那?????6?2?4?28?56?12q个序列Z么有q么个魔力?q个数列的特点:1、每Ҏ(gu)后一的二倍,2、每w比前面所有项的和大,而且?。这?是关键Q就因ؓq个1Q它才可以按1递增Q拼出d之内L一个整数。这个序列叫做超递增序列Q它是解册包问题的基础?、拼出d之内L一个整数可以由q个序列中的一些数构成Q且构成Ҏ(gu)唯一Q据说是密码学中的NP定理。譬如说q个数列d?0q个敎ͼ只能?6+4一U方法构成,由此延出来Q如果综合中q个数据代表一个权|我们可以解出它的所有构成参敎ͼ操作Q,?0q个数据Q我们可以挨个和序列中每一Ҏ(gu)位与Q得出来如果不等?Q就说明他是p个数构成的?
保存权值到intq是varchar对于我们来说是个问题Q当Ӟ保存字符串的好处是运压力小。我们可能听q一个故事,是把这个超递增序列延到第64,是那个术士和皇帝在国际象棋盘上要c粒的传说?4的和是一个天文数字!但计机本n是一个只认识二进制的机器Q很多程序员整天只关心架构,甚至不知道或者不兛_位操作是什么玩意,当然我们有朋友担心数据库的int不够长,那么既然可以保存一个只??l成的varchar字符ԌZ么不能保存一个十六进制的字符Ԍ有h规定varchar只能保存01吗?十六q制串的长度正好是二q制的四分之一?
由此我们可以无限制的扩展权值操作?
在最q的目里,我对权限的控制分成两个部分,W一是用户体验上,我设|了一个权限标{,从数据库中抽取权限信息,然后做到标签里,也凑或算成是界面AOP了,W二是底层的拦截,用了Spring 的AOPQؓ的是防止权限冲突Q双齐下。暂时解x限所需Q另外在法上我用了16q制的权限判别代码,虽然配置较麻烦,写完代码q要写文说明,不过也解决了权限J杂又多的问题,暂时p样了Q嘿嘿,以后有空再研I?