文章分类 » Blog my Blog

JS操作cookie实现单点登录

对于单点域名共享登录信息,我建议使用cookie是比较好的。

用cookie是因为它可以共享信息。
cookie是不能跨域访问的,但是在二级域名是可以共享cookie的。
然后你把你的项目统一平台,域名也统一,这样就可以实现cookie的单点登录了。
比如:http://tieba.baidu.com
http://mp3.baidu.com
这样的就算是统一域名。而二级域名可以共享cookie。
cookie的四个可选属性:
1 cookie的生存期属性:expires;默认情况下,cookie只在浏览器会话期存在.退出浏览器就丢失;可以用expires设置时间;退出浏览器后就不会丢失并存为客户端浏览器的cookie文件;过了时间后cookie失效,还会自动删除cookie文件.
2 path属性:默认情况下,在同一个目录下文件可以调用;
3 domain属性:例如设成”.baidu.com”则在.baidu.com下的所有服务器下的文件都可以调用cookie.
4 安全属性:默认情况下为false;用http协议不安全传输;true:用https等协议安全传输.
Javascript代码

Javascript代码  收藏代码
  1. /**
  2. 函数名称:getCookie
  3. 函数功能:获取指定名称的cookie的值
  4. 输入参数:需要测试的字符串
  5. 返回参数:
  6. */
  7. function getSSOCookie()
  8. {
  9.     var arrStr = document.cookie.split(“; “);
  10.     for(var i = 0;i < arrStr.length;i ++){
  11.         var temp = arrStr[i].split(“=”);
  12.         if(temp[0] == “sso”) {
  13.           return unescape(temp[1]);
  14.         }
  15.     }
  16.     return “”;
  17. }
  18. /**
  19. 函数名称:addCookie
  20. 函数功能:添加cookie
  21. 输入参数:需要测试的字符串
  22. 返回参数:
  23. */
  24. function addSSOCookie(objValue)
  25. {
  26.     var str = “sso” + “=” + escape(objValue);
  27.     if(true){//为0时不设定过期时间,浏览器关闭时cookie自动消失
  28.         str += “; path=/”;
  29.     }
  30.     document.cookie = str;
  31. }
  32. /**
  33. 函数名称:delCookie
  34. 函数功能:删除cookie
  35. 输入参数:需要测试的字符串
  36. 返回参数:
  37. */
  38. function delCookie()
  39. {//为了删除指定名称的cookie,可以将其过期时间设定为一个过去的时间
  40.     var date =  new  Date();
  41.     date.setTime(date.getTime() – 10000);
  42.     document.cookie = “sso” + “=a; expires=” + date.toGMTString()+”; path=/”;
  43. }

用户在统一加载平台认证系统认证通过后,使用addSSOCookie,用户权限信息保存到了cookie中,其他平台通过调用getSSOCookie,取得用户信息。这样用户就可以不再受平台限制,而实现自由访问各个系统了。

在addSSOCookie方法中,没有设置cookie的失效时间,这样在浏览器关闭后,cookie就自动消失。注意:这样cookie的有效性只能在同一浏览器进程,如果重新打开了一个浏览器进程,cookie信息是获取不到的,也就是单点登录只能在同一个浏览器进程有效。如果想在不用浏览器进程中共享cookie信息,那就设置失效时间,如下:
Javascript代码

Javascript代码  收藏代码
  1. function addCookie(objValue,objHours){//添加cookie
  2.            var str = “sso”+ “=” + escape(objValue);
  3.             if(objHours > 0){//为0时不设定过期时间,浏览器关闭时cookie自动消失
  4.                 var date = new Date();
  5.                 var ms = objHours*3600*1000;
  6.                 date.setTime(date.getTime() + ms);
  7.                 str += “; expires=” + date.toGMTString()+”; path=/; domain=.hanj.com”;
  8.             }
  9.             document.cookie = str;
  10.         }

这样cookie在指定的时间后失效。但这样安全性不能保证,如果时间设置太短,用户在使用中,可能cookie就失效了,需要重新登录。如果时间过长,用户在下次访问,或电脑重起访问,cookie还在有效期中,有可能别其他人使用。cookie不能准确的删除,存在安全隐患。

java使用sql之使用for update锁定表

一:

1>首先for update是对表的行进行锁定。锁定就好比我们学java Thread那一章时,为某个线程的run()枷锁,当实例化出来多个线程时,它必须一个线程全部执行完后,释放锁其他线程才有机会运行。本文for update功能上一样,就是为一个select语句枷锁,这样在对这个表进行update ,delete时就会处于等待状态,等待selec执行commit或rollback(相当于线程释放锁)后,才可以对表进行更改或删除。

怎样看效果呢?1:首先在“运行”–>cmd–>连接数据库 执行select * from emp for update

2 :然后在打开另一个窗口(就相当于创建了两个用户):“运行”–>cmd–>连接数据库  执行update emp set sal=100;你会发现它不执行了。

2>那马for update与for update of 有神马区别呢?

1.select * from Table1 for update 锁定表的所有行,只能读不能写

2  select * from Table1 where id = 1 for update 只锁定id=1的行

3  select * from Table1 a join Table2 b on a.id=b.id for update 锁定两个表的所有记录

4 select * from Table1 a join Table2 b on a.id=b.id where a.id = 10 for update 锁定两个表的中满足条件的行

5. select * from Table1 a join Table2 b on a.id=b.id where a.id = 10 for update of a.id 只锁定Table1中满足条件的行

for update 是把所有的表都锁点 for update of 根据of 后表的条件锁定相对应的表

3>关于oracle:select…for update of columns

按照1>步骤执行1:select * from emp for update of sal在另一个窗口中执:2:update emp set job=’clerk’ where empno=10;按照2>的的思维我们可能认:“1”只锁定了emp表的sal列,其实不然当运行“2”时,我们发现它任然不执行,所以for update of columns 是锁定的与sal相关的行。那么for update 与for update of 有神吗区别呢?区别在于多表连接时;

例如:

按照1>分别执行 select ename,dname from emp,dept where emp.deptno=dept.deptno for update;

另一窗口执行:update dept set dname=’haha’where deptno=10;我们发现dept表不能更改

当我们在 select ename,dname from emp,dept where emp.deptno=dept.deptno for update of sal;时

update dept set dname=’haha’where deptno=10;可以在执行了。

由此我们可以综结出:for update of columns 用在多表连接锁定时,可以指定要锁定的是哪几张表,而如果表中的列没有在for update of 后面出现的话,就意味着这张表其实并没有被锁定,其他用户是可以对这些表的数据进行update操作的。这种情况经常会出现在用户对带有连接查询的视图进行操作场景下。用户只锁定相关表的数据,其他用户仍然可以对视图中其他原始表的数据来进行操作。

4>关于nowait与wait

SELECT … FOR UPDATE [OF column_list][WAIT n|NOWAIT][SKIP LOCKED];
1:其中:

OF 子句用于指定即将更新的列,即锁定行上的特定列。

NOWAIT不进行等待,如果这条语句的锁没被释放,则会直接报出:系统资源正忙
WAIT 子句指定等待其他用户释放锁的秒数,防止无限期的等待。
“使用FOR UPDATE WAIT”子句的优点如下:
1防止无限期地等待被锁定的行;
2允许应用程序中对锁的等待时间进行更多的控制。
3对于交互式应用程序非常有用,因为这些用户不能等待不确定
4 若使用了skip locked,则可以越过锁定的行,不会报告由wait n 引发的‘资源忙’异常报告 :

2:现在执行如下操作:

在plsql develope中打开两个sql窗口, 在1窗口中运行sql
select * from t where a=’1′ for update;
在2窗口中运行sql1
1. select * from t where a=’1′; 这一点问题也没有,因为行级锁不会影响纯粹的select语句
再运行sql2
2. select * from t where a=’1′ for update; 则这一句sql在执行时,永远处于等待状态除非窗口1中sql 被提交或回滚。
如何才能让sql2不等待或等待指定的时间呢? 我们再运行sql3
3. select * from t where a=’1′ for update nowait; 则在执行此sql时,直接报资源忙的异常。
若执行 select * from t where a=’1′ for update wait 6; 则在等待6秒后,报 资源忙的异常。 如果我们执行 sql4
4. select * from t where a=’1′ for update nowait skip Locked; 则执行sql时,即不等待,也不报资源 忙异常。
现在我们看看执行如下操作将会发生什么呢?
在窗口1中执行:
select * from t where rownum<=3 nowait skip Locked;
在窗口2中执行:
select * from t where rownum<=6 nowait skip Locked;
select for update 也就如此了吧,insert、update、delete操作默认加行级锁,其原理和操作与select for update并无两样。
select for update of,这个of子句在牵连到多个表时,具有较大作用,如不使用of指定锁定的表的列,则所有表的相关行均被锁定,若在of中指定了需修改的列,则只有与这些列相关的表的行才会被锁定.

二:

1:

如果你想删除或者更新被Select For Update引用的记录,你可以使用Where Current Of语句

 

[sql]
  1. DECLARE
  2.   CURSOR CUR_NAME IS
  3.     SELECT * FROM EMP WHERE deptno=10 FOR UPDATE OF sal;
  4. BEGIN
  5.   FOR REC IN CUR_NAME LOOP
  6.     UPDATE EMP SET sal =100 ;
  7.   END LOOP;
  8. END;

上述pl/sql执行过之后我们发现emp表中所有的sal列数据都被更改,此时我们只想更改跟游标对应的行,所以我们又到where current of执行游标遍历时的当前行就好像for(int i=0;i++;i<10){}where current of与“i”的功能相似。所以当我们想执行游标影响的行时,上我们可以把上面pl/sql快改为:

 

[sql]
  1. DECLARE
  2.   CURSOR CUR_NAME IS
  3.     SELECT JOB FROM EMP WHERE deptno=10 FOR UPDATE OF sal;
  4. BEGIN
  5.   FOR REC IN CUR_NAME LOOP
  6.     UPDATE EMP SET sal =100 WHERE CURRENT OF CUR_NAME;
  7.   END LOOP;
  8. END;

Struts1开发流程描述

我们在这篇文章将会一步一步的讲解Struts的应用,以这样的形式打开Struts一道道神秘的大门,通过这样的过程,相信也能激起你在应用开发中如何应用Struts的灵感。如果你对Struts的一些术语不是很清楚的话,可以参考本系列前一篇对Struts作大体介绍的文章。
再次重复一遍,本文需要读者有如下几方面的知识和经验:JSP,Servlets,自定义标签库(CustomTaglibraries)和XML。此外,在本文中,我还会用到Jakarta项目组其他一些好东东,比如Tomcat(实现Servlet和JSP官方标准的Servlet容器,通俗的讲就是一个JSP的Web啦)和Ant(基于Java的自动编译发布工具,这可是好东东啊)。
作为一名一直使用前沿技术开发了诸多应用的技术人员,我一直坚信掌握新技术,理解该技术开发的逻辑是至关重要的。但这往往就是陷住我们学习步伐的泥潭,正因如此,我打算将利用Struts开发的一套完整流程作为我们教学的案例。该流程的这个案例可谓“麻雀虽小、五脏据全”,你完全可以将这个流程应用到你手头那些复杂庞大的项目中,至少在我们的大项目中应用这个流程效果不错。
有开发复杂商业应用的开发人员都知道,客户的需求总是在不停变幻,所以如果有一套规范的开发流程来遵循,当客户提出新的需求时,我们至少可以明确哪些“无理”需求其实是合理可行的。好,接下里我将在我的这个例子中向各位展示和应用整个流程。
本文中的示例代码是StrutsSample应用中的一部分,包括build.xml的完整代码可以到此处http://www.onjava.com/onjava/2001/10/31/examples/StrutsPartII.jar下载。
Struts开发过程
从Struts发布的版本号可以看出,Struts是个新玩意,她有好几个部分组成,明智的你如果搞清楚了何时该开发完成合适的部分,那将会更好的利用我们的开发时间。从我所开发的几个利用Struts应用中,我大致总结出如下这个比较有效的开发步骤:
1,明确应用需求;
2,由用户输入和获取数据的角度出发,明确和设计出每一个用户界面;
3,确定用户界面的进入路径;
4,由应用逻辑确定动作映射表;
5,由设计完成的用户界面开发其所用到的类和应用函数;
6,由用户界面中的数据开发ActionForm和相应的数据校验方法;
7,ActionMapping中将会被调用相应的Action或转到相应的JSP页面,这一步我们先开发这些Action;
8,开发商业应用逻辑,就是相应的JavaBean、EJB或其他东东;
9,开发由ActionMapping定义的系统工作流程完成对应的JSP页面;
10,完成系统:struts-config.xml和web.xml;
11,编译/测试/发布。
明确应用需求
开发任何应用系统的第一步就是收集用户需求。不管一个用户逻辑初看上去多么合理,但总有可能在开发时才发现它比看上去要难得多。所以,建议拟一份明确的用户需求列表,这不只是出于开发的目的,还能通过该表分析用户需求以确定哪些地方可能需要花更多的精力。
在我们这个StrutsSample项目中,应用需求就是:
作为一个展示Struts框架应用的完整例子,本示例完成的功能是用户登录。目的只为明确Struts的应用,本示例将不会涉及到一般复杂应用系统中可能应用的安全、、EJB开发等等相关技术。
设计用户界面
这个应用中,包括如下三个用户界面:
1)登录界面,用于用户名和密码输入;
2)当登录用户为合法用户时的欢迎界面;
3)当登录失败时的错误提示界面。
确定用户界面的进入路径
1)登录界面作为这个应用的默认页面;
2)欢迎界面只有当成功登录后才能进入;
3)任何可能发生错误的页面能可以进入错误提示界面;
由应用逻辑确定ActionMapping
ActionMapping为整个应用确定的“线路图”,在配置文件struts-config.xml对ActionMapping进行定义,通过转发请求(forward)来理顺应用的处理流程,确定应用中每个用户请求对应的动作。
通常我们在开发过程中就逐步确定了ActionMapping所需的,开发代码的过程就是在由草稿开始一步步完善struts-config.xml的过程。当Action类处理完用户请求后,其返回的的forward就是在ActionMapping中定义的一个。一个Action返回的forward完全有多种可能,尽管一个Action一般只定义其相关的几个forward。那么,如果有多个Action都可能返回的同一个forward,那么就可以将其定义为全局转发(globalforward)。这类似于C中的头文件中全局变量,如果在struts-config.xml描述中,某一个forward并不是在当前Action描述中定义的而是全局定义的,那么这个全局的将起作用,同样,一个Action中当前定义的forward将覆盖全局定义。在我们所给的这个简单实例中,我们定义了全局forward――“error”,当某Action返回的forward是“error”这个映射,那么Errorpage.jsp页面将会显示给用户,尽管当前Action并没有对其定义。
我们继续不断的开发,项目日渐完善,项目相关的配置文件也会越来越详细。在下面的例子中,我们将以StrutsSample中用到的struts-confug.xml文件为例,学习globalforward和一个Action中相关映射的定义。下面定义了一个名为“login”的Action,其为com.oreilly.actions.LoginAction的实例,当Action处理用户登录成功后将一个名为”success”的forward返回,用户也就会看到Welcome.jsp页面,如果登录失败,Action将返回对应的forward以再显示Login.jsp给用户,而如果处理过程中发生其他错误,Action将返回全局定义的forward――“error”,用户也就会看到错误提示页面Errorpage.jsp。
元素的相关属性–>
以下只列出常用属性,其他请参考org.apache.struts.action.ActionMapping的相关文档
path-当前Action对应的用户请求URI路径
type-实现当前Action的Javaclass的完整名字
name-当前Action中用到的ActionForm的名字,其具体在配置文件其他地方另有详细定义
unknown-如果将该属性设置为true,那么就是声明这个Action将处理整个应用中所有未找到相应处理Action的请求,当然,一个应用系统中也只会有一个Action的unknown属性可以设为true
scope-Action中所用到的ActionForm的生存期,可以为“request”或“session”,随着生存期的设置,该Action也会在相应的时间被创建
input-该Action中相关ActionForm获取用户输入的输入页面,当将ActionForm设为自动验证输入数据,发现不合法数据返回错误时,将返回该页面
validate-如果本属性为true则在Action动作之前其对应的ActionForm的validate方法会自动被调用,一般用以验证用户输入的数据
forward元素-定义当前Action相关的ActionForward
–>
type=”com.oreilly.actions.LoginAction”
name=”loginForm”
scope=”request”
input=”/Login.jsp”>
在前一篇文章中,我们曾说过,struts-config.xml就是MVC模式的的Controller。在确定struts-config.xml中的配置时,应该多花些时间精力在上面,以保证每一个Action定义及其相关定义是符合应用的需求的。如果在项目开始没有详细的设计其定义,当将所有代码和配置集成到一起的时候,我们将不可避免的将各部分的代码和配置完全重新组织一遍。
我们当前的例子StrusSample因为只是处理用户登录,所以只需要一个Action。一个应用系统中所要用到的Action的多少完全依应用的大小而定。一旦整套Action的映射完全的定义出来后,我们就可以一个一个开发其具体实现的Action和ActionForm类,并逐渐将完成的部分一点一点集成起来。
由设计完成的用户界面开发其所用到的类和应用函数
所有ActionForm的实现类都是org.apache.struts.ActionForm的子类。一个ActionForm是与页面上的输入表单相关联的,而且ActionForm的实现还可以对用户输入数据的合法性进行验证。作为一个JavaBean,ActionForm有Set和Get方法,当一个页面中表单被提交时,系统将自动调用Set方法将数据放入ActionForm中,而Get方法将为在Action中操作这些数据所提供。一般来说,处理表单中的所有数据,并进行合法性验证都完全可以交由ActionForm来完成。在应用中,就我个人而言,倾向于将ActionForm和Action划分到不同的包中,因为当一个页面中要用到几对ActionFrom和Action时,都放在一个包内会混淆的。