当前位置:文档之家› session与transaction详解

session与transaction详解

session与transaction详解
session与transaction详解

Spring 与Hibernate结合的细节源码分析(一)

@Transactional标记的方法使用session的两种情况:

(1)之前已经打开了session(如opensessioninview模式下),那么事务也会开启并将之前打开的session标记为旧session并开始事务,然后调用目标方法,再提交或回滚事务。接下来判断如果是旧SESSION,则事务结束释放数据库连接但不关闭

SESSION,如果还用此SESSION再开启事务,再绑定另外的连接(所以上文说单

SESSION并不等于同一个连接),最后由opensessioninview FILTER关闭

SESSION。由此可见即使使用了opensessioninview模式也不是响应用户后才

commit或rollback,而是在service层的@Transactional标记的方法执行完后进行commit或rollback。但在opensessioninview filter自己关闭session 时又会commit或rollbakc一次。在opensessioninview模式下打开sesson的时候并没有使session获得数据库连接而是在进入@Transactional标记的方法后

才使session获得数据库连接。@Transactional标记的方法执行完后事务管理程序会提交或回滚并释放session的数据库连接但不关闭session(已验证)。

(2)如果调用带有@Transactional标记的方法前没有打开session(没有与当前线程绑定的session)或者不是请求发起的调用(如计划任务Timer.schedule(...)发起的

SERVICE调用),那么流程为--在此方法打开SESSION,标志为新连接,开启事务,调

用目标,提交或回滚事务,释放数据库连接,判断如果是新SESSION,则关闭SESSION。

原文https://www.doczj.com/doc/8b6212556.html,/topic/579603

本文基于SPRING2.56,HIBERANTE3.25及Oracle10g classes14.jar驱动,介绍SPRING与HIBERNATE是如何配合的细节,如SESSION、事务、数据库连接何时打开与关闭;如果调用不是发自请求,不经过FILTER(如定时器对SERVICE调用),如何做到从头到尾只用一个SESSION?此时SESSION需不需要手动关闭?从SESSION取得的数据库连接需不需要关闭,看完本文,你会清楚里面每一个细节。

两种访问系统的路径:

1、request-->filters(spring and

struts)-->actions-->AOP(transaction)-->services-->dao-->db

2、timer(run)->AOP(transaction)-->services-->dao-->db

下面是调用链的图示

在WEB.XML配置了OpenSessionInViewFilter,整个请求只用一个SESSION,

在ACTION与SERVICE之间使用SPRING的AOP配置事务拦截器,所以事务范围涵盖整个SERVICE的方法调用,

DAO中一般使用SPRING的HibernateTemplate对象操作数据库

首先看OpenSessionInViewFilter在web.xml和事务拦截器相关配置

Xml代码

1.

2.

3. openSessionInViewFilter

4.

5. org.springframework.orm.hibernate3.support.OpenSessionInViewFilt

er

6.

7.

8. singleSession

9. true

10.

11.

12.

13./////SRPING 配置文件中事务拦截器相关配置

14.

15.

16. class="org.springframework.orm.hibernate3.HibernateTransactionManage

r">

17.

18.

19.

20.

21. class="org.springframework.transaction.interceptor.TransactionInterc

eptor">

22.

23.

24.

25.

26.

27. PROPAGATION_REQUIRED

28. PROPAGATION_REQUIRED

29. PROPAGATION_REQUIRED

30. PROPAGATION_REQUIRED

31. PROPAGATION_REQUIRED

32. PROPAGATION_REQUIRED,readOnly

33. PROPAGATION_REQUIRED,readOnly

34. PROPAGATION_REQUIRED,readOnly

35. PROPAGATION_NOT_SUPPORTED,readOnly

>

36.

37.

38.

39./////配置 service自动代理

40.

41.

42.

43.

44. *Service

45.

46.

47.

48.

49. transactionInterceptor

50.

51.

52.

//下面从FILTER开始分析代码

Java代码

1.//这是OpenSessionInViewFilter类的方法,请求到来时,此方法由父类

OncePerRequestFilter的doFilter()方法调用,

2.protected void doFilterInternal(

3. HttpServletRequest request, HttpServletResponse response, Filter

Chain filterChain)

4. throws ServletException, IOException {

5.

6. //取得SessionFactory实例,实际上就是调用

WebApplicationContext.getBean("beanName"),

7. SessionFactory sessionFactory = lookupSessionFactory(request);

8. //在lookupSessionFactory方法里看到原来此FILTER还支持配置

sessionFactory为的名字,默认就叫sessionFactory,如果想改成其它名字具体配置方式:

9. //在web.xml中,

name>sessionFactoryBeanNamesessionFactory

10.

11. //此次调用有无打开SESSION,有的话在finally块关闭

12. boolean participate = false;

13. //是否单SESSION模式(上文web.xml中配置了),注意这并不意味着每个请

求只用一个 connection,下文详解

14. if (isSingleSession()) {//这里我只分析单SESSION的情况,因为另一种情

况不是此filter推荐的用法,就懒得看了

15. // 单SESSION模式

16.

17. // 是否已经打开了SESSION,一般来说每个请求一开始是没有打开的

18. if (TransactionSynchronizationManager.hasResource(sessionFactory

)) {

19. participate = true;

20. }

21. else {

22. logger.debug("Opening single Hibernate Session in OpenSessio

nInViewFilter");

23. //打开session,注意想在整个请求内部都用SESSION,这一句还不够,

还必须有下面一句。 getSession方法如何打开SESSION接下来讲解

24. Session session = getSession(sessionFactory);

25. //把SESSION放入SessionHolder,再用sessionFactory作为 KEY,

SessionHolder作为VALUE放入MAP,再把此MAP放入ThreadLocal

26. //------不熟ThreadLocal看这,其他人跳过,ThreadLocal有两个

主要的方法,get() 和set(value),用法和MAP差不多,只是不需要提供KEY,27. //KEY就是当前线程,这样对于每个线程,只能往ThreadLocal里放

入一个对象,在此放入了一个MAP。

28. //不同的线程可以同时操作这个ThreadLocal对象,放入内容,因为

各自有着不同的KEY------//

29. TransactionSynchronizationManager.bindResource(sessionFactor

y, new SessionHolder(session));

30. }

31. }

32. else {//非单 Session模式,本文不讨论此情况

33. // deferred close mode

34. if (SessionFactoryUtils.isDeferredCloseActive(sessionFactory)) {

35. // Do not modify deferred close: just set the participate fl

ag.

36. participate = true;

37. }else {

38. SessionFactoryUtils.initDeferredClose(sessionFactory);

39. }

40. }

41.

42. try {//SESSION 已打开,往下调用,

-->action-->aop-->service-->dao-->db

43. filterChain.doFilter(request, response);

44. }

45.

46. finally {//目标调用完成,关闭SESSION

47. if (!participate) {//如果上文打开了SESSION

48. if (isSingleSession()) {

49. //从ThreadLocal里面把上面放入的MAP移除

50. SessionHolder sessionHolder =

51. (SessionHolder) TransactionSynchronizationManage

r.unbindResource(sessionFactory);

52. logger.debug("Closing single Hibernate Session in OpenSe

ssionInViewFilter");

53. //关闭SESSION

54. closeSession(sessionHolder.getSession(), sessionFactory)

;

55. }

56. else {

57. // deferred close mode

58. SessionFactoryUtils.processDeferredClose(sessionFactory)

;

59. }

60. }

61. }

62.}

getSession方法

Java代码

1.//OpenSessionInViewFilter类,还是上面那个FILTER类

2.protected Session getSession(SessionFactory sessionFactory) throws DataA

ccessResourceFailureException {

3. //取SESSION,下文讲解

4. Session session = SessionFactoryUtils.getSession(sessionFactory, tru

e);

5. //设置提交方式,getFlushMode默认返回FlushMode.NEVER,

6. //NEVER看名字好像是永不提交,其实是外部显式调用FLUSH时才提交的意思,

也许是因为名字不好,此变量已过时了,新的名字是FlushMode.MANUAL

7. //如果请求是写操作,会在打开事务时被改成AUTO,

8. FlushMode flushMode = getFlushMode();

9. if (flushMode != null) {

10. session.setFlushMode(flushMode);

11. }

12. return session;

13.}

SessionFactoryUtils.doGetSession方法

Java代码

1.//SessionFactoryUtils类,取SESSION,此工具方法在以下两种情况被调用:在

FILTER层开SESSION和在DAO层取SESSION去查数据库

2.//在FILTER层调用时,没有事务(执行此方法的后半部份),在DAO层调用时,由

于经过了AOP,开启了事务(执行方法的前半部份)

3.//在没有JTA事务的环境中,此方法只是打开或取得一个SESSION,关于事务的事

什么也没有做。

4.private static Session doGetSession(

5. SessionFactory sessionFactory, Interceptor entityInterceptor,

6. SQLExceptionTranslator jdbcExceptionTranslator, boolean allowCre

ate)

7. throws HibernateException, IllegalStateException {

8.

9. Assert.notNull(sessionFactory, "No SessionFactory specified");

10. //上文放入的sessionHolder在这里被取出来,如果调用来源于FILTER,则还

没有放入,取出空,如果 DAO层的调用,那么就不为空了

11. SessionHolder sessionHolder = (SessionHolder) TransactionSynchroniza

tionManager.getResource(sessionFactory);

12. ///--------------前半部份-------------------//////////////

13. if (sessionHolder != null && !sessionHolder.isEmpty()) {// DAO中的

调用,取得非空值,

14. Session session = null;

15.

16. //如果:事务是否已开始 && sessionHolder中没有SESSION或只有一个

默认 SESSION

17. if (TransactionSynchronizationManager.isSynchronizationActive()

&&

18. sessionHolder.doesNotHoldNonDefaultSession()) {

19. //取出SESSION,里面主要判断一下SESSION有没有被关闭

20. session = sessionHolder.getValidatedSession();

21. //session不为空 && 事务没有开始,

22. if (session != null && !sessionHolder.isSynchronizedWithTran

saction()) {

23. //在AOP中开始事务时,会将这个标志设为真,所以这里不会被

执行,至少我还没有发现哪一次执行经过这里了

24. logger.debug("Registering Spring transaction synchroniza

tion for existing Hibernate Session");

25. TransactionSynchronizationManager.registerSynchronizatio

n(//注册一个SESSION

26. new SpringSessionSynchronization(sessionHolder,

sessionFactory, jdbcExceptionTranslator, false));

27. sessionHolder.setSynchronizedWithTransaction(true);

28. // 取出当前SESSION的提交方式

29. FlushMode flushMode = session.getFlushMode();

30. if (flushMode.lessThan(https://www.doczj.com/doc/8b6212556.html,MIT) &&

31. !TransactionSynchronizationManager.isCurrentTran

sactionReadOnly()) {

32. //如果是小于COMMIT,就是NEVER,那么改成自动

33. session.setFlushMode(FlushMode.AUTO);

34. //设置之前的提交模式

35. sessionHolder.setPreviousFlushMode(flushMode);

36. }

37. }

38. }

39. else {//这里也是一般都不会被执行,因为AOP中已经开启了事务

40. // No Spring transaction management active -> try JTA transa

ction synchronization.

41. session = getJtaSynchronizedSession(sessionHolder, sessionFa

ctory, jdbcExceptionTranslator);

42. }

43. if (session != null) {

44. return session;

45. }

46. }

47. ////////-------------------后半部份 --------------------------

48.

49. //来自FILTER的调用,一般sessionHolder为空

50. logger.debug("Opening Hibernate Session");

51. //调用HIBERNATE打开SESSION

52. Session session = (entityInterceptor != null ?

53. sessionFactory.openSession(entityInterceptor) : sessionFacto

ry.openSession());

54.

55. // 当前请求是否已开启事务,FILTER中的调用,还没有到AOP层,事务没有

打开,一般会执行ELSE

56. if (TransactionSynchronizationManager.isSynchronizationActive()) {

57. // We're within a Spring-managed transaction, possibly from JtaT

ransactionManager.

58. logger.debug("Registering Spring transaction synchronization for

new Hibernate Session");

59. SessionHolder holderToUse = sessionHolder;

60. if (holderToUse == null) {

61. holderToUse = new SessionHolder(session);

62. }

63. else {

64. holderToUse.addSession(session);

65. }

66. if (TransactionSynchronizationManager.isCurrentTransactionReadOn

ly()) {

67. session.setFlushMode(FlushMode.NEVER);

68. }

69. TransactionSynchronizationManager.registerSynchronization(

70. new SpringSessionSynchronization(holderToUse, sessionFac

tory, jdbcExceptionTranslator, true));

71. holderToUse.setSynchronizedWithTransaction(true);

72. if (holderToUse != sessionHolder) {

73. TransactionSynchronizationManager.bindResource(sessionFactor

y, holderToUse);

74. }

75. }

76. else {

77. // 上面没有找到事务,从sessionFactory中找,如果sessionFactory

有配置JTA事务,则注册事务

78. // 本文也没有配置JTA事务,所以里面什么也没有干,还是没有注册事

79. registerJtaSynchronization(session, sessionFactory, jdbcExceptio

nTranslator, sessionHolder);

80. }

81.

82. // 如果不自动创建 && sessionHolder中没有session,则关闭 SESSION

83. if (!allowCreate && !isSessionTransactional(session, sessionFactory)

) {

84. closeSession(session);

85. throw new IllegalStateException("No Hibernate Session bound to t

hread, " +

86. "and configuration does not allow creation of non-transactio

nal one here");

87. }

88. //到此就在FILTER中取得了(或者说打开了)SESSION,下面就从ACTION调用

SERVICE这一节了。

89. return session;

90.}

//下面开始到了ACTION的操作,action调用service,此service实际上是Spring动态生成的代理类,此代理类调用

//目标SERVICE类对应的方法前,要经过AOP拦截,下面我们对ACTION到SERVICE这中间经过的所有类方法代码分析一遍。

//我的应用在AOP层配置了一个事务拦截器,所以这中间的代码主要操作事务相关。

//动态生成的代理类代码看不到,从动态代理类下面的那个类(JdkDynamicAopProxy)开始吧

Java 代码

1.//JdkDynamicAopProxy类,此方法被动态代理类调用

2.//参数说明:proxy动态代理类对象,method目标方法,args目标方法参数

3.public Object invoke(Object proxy, Method method, Object[] args) throws

Throwable {

4. MethodInvocation invocation = null;

5. Object oldProxy = null;

6. boolean setProxyContext = false;

7.

8. //targetSource对象包含目标SERVICE对象

9. TargetSource targetSource = this.advised.targetSource;

10. Class targetClass = null;

11. Object target = null;

12.

13. try {

14. //如果目标类没有重载equals方法 && 目前正在调用目标类的equals方

法,那直接调本类重载方法,

15. //这样就不需要再往下走,不需要再开启事务等等多余的操作以至于浪费

性能了,下面的几个IF都是做类似的事

16. if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {

17. // The target does not implement the equals(Object) method i

tself.

18. return (equals(args[0]) ? Boolean.TRUE : Boolean.FALSE);

19. }

20. if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method))

{

21. // The target does not implement the hashCode() method itsel

f.

22. return new Integer(hashCode());

23. }

24. if (!this.advised.opaque && method.getDeclaringClass().isInterfa

ce() &&

25. method.getDeclaringClass().isAssignableFrom(Advised.clas

s)) {

26. // Service invocations on ProxyConfig with the proxy config.

..

27. return AopUtils.invokeJoinpointUsingReflection(this.advised,

method, args);

28. }

29.

30. Object retVal = null;

31.

32. //ProxyConfig类的exposeProxy属性,表示是否要将当前的代理对象放

入AopContext 中,

33. //这样在你的Service中可以用AopContext.currentProxy()取得当前代

理,相当于 this引用,

34. //不同于this引用的是,调用当前代理会被AOP拦截,而this不会。

35. //此属性默认为FALSE,如果要打开,

36. //在BeanNameAutoProxyCreator等代理类BEAN的配置中加入

37. if (this.advised.exposeProxy) {

38. // Make invocation available if necessary.

39. oldProxy = AopContext.setCurrentProxy(proxy);

40. setProxyContext = true;

41. }

42.

43. // 取得目标(真实SERVICE对象)

44. target = targetSource.getTarget();

45. if (target != null) {

46. targetClass = target.getClass();

47. }

48.

49. // 取得所有拦截器

50. List chain = this.advised.getInterceptorsAndDynamicInterceptionA

dvice(method, targetClass);

51.

52. // 如果没有拦截器

53. if (chain.isEmpty()) {

54. // 直接调用目标

55. retVal = AopUtils.invokeJoinpointUsingReflection(target, met

hod, args);

56. }

57. else {//有拦截器

58. // 创建一个调用器对象

59. invocation = new ReflectiveMethodInvocation(proxy, target, m

ethod, args, targetClass, chain);

60. // 通过调用器往下调用目标或第一个拦截器

61. retVal = invocation.proceed();

62. }

63.

64. // 调用的返回结果目标类对象本身,就把它替换成代理类对象

65. if (retVal != null && retVal == target && method.getReturnType()

.isInstance(proxy) &&

66. !RawTargetAccess.class.isAssignableFrom(method.getDeclar

ingClass())) {

67. retVal = proxy;

68. }

69. return retVal;

70. }

71. finally {//释放资源

72. //主要是从当前线程清除代理类对象

73. if (target != null && !targetSource.isStatic()) {

74. targetSource.releaseTarget(target);

75. }

76. if (setProxyContext) {

77. // Restore old proxy.

78. AopContext.setCurrentProxy(oldProxy);

79. }

80. }

81.}

递归调用拦截器

Java代码

1.//ReflectiveMethodInvocation类,上面执行 retVal = invocation.proceed();

就进入到了这个方法

2.//这个方法主要是递归调用各个拦截器,最后调用目标类

3.public Object proceed() throws Throwable {

4. // 判断是否还有拦截器要调用,

5. if (this.currentInterceptorIndex == this.interceptorsAndDynamicMetho

dMatchers.size() - 1) {

6. //没有拦截器了,调用目标

7. return invokeJoinpoint();

8. }

9.

10. //取出拦截器

11. Object interceptorOrInterceptionAdvice =

12. this.interceptorsAndDynamicMethodMatchers.get(++this.currentInte

rceptorIndex);

13.

14. //判断拦截器型,对不同类型的调用方法不一样,SPRING事务拦截器

TransactionInterceptor是MethodInterceptor实现类,

15. //不属于InterceptorAndDynamicMethodMatcher,执行ELSE

16. if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamic

MethodMatcher) {

17. InterceptorAndDynamicMethodMatcher dm =

18. (InterceptorAndDynamicMethodMatcher) interceptorOrIntercepti

onAdvice;

19. if (dm.methodMatcher.matches(this.method, this.targetClass, this

.arguments)) {

20. return dm.interceptor.invoke(this);

21. }

22. else {//方法匹配失败,跳过,继续递归

23. return proceed();

24. }

25. }

26. else {

27. // 调用事务拦截器等,MethodInterceptor--林信良的SPRING手册介绍过

个这接口如何使用

28. return ((MethodInterceptor) interceptorOrInterceptionAdvice).inv

oke(this);

29. }

30.}

事务拦截器

Java代码

1.//TransactionInterceptor--SPRING的事务拦截器实现类,这个方法可以根据事务

管理器的种类分类if和else上下两部分,

2.//如果配置的是

org.springframework.orm.hibernate3.HibernateTransactionManager等非

CallbackPreferringPlatformTransactionManager接口实现类

3.//则看只需要看if部份

4.//了解这里工作原理很重要:

5.//1、如果是请求发起的调用,流程路线为--FILTER打开Session,并且绑定到了线

程信息中

(TransactionSynchronizationManager.bindResource(sessionFactory, new Sess ionHolder(session))),

6.//在此方法里标志为旧SESSION,开始事务,调用目标,提交或回滚事务,判断如

果是旧SESSION,则事务结束释放连接但不关闭SESSION,如果还用此SESSION再开启事务,再绑定另外的连接(所以上文说单SESSION并不等于同一个连接),最后在 FILTER关闭SESSION。

7.//2、如果不是请求发起的调用,如计划任务Timer.schedule(...)发起的SERVICE

调用,流程为 --在此方法打开SESSION,标志为新连接,开启事务,调用目标,提交或回滚事务,释放数据库连接,判断如果是新SESSION,则关闭 SESSION。

8.//总结如下:

9.//1、只要有配置了此事务拦截器,底层使用SPRING的

HibernateTemplate.getSession()、getSession().connection()取得连接或

Spring提供的各种查询,那么SESSION和数据库连接的关闭不需要你操心,但是stateMent和ResultSet要记得关闭。

10.//2、如果要在Timer的run方法中多次调用SERVICE时,也要实现

OpenSessionInViewFilter这样的效果,那么使用如这句,结束时要记得自已关闭SESSION。

11.//打开SESSION 后:

TransactionSynchronizationManager.bindResource(getSessionFactory(), new SessionHolder(session));

12.//最后关闭SESSION:

13.//SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizati

onManager.unbindResource(getSessionFactory());

14.//SessionFactoryUtils.closeSession(sessionHolder.getSession());

15.public Object invoke(final MethodInvocation invocation) throws Throwable

{

16. // 取得目标类名

17. Class targetClass = (invocation.getThis() != null ? invocation.getTh

is().getClass() : null);

18.

19. // 通过类名及方法名,取得事务属性,即

PROPAGATION_REQUIRED,readOnly这些内容

20. final TransactionAttribute txAttr = getTransactionAttributeSource().

getTransactionAttribute(invocation.getMethod(), targetClass);

21. //取得类名+方法名全称

22. final String joinpointIdentification = methodIdentification(invocati

on.getMethod());

23. //没有事务属性 || 事务管理者不是

CallbackPreferringPlatformTransactionManager类型(事务采用回调方法实现的方式)

24. if (txAttr == null || !(getTransactionManager() instanceof CallbackP

referringPlatformTransactionManager)) {

25. //开始事务并创建事务信息对象(此对象主要包括事务属性和事务状态等

信息),就是在这里调用了 session.beginTransaction()方法

26. //将事务信息以当前线程为KEY放入了

TransactionAspectSupport.transactionInfoHolder对象中

27. //注意:到这里如果当前取得到SessionHolder,那么SESSION就被标记

成老SESSION,提交事务时就不会关闭之,反之那么session会在打开,并被标为新SESSION,提交事务时会把此SESSION关闭

28. TransactionInfo txInfo = createTransactionIfNecessary(txAttr, jo

inpointIdentification);

29. Object retVal = null;

30. try {

31. // 调用下一下拦截器,如果没有下一个拦截器,那么目标类会被调

32. retVal = invocation.proceed();

33. }

34. catch (Throwable ex) {

35. // 发生异常时,在这里回滚,回滚时,除了rollBack,还执行

session.clear(),setFlushMode(NEVER)等动作

36. // 新SESSION会在此被关闭,老的则不会

37. completeTransactionAfterThrowing(txInfo, ex);

38. throw ex;

39. }

40. finally {

41. //清理当前线程对应的事务信息,

42. cleanupTransactionInfo(txInfo);

43. }

44. //未发生异常,提交事务,如果是新SESSION,会在此被关闭,老的则不

45. commitTransactionAfterReturning(txInfo);

46. return retVal;

47. }

48.

49. else {

50. // 回调式的事务管理器,SPRING中只提供了一个

WebSphereUowTransactionManager的具体实现,

51. /**CallbackPreferringPlatformTransactionManager接口的注释

52. * Extension of the {@link org.springframework.transaction.Platf

ormTransactionManager}

53. * interface, exposing a method for executing a given callback w

ithin a transaction.

54. *

Implementors of this interface automatically express a pre

ference for

55. * callbacks over programmatic getTransaction,

e>commit

56. * and rollback calls. Calling code may check wheth

er a given

57. * transaction manager implements this interface to choose to pr

epare a

58. * callback instead of explicit transaction demarcation control.

*/

59. // 大意应该是可以由此接口的具体实现来决定事务的控制,我的E文一般

般,有错的就砸砖

60. try {

61. Object result = ((CallbackPreferringPlatformTransactionManag

er) getTransactionManager()).execute(txAttr,

62. new TransactionCallback() {

63. public Object doInTransaction(TransactionStatus

status) {

64. TransactionInfo txInfo = prepareTransactionI

nfo(txAttr, joinpointIdentification, status);

65. try {

66. //往下调用

67. return invocation.proceed();

68. }

69. catch (Throwable ex) {

70. if (txAttr.rollbackOn(ex)) {

71. // A RuntimeException: will lead to

a rollback.

72. if (ex instanceof RuntimeException)

{

73. throw (RuntimeException) ex;

74. }

75. else {

76. throw new ThrowableHolderExcepti

on(ex);

77. }

78. }

79. else {

80. // A normal return value: will lead

to a commit.

81. return new ThrowableHolder(ex);

82. }

83. }

84. finally {

85. cleanupTransactionInfo(txInfo);

86. }

87. }

88. });

89.

90. // Check result: It might indicate a Throwable to rethrow.

91. if (result instanceof ThrowableHolder) {

92. throw ((ThrowableHolder) result).getThrowable();

93. }

94. else {

95. return result;

96. }

97. }

98. catch (ThrowableHolderException ex) {

99. throw ex.getCause();

100. }

101. }

102.}

//这篇文章在打开和提交事务、同一SESSION多次切换不同事务的细节没有提及,下一篇讲解。

//本人水平很有限,错漏之处难免,请各位指出,并请手下留情...呵呵

深入理解ServletJSP之Cookie和Session原理

由于H T T P协议的无状态特征,W e b应用中经常使用C o o k i e和S e s s i o n来保存用户在与系统交互过程中的状态数据。下面通过分析H T T P协议对C o o k i e和S e s s i o n的工作原理加以了解。 一、C o o k i e C o o k i e的含义是“服务器送给浏览器的甜点”,即服务器在响应请求时可以将一些数据以“键-值”对的形式通过响应信息保存在客户端。当浏览器再次访问相同的应用时,会将原先的C o o k i e通过请求信息带到服务器端。 下面的S e r v l e t展示了C o o k i e的功能。 ......... p u b l i c v o i d d o G e t(H t t p S e r v l e t R e q u e s t r e q u e s t,H t t p S e r v l e t R e s p o n s e r e s p o n s e) t h r o w s S e r v l e t E x c e p t i o n,I O E x c e p t i o n{ r e s p o n s e.s e t C o n t e n t T y p e("t e x t/h t m l"); P r i n t W r i t e r o u t=r e s p o n s e.g e t W r i t e r(); S t r i n g o p t i o n=r e q u e s t.g e t P a r a m e t e r("o p t i o n"); i f("s h o w".e q u a l s(o p t i o n)){ //获得请求信息中的C o o k i e数据 C o o k i e[]c o o k i e s=r e q u e s t.g e t C o o k i e s(); i f(c o o k i e s!=n u l l){ //找出名称(键)为“c o o l”的C o o k i e f o r(i n t i=0;i"+c o o k i e s[i].g e t N a m e()+":" +c o o k i e s[i].g e t V a l u e()+""); } } } }e l s e i f("a d d".e q u a l s(o p t i o n)){ //创建C o o k i e对象 C o o k i e c o o k i e=n e w C o o k i e("c o o l","y e a h!"); //设置生命周期以秒为单位 c o o k i e.s e t M a x A g e(20); //添加C o o k i e r e s p o n s e.a d d C o o k i e(c o o k i e); }

APPlication,Session和Cookie的区别

APPlication,Session 和Cookie 的区别 方法信息量大小 保存时间应用范围保存位置 Application 任意大小整个应用程序的生命期 所有用户服务器端Session 小量,简单的数据用户活动时间+一段延迟时间(一般为20分钟) 单个用户服务器端Cookie 小量,简单的数据可以根据需要设定 单个用户客户端1.Application 对象 Application 用于保存所有用户的公共的数据信息,如果使用Application 对象,一个需要考虑的问题是任何写操作都要在Application_OnStart 事件(global.asax)中完成.尽管使用Application.Lock 和Applicaiton.Unlock 方法来避免写操作的同步,但是它串行化了对Application 对象的请求,当网站访问量大的时候会产生严重的性能瓶颈.因此最好不要用此对象保存大的数据集合 2.Session 对象 Session 用于保存每个用户的专用信息.她的生存期是用户持续请求时间再加上一段时间(一般是20分钟左右).Session 中的信息保存在Web 服务器内容中,保存的数据量可大可小.当Session 超时或被关闭时将自动释放保存的数据信息.由于用户停止使用应用程序后它仍然在内存中保持一段时间,因此使用Session 对象使保存用户数据的方法效率很低.对于小量的数据,使用Session 对象保存还是一个不错的选择.使用Session 对象保存信息的代码如下:// 存放信息Session["username"]="zhouhuan";//读取数据string UserName=Session["username"].ToString(); 3.Cookie 对象 Cookie 用于保存客户浏览器请求服务器页面的请求信息,程序员也可以用它存放非敏感性的用户信息,信息保存的时间可以根据需要设置.如果没有设置Cookie 失效日期,它们仅保存到关闭浏览器程序为止.如果将Cookie 对象的Expires 属性设置为Minvalue,则表示Cookie 永远不会过期.Cookie 存储的数据量很受限制,大多数浏览器支持最大容量为4096,因此不要用来保存数据集及其他大量数据.由于并非所有的浏览器都支持Cookie,并且数据信息是以明文文本的形式保存在客户端的计算机中,因此最好不要保存敏感的,未加密的数据,否则会影响网站的安全

java web之会话技术cookie+session

会话技术 1.什么是会话: 指用户开一个浏览器,访问一个网站,只要不关闭该浏览器,不管该用户点击多少个超链接、访问多少个资源,直到用户关闭浏览器,整个这个过程我们成为一次会话 2.实际情况: 张三打开浏览器,进入淘宝,买了2样东西;李四打开浏览器,进入淘宝,买了3样东西。当这两位结账时,结账的s e r v l e t如何得到张三和李四买的东西,并为他两分别结账? 3.使用会话保存数据 ?S e s s i o n ?C o o k i e 为什么需要C o o k i e? 情景1.张在访问某个网站的时候,看到了提示你上次登录网站的时间,而且不同用户上次登录时间不同,这个怎么实现 没有会话技术前:u s e r表每次用户登录就更新u s e r表里的时间 I d N a m e P a s s w o r d L o g i n_t i m e v i e w H i s t o r y 001A a A a2012-1-5 5:00:0022,33,2 5 002B b B b2012-3-12 6:00:0012,24,5 6 情景2.访问购物网的时候,能够看到曾经浏览过的商品,当然不同用户浏览过的商品不同 如果登录了,则可以用数据库 但如果没有登录那又怎么办?????? 情景3.保存登录密码及用户名 Cookie技术 1.服务器把每个用户的数据以cookie的形式写给用户各自的浏览器当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去 Servlet有一个Cookie类 Cookie(String name ,String value) 3.Cookie小结: ①Cookie在服务端创建 Cookie cookie = new Cookie(name,value); ②Cookie是保存在浏览器这端 response.addCookie(cookie); ③Cookie的生命周期可以通过cookie.setMaxAge(int second)来设置 Cookie默认生命周期是会话级别(即存储在浏览器的内存中) 如果没有设置setMaxAge(),则该cookie的生命周期当浏览器关闭时就挂了,setMaxAge(0) +response.addCookie(cookie),相当于删除Cookie 此时如果cookie文件内部只有该Cookie则,文件也一并删除;否则只删除该Cookie ④Cookie可以被多个浏览器共享

几种session存储方式比较

几种session存储方式比较 1. 客户端cookie加密 这是我以前采用的方式,简单,高效。比较好的方法是自己采用cookie机制来实现一个session,在应用中使用此session实现。 问题:session中数据不能太多,最好只有个用户id。 参考实现:https://www.doczj.com/doc/8b6212556.html, 2. application server的session复制 可能大部分应用服务器都提供了session复制的功能来实现集群,tomcat,jboss,was都提供了这样的功能。 问题: 性能随着服务器增加急剧下降,而且容易引起广播风暴; session数据需要序列化,影响性能。 如何序列化,可以参考对象的序列化和反序列化. 参考资料 Tomcat 5集群中的SESSION复制一 Tomcat 5集群中的SESSION复制二 应用服务器-JBoss 4.0.2集群指南 3. 使用数据库保存session 使用数据库来保存session,就算服务器宕机了也没事,session照样在。 问题: 程序需要定制; 每次请求都进行数据库读写开销不小(使用内存数据库可以提高性能,宕机就会丢失数据。可供选择的内存数据库有BerkeleyDB,MySQL的内存表); 数据库是一个单点,当然可以做数据库的ha来解决这个问题。 4. 使用共享存储来保存session 和数据库类似,就算服务器宕机了也没事,session照样在。使用nfs或windows文件共享都可以,或者专用的共享存储设备。 问题: 程序需要定制; 频繁的进行数据的序列化和反序列化,性能是否有影响; 共享存储是一个单点,这个可以通过raid来解决。 5. 使用memcached来保存session 这种方式跟数据库类似,不过因为是内存存取的,性能自然要比数据库好多了。 问题: 程序需要定制,增加了工作量; 存入memcached中的数据都需要序列化,效率较低; memcached服务器一死,所有session全丢。memchached能不能做HA 我也不知道,网站上没提。 参考资料 应用memcached保存session会话信息 正确认识memcached的缓存失效 扩展Tomcat 6.x,使用memcached存放session信息 6. 使用terracotta来保存session

c#下使用cookie和session

c#如何记住用户的信息 记录加密之后的信息,确保用户的信息安全 使用cookie和session记录用户的信息 1、保存时间 session的默认保存时间是24分钟 cookie在没有设置的情况下关闭之后立即结束生命周期 设置cookie的时间,cookie-name.Expires=Date.Now.AddDays();/DateTime.MaxValue;(永久) C#读取设置Cookie 设置: HttpCookie cookie = new HttpCookie("cookieName"); cookie.Value = "name1" HttpContext.Current.Response.Cookies.Add(cookie); 读取: HttpContext.Current.Request.Cookies["cookieName"].Value 判断cookie是否存在: if(HttpContext.Current.Request.Cookies["cookieName"]==null){ //do something } 设置cookie有效期 cookie.Expires = DateTime.Now.AddDays(1); https://www.doczj.com/doc/8b6212556.html,中Cookies的用法(转) 一,cookies 写入 方法1: Response.Cookies["username"].Value="gjy"; Response.Cookies["username"].Expires=DateTime.Now.AddDays(1); 方法2: System.Web.HttpCookie newcookie=new HttpCookie("username"); newcookie.Value="gjy"; newcookie.Expires=DateTime.Now.AddDays(1); Response.AppendCookie(newcookie); 创建带有子键的cookies: System.Web.HttpCookie newcookie=new HttpCookie("user"); newcookie.Values["username"]="gjy"; newcookie.Values["password"]="111";

Cookie和Session的作用和工作原理

一、Cookie详解 (1)简介 因为HTTP协议是无状态的,即服务器不知道用户上一次做了什么,这严重阻碍了交互式Web应用程序的实现。在典型的网上购物场景中,用户浏览了几个页面,买了一盒饼干和两饮料。最后结帐时,由于HTTP的无状态性,不通过额外的手段,服务器并不知道用户到底买了什么。为了做到这点,就需要使用到Cookie了。服务器可以设置或读取Cook ies中包含信息,借此维护用户跟服务器会话中的状态。 Cookie(复数形态:Cookies),是指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。 Cookie是由服务端生成的,发送给客户端(通常是浏览器)的。Cookie总是保存在客户端中,按在客户端中的存储位置,可分为内存Cookie和硬盘Cookie: 内存Cookie由浏览器维护,保存在内存中,浏览器关闭后就消失了,其存在时间是短暂的。 硬盘Cookie保存在硬盘里,有一个过期时间,除非用户手工清理或到了过期时间,硬盘Cookie不会被删除,其存在时间是长期的。所以,按存在时间,可分为非持久Cookie和持久Cookie。 (2)工作原理 1、创建Cookie 当用户第一次浏览某个使用Cookie的网站时,该网站的服务器就进行如下工作: ①该用户生成一个唯一的识别码(Cookie id),创建一个Cookie对象; ②默认情况下它是一个会话级别的cookie,存储在浏览器的内存中,用户退出浏览器之后被删除。如果网站希望浏览器将该Cookie存储在磁盘上,则需要设置最大时效(maxAge),并给出一个以秒为单位的时间(将最大时效设为0则是命令浏览器删除该Cookie); ③将Cookie放入到HTTP响应报头,将Cookie插入到一个Set-Cookie HTTP请求报头中。 ④发送该HTTP响应报文。 2、设置存储Cookie 浏览器收到该响应报文之后,根据报文头里的Set-Cookied特殊的指示,生成相应的Cookie,保存在客户端。该Cook ie里面记录着用户当前的信息。 3、发送Cookie 当用户再次访问该网站时,浏览器首先检查所有存储的Cookies,如果某个存在该网站的Cookie(即该Cookie所声明的作用范围大于等于将要请求的资源),则把该cookie附在请求资源的HTTP请求头上发送给服务器。 4、读取Cookie 服务器接收到用户的HTTP请求报文之后,从报文头获取到该用户的Cookie,从里面找到所需要的东西。 (3)作用 Cookie的根本作用就是在客户端存储用户访问网站的一些信息。典型的应用有: 1、记住密码,下次自动登录。 2、购物车功能。 3、记录用户浏览数据,进行商品(广告)推荐。 (4)缺陷 ①Cookie会被附加在每个HTTP请求中,所以无形中增加了流量。 ②由于在HTTP请求中的Cookie是明文传递的,所以安全性成问题。(除非用HTTPS) ③Cookie的大小限制在4KB左右。对于复杂的存储需求来说是不够用的。 二、Session详解 (1)简介 Session代表服务器与浏览器的一次会话过程,这个过程是连续的,也可以时断时续的。Session是一种服务器端的机制,Session 对象用来存储特定用户会话所需的信息。 Session由服务端生成,保存在服务器的内存、缓存、硬盘或数据库中。

深入理解Session,cookie

深入理解Servlet/JSP之“Cookie和Session原理” (2008-06-29 13:41:09) 转载 标签:it it培训 java jsp servlet session cookie session持久化 由于HTTP协议的无状态特征,Web应用中经常使用Cookie和Session来保存用户在与系统交互过程中的状态数据。下面通过分析HTTP协议对Cookie和Session的工作原理加以了解。 一、Cookie Cookie的含义是“服务器送给浏览器的甜点”,即服务器在响应请求时可以将一些数据以“键-值”对的形式通过响应信息保存在客户端。当浏览器再次访问相同的应用时,会将原先的Cookie通过请求信息带到服务器端。 下面的Servlet展示了Cookie的功能。 ... ... ... public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String option = request.getParameter("option"); if ("show".equals(option)) { //获得请求信息中的Cookie数据 Cookie[] cookies = request.getCookies(); if (cookies != null) { //找出名称(键)为“cool”的Cookie for (int i = 0; i < cookies.length; i++) { if ("cool".equals(cookies[i].getName())) { out.println("

" + cookies[i].getName() + ":" + cookies[i].getValue() + "

"); } } } } else if ("add".equals(option)) { //创建Cookie对象 Cookie cookie = new Cookie("cool", "yeah!");

页面跳转及Cookie和Session

第十五天课堂笔记 1.页面跳转的两种方式 a)请求转发 i.实现代码: ii.特点: 1.不管转发几次, 只发送一次请求 2.请求携带的数据在转发后还可以继续获取 3.地址栏在多次转发时不会改变 4.转发后的代码还可以继续执行, 但是, 只能转发一 次 5.可以转发给项目内的资源(servlet, 界面…), 但是不 能转发到项目外的资源 b)重定向 i.实现代码 ii.特点 1.重定向一次会发送两次请求 2.因为是两次请求, 所以第一次携带的数据在第二次 请求时就已经无效了, 需要再次携带数据 3.地址栏会发生改变

4.重定向后代码还可以继续执行, 但是, 只能重定向 一次 5.重定向既可以访问内部资源, 也可以访问外部资源 2.ServletContext对象 a)一个应用程序只有一个ServletContext对象, 被所有 Servlet所共享, 因此, 该对象也被称之为Application对象 b)获取ServletContext对象的三种方式: c)ServletContext对象常用的功能 i.获取全局配置信息 1.全局配置信息的定义 2.获取全局配置信息 ii.获取相关路径信息 iii.获取WebRoot下的资源文件

iv.请求转发 3.Cookie a)Cookie是一个类, 它用于存储一些少量的信息, 首先在Servlet 中创建, 然后发送到客户端浏览器进行保存, 在之后的访问服 务器的过程中, 浏览器会自动携带Cookie信息 b)Cookie信息默认存储于浏览器内存中, 关闭浏览器或使用不同 的浏览器, 均无法获取到cookie信息 c)可以通过setMaxAge(seconds)方法给Cookie设置最大存活时间. 设置后, Cookie会保存到本地硬盘中, 到期后自动删除.如果时 间设置为0, cookie会被直接删除. d)可以通过setPath(uri)方法给Cookie设置访问路径, 设置后只有 访问固定路径时, 才会携带Cookie信息

利用FIDDLER工具进行session和cookie欺骗

利用FIDDLER工具进行session和cookie欺骗 Agileone登录捕获: 选中post请求,在内容中修改密码并执行。 将password=admin,改成password=123,显示结果如下: 在textview中,结果反馈为password invalid。 进行session欺骗:把登录后的任意一个请求的sessionIDcopy到登录get请求内容中,结果响应出已经进入到登录后的首页,和首页中的源文件一样。如图,

请求内容: GET http://localhost/agileone/ HTTP/1.1 Host: localhost Connection: keep-alive Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: zh-CN,zh;q=0.8 Cookie:PHPSESSID=68aa4b8855d4e704dce53b23eb9a5c92;PHPSESSID=4766b699b16758c0ce 8eca2756a3a459; Cookie欺骗操作同理。

对java中cookie和session的一些简介

1 课程回顾 Servlet编程 1)Servlet生命周期(重点) 构造方法:创建servlet对象。默认情况下,第一次访问servlet对象时。只调用1次。 init方法(有参):创建完servlet对象后调用。只调用1次。 注意:会调用无参的init方法。 service方法:servlet提供服务的方法。每次发出请求调用。 注意:request对象,response对象 destroy方法:tomcat服务器停止或web应用重新部署,servlet对象销毁,destroy方法被调用。 2)ServletConfig对象 获取servlet的初始化参数: getInitParameter("name "); getInitParameterNames(); 3)ServletContext对象 得到web应用路径: context.getContextPath(); request.getContextPath(); 等价于上面的代码 得到web应用参数: context.getInitParameter("name"); context.getInitParameterNames(); 域对象: context.setAttribute("name",Object): 保存数据 context.getAttribute("name") 得到数据 context.removeAttribue("name") 清除数据 转发 context.getRequestDispatcher("路径").forward(request,response); request.getRequestDispacher("路径").forward(request,response); 等价于上面的代码得到web应用中的资源文件 context.getRealPath("路径") context.getResourceAsStream("路径"); 今天的目标:会话管理 // 代表java命令运行目录,java运行命令哪里? 服务器启动的目录,tomcat/bin 到底在什么环境下运行,用.在java和entete不一样。Java和tomcat的不一样, 用这个方法, 2. 会话管得到web应用中的资源文件 context.getRealPath("路径") context.getResourceAsStream("路径");

Session四种方式测试报告(ASP&NET)

目录 https://www.doczj.com/doc/8b6212556.html, Session四种方式测试报告 (1) 测试环境 (1) 简介 (1) 默认模式 (1) cookieless模式 (4) 将服务器Session信息存储在进程中 (4) 将服务器Session信息存储在数据库中 (5) 结论 (6) https://www.doczj.com/doc/8b6212556.html, Session四种方式测试报告 版权归属:Top of c# 5885668群风之痕(499905171)原创文章,如果有转载,请保留该句。测试环境 .net 4.0 谷歌浏览器(34.0.1847.116) 简介 SessionState是https://www.doczj.com/doc/8b6212556.html,默认的机制。SessionState有几种模式。InProc,StateServer,SqlServer模式。InProc不支持负载均衡的场景。只有StateServer和SqlServer模式才支持。自定义模式是指我们自己实现Session数据的持久化,比如将Session数据放到Oracle数据库或者MySql数据库中,自定义模式也可以支持负载均衡。在StateServer和SqlServer模式时,放入Session中的数据都必须是能序列化的。建议采用SqlServer模式的Session机制。 默认模式 默认模式下Session会在客户生成一个浏览器的cookie,跟在服务端生成一个内存对象。 因为这种原理,所以当我们清理掉浏览器的cookie,再连接的时候,服务端还会生成一个新的Session对象,如果前个Session还没释放的话,就会有2个对象产生。 下面代码会通过全局文件,去判断Session是否产生,是否释放,产生的话+1,释放-1

https://www.doczj.com/doc/8b6212556.html, Application,Session,Cookie和ViewState等对象用法和区别

https://www.doczj.com/doc/8b6212556.html, Application,Session,Cookie和ViewState等对象用法和区别 在https://www.doczj.com/doc/8b6212556.html,中,有很多种保存信息的内置对象,如:Application,Session,Cookie,ViewState和Cache 等。下面分别介绍它们的用法和区别。 方法 信息量大 小 作用域和保存时间应用范围 保存位 置 Applic ation任意大小整个应用程序的生 命期 整个应用程序/ 所有用户 服务器 端 Cach e 任意大小可以根据需要设定 整个应用程序/ 所有用户 服务器 端 Sessi on 小量,简单 的数据 用户活动时间+一 段延迟时间(一般为20分 钟) 单个用户 服务器 端 Cooki e 小量,简单 的数据 可以根据需要设定单个用户客户端 Views tate 小量,简单 的数据 一个Web页面的生 命期 单个用户客户端 隐藏域 小量,简单 的数据 一个Web页面的生 命期 单个用户客户端 查询字符串 小量,简单 的数据 直到下次页面跳转 请求 单个用户客户端 1.Application对象 Application用于保存所有用户的公共的数据信息,如果使用Application对象,一个需要考虑的问题是任何写操作都要在Application_OnStart事件(global.asax)中完成.尽管使用Application.Lock和Applicaiton.Unlock方法来避免写操作的同步,但是它串行化了对Application对象的请求,当网站访问量大的时候会产生严重的性能瓶颈.因此最好不要用此对象保存大的数据集合. 下面我们做个在线用户统计的例子来说明这个问题:

Cookie和会话状态的工作原理及Cookie欺骗

存在两种类型的cookie: Session cookies - these are temporary and are erased when you close your browser at the end of your surfing session. The next time you visit that particular site it will not recognise you an d will treat you as a completely new visitor as there is nothing in your browser to let the site k now that you have visited before 不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie 就消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。 Persistent cookies - these remain on your hard drive until you erase them or they expire. How long a cookie remains on your browser depends on how long the visited website has program med the cookie to last 设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。 存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存的cookie,不同的浏览器有不同的处理方式。 Cookie和会话状态的工作原理及Cookie欺骗 session是一种保存上下文信息的机制,它是针对每一个用户的,变量的值保存在服务器端,通过SessionID来区分不同的客户,session是以Cookie或URL重写为基础。默认使用Cookie 来实现,系统会创造一个名为JSESSIONID的输出Cookie,或称为"Session Cookie",以区别Persistent Cookies(通常所说的Cookie).Session Cookie是存储在浏览器中,并不是写在硬盘上的,但是把浏览器的Cookie禁止后,使用response对象的encodeURL或 encodeRedirectURL 方法编码URL,WEB服务器会采URL重写的方式传递Sessionid,用户就可以在地址栏看到 jsessionid=A09JHGHKHU68624309UTY84932之类的字符串。 通常Session Cookie是不能跨窗口使用,当用户新开了一个浏览器进入相同的页面时,系统会赋予用户一个新的SessionID,这样信息共享的目的就达不到,此时可以把SessionID保存在Persistent Cookie中,然后再新的窗口中读出来,就可以得到上一个窗口的SessionID了,这样通过Session Cookie和Persistent Cookie的结合,实现了跨窗口的会话跟踪。 session的工作原理 就session的实现而言,好像是这样的: (1)当有Session启动时,服务器生成一个唯一值,称为SessionID(好像是通过取进程ID的方式取得的)。 (2)然后,服务器开辟一块内存,对应于该SessionID。 (3)服务器再将该SessionID写入浏览器的cookie(一些在网页的源代码中有所体现)。

Session和Cookie的作用以及实现

Session和Cookie的作用以及实现 最近学习Session和Cookie的总结,我发现好多做测试的朋友对这个的理解不是那么透彻;如果理解了Cookie和session的原理和使用,在我们的测试工作中,有很大的帮助;尤其是在接口测试,性能测试中。。。 我把下面的内容做成了一个pdf文档,有需要看的朋友,可以去百度云盘下载,地址在文章的最后: 内容如下: 一、为什么要用Cookie和Session? 很多时候客户端和服务器进行交互使用了HTTP协议,但是HTTP协议是无状态的;HTTP协议的请求过程,是基于TCP/IP 的,当客户端请求服务器,服务器处理后,进行响应,该过程是无状态的。 但是在有些时候是需要保存一些客户端的请求信息,识别客户端的某些状态,智能的、有针对性的去分析某些客户端的习惯。这些时候,就需要去记录客户端的连接状态,识别请求的状态等。所以为了解决类似的事情,就需要使用到了Cookie 和Session。 比如,使用Cookie的场景:有些网站有记住用户名的功能,当你勾这个的时候,下次进入该网站时,就会保存上一次登录的用户名;使用Seesion的场景:利用Seesion来验证用户是否已登录,利用Session来保存验证码。 二、Cookie和Session是什么? (1)Cookie:在客户端访问某个地址时,会将请求交到服务器进行处理,在发送请求的时候,浏览器会将页面的头部信息一并的交到服务器端进行处理。在处理的过程中,Cookie 在服务器端生成,在此同时,可以将一些需要保存的信息,存放到此Cookie 中。生成Cookie 对象时,需要确定具体的名称及具体的值,可以设置当前Cookie 的过期时间,设置过期时间后,就相当于持久化了Cookie 中的数据,此时的Cookie 会以之前的Cookie 名称,保存在客户端。 如果不设置过期时间,则当前Cookie 的生命期是浏览器会话期间,一旦关闭了该浏览器,当前的Cookie 就会不存在了,此时的Cookie 信息是保存在内存中。在服务器端,处理完后,会将生成的Cookie ,随着Http 响应,会在Http 响应头中,加上Cookie 信息,浏览器接受到响应后,会按照Http 响应头里的Cookie ,在客户端建立Cookie 。在下次客户进行请求的时候,Http 会附带着已经存储过的Cookie,一并发送到服务器。一个域,在客户端建立的所以Cookie 都是可以共享的,只要Cookie 没有过期。 (2)Session:Session 是在服务器端生成的,存储在服务器端,即存在内存中。可以对生成的Session 设置过期时间,如果不设置过期时间,默认的Session 过期时间是30 分钟(在不同的服务器中,它的过期时间略有不同,本文是以Tomcat 来说的)但是,Sesssion 的生成的同时,会生成一个与之相关联的的SessionID ,此SessionID 的存储是需要Cookie 来完成的。SessionID 是以名称为JSESSIONID,其值应该是一个既不会重复,又不容易被找到规律以仿造的字符串。SessionID会随着此次Http 响应,一并返回到客户端,并保存在客户端中。到当前请求再次发出后,该SessionID会随着Http 头部,传到服务器中,服务器依据当前SessionID 得到与之对应的Session. 其中:通过Cookie 的方式存储Session 状态,只是其中一种方式。如果客户端禁用了Cookie 的话,很多网站任然可以存储用户的信息。一种处理的方式是URL 重写,将SesseionID 直接附加在请求地址的后面。另一种处理的方式是,使用隐藏自动的方式。就是服务器自动的在表单中,添加一个隐藏字段,以便在表单提交时,将SesseionID 一起传到服务器,进行识别。 (3)总结下:Cookie是存在客户端的,比如我们电脑的本地文件中(设置的过期时间的话),在我本地的话(C:\Users\xxx\AppData\Roaming\Microsoft\Windows\Cookies): 也可以在浏览器中看(chrome): Session是存在服务器端的(我的apche也安装在本地的):

10分钟让你区分Session和Cookie区别

Session Session定义 一般被翻译为‘会话’,具体到Web中的Session指的就是用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间。因此从上述的定义中我们可以看到,Session实际上是一个特定的时间概念。 session工作原理 session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(来保存信息。 当客户端请求创建一个session的时候,服务器首先检查客户端请求里是否已包含了一个session标识session id,如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用。 如果客户端请求不包含session id,则为此服务器创建一个session并且生成一个与此session相关联的session id。session id的值是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。保存这个session id的方式可以采用cookie。一般这个cookie的名字都是类似于SEEESIONID。 比如: JSESSIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,它的名字就是JSESSIONID。 由于cookie可以被人为的禁止,必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一种技术叫做URL重写。 就是把session id直接附加在URL路径的后面,附加方式也有两种: 1.一种是作为URL路径的附加信息,表现形式为http://...../xxx;jsessionid=ByOK ... 99zWpBng!-145788764 2.另一种是作为查询字符串附加在URL后面,表现形式为http://...../xxx?jsessionid=ByOK ... 99zWpBng!-145788764 这两种方式对于用户来说是没有区别的,只是服务器在解析的时候处理的方式不同,采用第一种方式也有利于把session id的信息和正常程序参数区分开来。 为了在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个session id。 另一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。这种技术现在已较少应用。 有一种一种误解:“只要关闭浏览器,session就消失了”。其实可以想象一下会员卡的例子,除非顾客主动对店家提出销卡,否则店家绝对不会轻易删除顾客的资料。对session 来说也是一样的,除非程序通知服务器删除一个session,否则服务器会一直保留,程序一般都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会主动在关闭之前通知服务器它将要关闭,因此服务器根本不会有机会知道浏览器已经关闭。

Session&Cookie 笔试题及答案

String username = "1234567899"; String regex1 = "^[a-zA-Z0-9]{5,12}$"; String regex2 = "^\\w{1,}[@]\\w{1,}[.]\\w{1,}[.]?\\w{1,}$";//email 写法 String email = "^[a-zA-Z0-9_-]+[@][a-zA-Z0-9_-]+((.com)|(.net))$"; String regex4 = "^\\w{1,}(.com|.cn)$"; String regex3 = "^\\d{3,4}[| -]?\\d{7,8}$";//电话号码,空格不能在最后 String userReg = "^[a-zA-Z0-9_]{5,12}$"; // 用户名5-12位 字母数字,_ String numberReg = "^\\d{6,8}$"; // 6-8位数字 String fpReg = "^[0-9]+[.]?\\d*$"; String telReg = "^(\\d{1,3}[-| ]?)?" + "\\d{3,4}[-| ]?\\d{7,8}[-| ]?(\\d{3,4})?$"; servlet 一、cookie 机制和session 机制的区别 具体来说cookie 机制采用的是在客户端保持状态的方案,而session 机制采用的是在服务器端保持状态的方案。 同时我们也看到,由于在服务器端保持状态的方案在客户端也需要保存一个标识,所以session 机制可能需要借助于cookie 机制来达到保存标识的目的,但实际上还有其他选择。 二、会话cookie 和持久cookie 的区别 如果不设置过期时间,则表示这个cookie 生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie 就消失了。这种生命期为浏览会话期的cookie 被称为会话cookie 。会话cookie 一般不保存在硬盘上而是保存在内存里。 如果设置了过期时间,浏览器就会把cookie 保存到硬盘上,关闭后再次打开浏览器,这些cookie 依然有效直到超过设定的过期时间。 存储在硬盘上的cookie 可以在不同的浏览器进程间共享,比如两个IE 窗口。而对于保存在内存的cookie ,不同的浏览器有不同的处理方式。 三、如何利用实现自动登录 当用户在某个网站注册后,就会收到一个惟一用户ID 的cookie 。客户后来重新连接时,这个用户ID 会自动返回,服务器对它[abc] a 、b 或 c (简单类) [^abc] 任何字符,除了 a 、b 或 c (否定) [a-zA-Z] a 到 z 或 A 到 Z ,两头的字母包括在内(范围) [a-d[m-p]] a 到 d 或 m 到 p :[a-dm-p](并集) [a-z&&[def]] d 、e 或 f (交集) [a-z&&[^bc]] a 到 z ,除了 b 和 c :[ad-z](减去) [a-z&&[^m-p]] a 到 z ,而非 m 到 p :[a-lq-z](减去) \d 数字:[0-9] \D 非数字: [^0-9] \s 空白字符:[ \t\n\x0B\f\r] \S 非空白字符:[^\s] \w 单词字符:[a-zA-Z_0-9] \W 非单词字符:[^\w]

相关主题
文本预览
相关文档 最新文档