ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>国产免费一区二区三区在线观看 ,国产日韩中文字幕在线,日韩一区二区久久http://www.aygfsteel.com/mkchen/category/18750.html用开攄¡š„脑子去闯è?用开阔的视野åŽÀL‹¼æ?用åã^和的íw«å¿ƒåŽÈ£¨¾l?用美好的理想去追æ±?zh-cnWed, 28 Feb 2007 07:48:02 GMTWed, 28 Feb 2007 07:48:02 GMT60[转]Acegi½Ž€ä»?/title><link>http://www.aygfsteel.com/mkchen/archive/2006/12/27/90397.html</link><dc:creator>‹¹äh€?/dc:creator><author>‹¹äh€?/author><pubDate>Wed, 27 Dec 2006 15:20:00 GMT</pubDate><guid>http://www.aygfsteel.com/mkchen/archive/2006/12/27/90397.html</guid><wfw:comment>http://www.aygfsteel.com/mkchen/comments/90397.html</wfw:comment><comments>http://www.aygfsteel.com/mkchen/archive/2006/12/27/90397.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/mkchen/comments/commentRss/90397.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/mkchen/services/trackbacks/90397.html</trackback:ping><description><![CDATA[ <a >matrixeditor</a> 发表äº?2005-07-28 11:06:41<br />作è€?Matrixeditor     来源:BEA dev2dev<br />评论æ•?4 点击æ•?6,815     投票æ€Õd¾—åˆ?8 投票æ€ÖMh‹Æ?3<br />关键å­? <!-- end of div title --><div id="wmqeeuq" class="summary"><div id="wmqeeuq" class="left"></div><div id="wmqeeuq" class="center"><h4>摘要:</h4>Acegi安全¾pȝ»ŸåQŒæ˜¯ä¸€ä¸ªç”¨äºŽSpring Framework的安全框æžÓž¼Œèƒ½å¤Ÿå’Œç›®å‰æµè¡Œçš„Web容器无缝集成。它使用了Spring的方式提供了安全和认证安全服务,包括使用Bean ContextåQŒæ‹¦æˆªå™¨å’Œé¢å‘接口的¾~–程方式。因此,Acegi安全¾pȝ»Ÿèƒ½å¤Ÿè½ÀL¾åœ°é€‚用于复杂的安全需求ã€?</div><div id="wmqeeuq" class="right"><div id="wmqeeuq" class="help"><h4>工具½Ž?/h4><a >本站收藏</a><br /><a onclick="javascript:location. >¾ŸŽå‘³ä¹¦ç­¾</a><br /><a >投票评分</a><br /><a >发表评论</a><br /><a title="点击后直接粘贴即å? onclick="copyLink();" >复制链接</a><br /></div></div></div><!-- end of summary line --><div id="wmqeeuq" class="overflow" id="text">           Acegi安全¾pȝ»ŸåQŒæ˜¯ä¸€ä¸ªç”¨äºŽSpring Framework的安全框æžÓž¼Œèƒ½å¤Ÿå’Œç›®å‰æµè¡Œçš„Web容器无缝集成。它使用了Spring的方式提供了安全和认证安全服务,包括使用Bean ContextåQŒæ‹¦æˆªå™¨å’Œé¢å‘接口的¾~–程方式。因此,Acegi安全¾pȝ»Ÿèƒ½å¤Ÿè½ÀL¾åœ°é€‚用于复杂的安全需求ã€?br />       安全涉及åˆîC¸¤ä¸ªä¸åŒçš„æ¦‚念åQŒè®¤è¯å’ŒæŽˆæƒã€‚前者是关于¼‹®è®¤ç”¨æˆ·æ˜¯å¦¼‹®å®žæ˜¯ä»–们所宣称的èín份。授权则是关于确认用æˆäh˜¯å¦æœ‰å…è®¸æ‰§è¡Œä¸€ä¸ªç‰¹å®šçš„æ“ä½œã€?br />       在Acegi安全¾pȝ»Ÿä¸­ï¼Œéœ€è¦è¢«è®¤è¯çš„ç”¨æˆøP¼Œ¾pȝ»Ÿæˆ–代理称ä¸?Principal"。Acegi安全¾pȝ»Ÿå’Œå…¶ä»–的安全¾pȝ»Ÿä¸åŒåQŒå®ƒòq¶æ²¡æœ‰è§’色和用户¾l„的概念ã€?br />Acegi¾pȝ»Ÿè®¾è®¡<br />  关键¾l„äšg<br />      Acegi安全¾pȝ»ŸåŒ…含以下七个关键的功能组ä»Óž¼š<br />        1 Authentication对象åQŒåŒ…含了PrincipalåQŒCredentialå’ŒPrincipal的授权信息。同时还可以包含关于发è“v认证è¯äh±‚的客æˆïLš„其他信息åQŒå¦‚IP地址ã€?br />        2 ContextHolder对象åQŒä‹É用ThreadLocal储存Authentication对象的地斏V€?br />        3 AuthenticationManageråQŒç”¨äºŽè®¤è¯ContextHolder中的Authentication对象ã€?br />        4 AccessDecissionManageråQŒç”¨äºŽæŽˆæƒä¸€ä¸ªç‰¹å®šçš„æ“ä½œã€?br />        5 RunAsManageråQŒå½“执行特定的操作时åQŒç”¨äºŽé€‰æ‹©æ€§åœ°æ›¿æ¢Authentication对象ã€?br />        6 Secure Object拦截器,用于协调AuthenticationManageråQŒAccessDecissionManageråQŒRunAsManager和特定操作的执行ã€?br />        7 ObjectDefinitionSourceåQŒåŒ…含了特定操作的授权定义ã€?br />      ˜q™ä¸ƒä¸ªå…³é”®çš„功能¾l„äšg的关¾pÕd¦‚下图所½Cºï¼ˆå›¾ä¸­ç°è‰²éƒ¨åˆ†æ˜¯å…³é”®ç»„ä»Óž¼‰åQ?br /><br /><br /><b>安全½Ž¡ç†å¯¹è±¡</b><br />       Acegi安全¾pȝ»Ÿç›®å‰æ”¯æŒä¸¤ç±»å®‰å…¨½Ž¡ç†å¯¹è±¡ã€?br />       ½W¬ä¸€¾cȝš„安全½Ž¡ç†å¯¹è±¡½Ž¡ç†AOP Allianceçš„MethodInvocationåQŒå¼€å‘äh员可以用它来保护Springå®¹å™¨ä¸­çš„ä¸šåŠ¡å¯¹è±¡ã€‚äØ“äº†ä‹ÉSpring½Ž¡ç†çš„Beanå¯ä»¥ä½œäØ“MethodInvocation来ä‹É用,Bean可以通过ProxyFactoryBeanå’ŒBeanNameAutoProxyCreator来管理,ž®±åƒåœ¨Spring的事务管理一样ä‹É用ã€?br />       ½W¬äºŒ¾cÀL˜¯FilterInvocation。它用过滤器åQˆFilteråQ‰æ¥åˆ›å¾åQŒåƈ½Ž€å•地包装了HTTPçš„ServletRequeståQŒServletResponseå’ŒFilterChain。FilterInvocation可以用来保护HTTP资源。通常åQŒå¼€å‘ähå‘˜åÆˆä¸éœ€è¦äº†è§£å®ƒçš„å·¥ä½œæœºåˆÓž¼Œå› äؓ他们只需要将Filter加入web.xmlåQŒAcegi安全¾pȝ»Ÿž®±å¯ä»¥å·¥ä½œäº†ã€?br /><br /><b>安全配置参数</b><br />       每个安全½Ž¡ç†å¯¹è±¡éƒ½å¯ä»¥æ˜q°æ•°é‡ä¸é™çš„各种安全认证è¯äh±‚。例如,MethodInvocation对象可以描述带有ä»ÀL„å‚æ•°çš„ä“Q意方法的调用åQŒè€ŒFilterInvocation可以描述ä»ÀL„çš„HTTP URLã€?br />       Acegi安全¾pȝ»Ÿéœ€è¦è®°å½•应用于每个认证è¯äh±‚的安全配¾|®å‚数。例如,对于BankManager.getBalanceåQˆint accountNumberåQ‰æ–¹æ³•å’ŒBankManager.approveLoanåQˆint applicationNumberåQ‰æ–¹æ³•,它们需要的认证è¯äh±‚的安全配¾|®å¾ˆä¸ç›¸åŒã€?br />       ä¸ÞZº†ä¿å­˜ä¸åŒçš„认证请求的安全配置åQŒéœ€è¦ä‹É用配¾|®å‚数。从实现的视角来看,配置参数使用ConfigAttribute接口来表½Cºã€‚Acegi安全¾pȝ»Ÿæä¾›äº†ConfigAttribute接口的一个实玎ͼŒSecurityConfigåQŒå®ƒæŠŠé…¾|®å‚æ•îC¿å­˜äؓ一个字½W¦ä¸²ã€?br />       ConfigAttributeDefinition¾cÀL˜¯ConfigAttribute对象的一个简单的容器åQŒå®ƒä¿å­˜äº†å’Œç‰¹å®šè¯äh±‚相关的ConfigAttribute的集合ã€?br />       当安全拦截器收到一个安全认证请求时åQŒéœ€è¦å†³å®šåº”用哪一个配¾|®å‚数。换句话è¯ß_¼Œå®ƒéœ€è¦æ‰¾å‡ºåº”用于˜q™ä¸ªè¯äh±‚çš„ConfigAttributeDefinition对象。这个查扄¡š„˜q‡ç¨‹æ˜¯ç”±ObjectDefinitionSource接口来处理的。这个接口的主要æ–ÒŽ³•是public ConfigAttributeDefinition getAttributes(Object object)åQŒå…¶ä¸­Object参数是一个安全管理对象。因为安全管理对象包含有认证è¯äh±‚的详¾l†ä¿¡æ¯ï¼Œæ‰€ä»¥ObjectDefinitionSource接口的实现类可以从中获得所需的详¾l†ä¿¡æ¯ï¼Œä»¥æŸ¥æ‰„¡›¸å…³çš„ConfigAttributeDefiniton对象ã€?br /><br /><br /><b>Acegi如何工作</b><br />       ä¸ÞZº†è¯´æ˜ŽAcegi安全¾pȝ»Ÿå¦‚何工作åQŒæˆ‘们设想一个ä‹É用Acegi的例子。通常åQŒä¸€ä¸ªå®‰å…¨ç³»¾lŸéœ€è¦å‘挥作用,它必™åÕd®Œæˆä»¥ä¸‹çš„工作åQ?br />      1 首先åQŒç³»¾lŸä»Žå®¢æˆ·ç«¯è¯·æ±‚中获得Principalå’ŒCredentialåQ?br />      2 然后¾pȝ»Ÿè®¤è¯Principalå’ŒCredential信息åQ?br />      3 如果认证通过åQŒç³»¾lŸå–出Principal的授权信息;<br />      4 接下来,客户端发èµäh“ä½œè¯·æ±‚ï¼›<br />      5 ¾pȝ»Ÿæ ÒŽ®é¢„先配置的参数检查Principal对于该操作的授权åQ?br />      6 如果授权‹‚€æŸ¥é€šè¿‡åˆ™æ‰§è¡Œæ“ä½œï¼Œå¦åˆ™æ‹’绝ã€?br />      那么åQŒAcegi安全¾pȝ»Ÿæ˜¯å¦‚何完成这些工作的呢?首先åQŒæˆ‘们来看看Acegi安全¾pȝ»Ÿçš„认证和授权的相关类åQ?<br />      安全拦截器的抽象基类åQŒå®ƒåŒ…含有两个管理类åQŒAuthenticationManagerå’ŒAccessDecisionManager。AuthenticationManager用于认证ContextHolder中的Authentication对象åQˆåŒ…含了PrincipalåQŒCredentialå’ŒPrincipal的授权信息)åQ›AccessDecissionManager则用于授权一个特定的操作ã€?br /><br />      下面来看一个MethodSecurityInterceptor的例子:<br /><pre class="overflow">      <bean id="bankManagerSecurity" <br />                     class="net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor"><br />             <property name="validateConfigAttributes"><br />                    <value>true</value><br />            </property><br />            <property name="authenticationManager"><br />                   <ref bean="authenticationManager"/><br />            </property><br />            <property name="accessDecisionManager"><br />                  <ref bean="accessDecisionManager"/><br />            </property><br />            <property name="objectDefinitionSource"><br />                  <value><br />                     net.sf.acegisecurity.context.BankManager.delete*=<br />                             ROLE_SUPERVISOR,RUN_AS_SERVER<br />                     net.sf.acegisecurity.context.BankManager.getBalance=<br />                             ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER,RUN_<br />                  </value><br />            </property><br />      </bean> </pre><br />      上面的配¾|®æ–‡ä»¶ä¸­åQŒMethodSecurityInterceptor是AbstractSecurityInterceptor的一个实现类。它包含了两个管理器åQŒauthenticationManagerå’ŒaccessDecisionManager。这两者的配置如下åQ?br />      <pre class="overflow"><bean id="authenticationDao" class="net.sf.acegisecurity.providers.dao.jdbc.JdbcDaoImpl"><br />               <property name="dataSource"><ref bean="dataSource"/></property><br />      </bean><br />      <bean id="daoAuthenticationProvider" <br />                     class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider"><br />               <property name="authenticationDao"><ref bean="authenticationDao"/></property><br />      </bean><br />      <bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager"><br />               <property name="providers"><br />                      <list><ref bean="daoAuthenticationProvider"/></list><br />               </property><br />      </bean><br />      <bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/><br />      <bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased"><br />               <property name="allowIfAllAbstainDecisions"><value>false</value></property><br />               <property name="decisionVoters"><br />                      <list><ref bean="roleVoter"/></list><br />               </property><br />      </bean></pre><br /><br />       准备工作做好了,现在我们来看看Acegi安全¾pȝ»Ÿæ˜¯å¦‚何实现认证和授权机制的。以使用HTTP BASICè®¤è¯çš„åº”ç”¨äØ“ä¾‹å­åQŒå®ƒåŒ…括下面的步骤:<br />       1. 用户ç™Õd½•¾pȝ»ŸåQŒAcegi从acegisecurity.ui子系¾lŸçš„安全拦截器(如BasicProcessingFilteråQ‰ä¸­å¾—到用户的登录信息(包括Principalå’ŒCredentialåQ‰åƈ攑օ¥Authentication对象åQŒåƈ保存在ContextHolder对象中;<br />       2. 安全拦截器将Authentication对象交给AuthenticationManager˜q›è¡Œíw«ä†¾è®¤è¯åQŒå¦‚果认证通过åQŒè¿”回带有Principal授权信息的Authentication对象。此时ContextHolder对象的Authentication对象已拥有Principal的详¾l†ä¿¡æ¯ï¼›<br />       3. 用户ç™Õd½•成功后,¾l§ç®‹˜q›è¡Œä¸šåŠ¡æ“ä½œåQ?br />       4. 安全拦截器(bankManagerSecurityåQ‰æ”¶åˆ°å®¢æˆïL«¯æ“ä½œè¯äh±‚后,ž®†æ“ä½œè¯·æ±‚的数据包装成安全管理对象(FilterInvocation或MethodInvocation对象åQ‰ï¼›<br />       5. 然后åQŒä»Žé…ç½®æ–‡äšgåQˆObjectDefinitionSourceåQ‰ä¸­è¯Õd‡ºç›¸å…³çš„安全配¾|®å‚æ•°ConfigAttributeDefinitionåQ?br />       6. 接着åQŒå®‰å…¨æ‹¦æˆªå™¨å–出ContextHolder中的Authentication对象åQŒæŠŠå®ƒä¼ é€’ç»™AuthenticationManager˜q›è¡Œíw«ä†¾è®¤è¯åQŒåƈ用返回值更新ContextHolderçš„Authentication对象åQ?br />       7. ž®†Authentication对象åQŒConfigAttributeDefinition对象和安全管理对象(secure ObjectåQ‰äº¤¾l™AccessDecisionManageråQŒæ£€æŸ¥Principal的操作授权;<br />       8. 如果授权‹‚€æŸ¥é€šè¿‡åˆ™æ‰§è¡Œå®¢æˆïL«¯è¯äh±‚的操作,否则拒绝åQ?br /><br /><b>AccessDecisionVoter</b><br />       注意上节的accessDecisionManager是一个AffirmativeBased¾c»ï¼Œå®ƒå¯¹äºŽç”¨æˆähŽˆæƒçš„æŠ•ç¥¨½{–略是,只要通过其中的一个授权投¼œ¨æ£€æŸ¥ï¼Œå›_¯é€šè¿‡åQ›å®ƒçš„allowIfAllAbstainDecisions属性值是falseåQŒæ„æ€æ˜¯å¦‚果所有的授权投票是都是弃权,则通不˜q‡æŽˆæƒæ£€æŸ¥ã€?br />       Acegi安全¾pȝ»ŸåŒ…括了几个基于投¼œ¨ç­–略的AccessDecisionManageråQŒä¸ŠèŠ‚çš„RoleVoterž®±æ˜¯å…¶ä¸­çš„一个投¼œ¨ç­–略实玎ͼŒå®ƒæ˜¯AccessDecisionVoter的一个子¾c…R€‚AccessDecisionVoter的具体实现类通过投票来进行授权决½{–,AccessDecisionManager则根据投¼œ¨ç»“果来军_®šæ˜¯é€šè¿‡æŽˆæƒ‹‚€æŸ¥ï¼Œ˜q˜æ˜¯æŠ›å‡ºAccessDeniedException例外ã€?br />       AccessDecisionVoter接口共有三个æ–ÒŽ³•åQ?br />public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config);<br />public boolean supports(ConfigAttribute attribute);<br />public boolean supports(Class clazz);<br />       其中的voteæ–ÒŽ³•˜q”回int˜q”回å€û|¼Œå®ƒä»¬æ˜¯AccessDecisionVoter的三个静态成员属性:ACCESS_ABSTAIN,åQŒACCESS_DENIEDå’ŒACCESS_GRANTEDåQŒå®ƒä»¬åˆ†åˆ«æ˜¯å¼ƒæƒåQŒå¦å†›_’Œèµžæˆã€?br />       Acegi安全¾pȝ»Ÿä¸­ï¼Œä½¿ç”¨æŠ•票½{–略的AccessDecisionManager共有三个具体实现¾c»ï¼šAffirmativeBased、ConsensusBasedå’ŒUnanimousBased。它们的投票½{–略是,AffirmativeBased¾cÕdªéœ€æœ‰ä¸€ä¸ªæŠ•¼œ¨èµžæˆå³å¯é€šè¿‡åQ›ConsensusBased¾c»éœ€è¦å¤§å¤šæ•°æŠ•票赞成卛_¯é€šè¿‡åQ›è€ŒUnanimousBased¾c»éœ€è¦æ‰€æœ‰çš„æŠ•票赞成才能通过ã€?br />       RoleVoter¾cÀL˜¯ä¸€ä¸ªAcegi安全¾pȝ»ŸAccessDecisionVoter接口的实现。如果ConfigAttribute以ROLE_å¼€å¤ß_¼ŒRoleVoter则进行投¼œ¨ã€‚如果GrantedAuthorityçš„getAutorityæ–ÒŽ³•çš„String˜q”回值匹配一个或多个以ROLE_开头的ConfigAttributeåQŒåˆ™æŠ•票通过åQŒå¦åˆ™ä¸é€šè¿‡ã€‚如果没有以ROLE_开头的ConfigAttributeåQŒRoleVoter则弃权ã€?br /><br /><b>安全拦截å™?/b><br />  拦截器如何工ä½?br />  MethodInvocation拦截å™?br />  FilterInvocation拦截å™?br />认证<br />  认证è¯äh±‚<br />  认证½Ž¡ç†å™?br />  Authentication Provider<br />授权<br />  Access Decision Manager<br />  Voting Decision Manager<br />  授权½Ž¡ç†æŽ¨è<br />ContextHolder的用æˆähŽ¥å?br />  用户接口目标<br />  HTTP会话认证<br />  HTTP Basic认证<br /><br />1、Log4j的概å¿?br />   Log4j中有三个主要的组ä»Óž¼Œå®ƒä»¬åˆ†åˆ«æ˜¯Logger、Appenderå’ŒLayoutåQŒLog4j 允许开发äh员定义多个LoggeråQŒæ¯ä¸ªLogger拥有自己的名字,Logger之间通过名字来表明隶属关¾p…R€‚有一个Logger¿UîCØ“RootåQŒå®ƒæ°¸è¿œ 存在åQŒä¸”不能通过名字‹‚€ç´¢æˆ–引用åQŒå¯ä»¥é€šè¿‡Logger.getRootLogger()æ–ÒŽ³•获得åQŒå…¶å®ƒLogger通过 Logger.getLogger(String name)æ–ÒŽ³•ã€?br />   Appender则是用来指明ž®†æ‰€æœ‰çš„log信息存放åˆîC»€ä¹ˆåœ°æ–¹ï¼ŒLog4j中支持多¿UappenderåQŒå¦‚ console、files、GUI components、NT Event Loggers½{‰ï¼Œä¸€ä¸ªLogger可以拥有多个AppenderåQŒä¹Ÿž®±æ˜¯ä½ æ—¢å¯ä»¥ž®†Log信息输出到屏òq•,同时存储åˆîC¸€ä¸ªæ–‡ä»¶ä¸­ã€?br />   Layout的作用是控制Log信息的输出方式,也就是格式化输出的信息ã€?br />   Log4j中将要输出的Log信息定义äº?¿Uçñ”别,依次为DEBUG、INFO、WARN、ERRORå’ŒFATALåQŒå½“输出æ—Óž¼Œåªæœ‰¾U§åˆ«é«˜è¿‡é…ç½®ä¸­è§„定的 ¾U§åˆ«çš„信息才能真正的输出åQŒè¿™æ ·å°±å¾ˆæ–¹ä¾¿çš„æ¥é…¾|®ä¸åŒæƒ…况下要输出的内容åQŒè€Œä¸éœ€è¦æ›´æ”¹ä»£ç ï¼Œ˜q™ç‚¹å®žåœ¨æ˜¯æ–¹ä¾¿å•Šã€?br /><br />2、Log4j的配¾|®æ–‡ä»?br />  虽然可以不用配置文äšgåQŒè€Œåœ¨½E‹åºä¸­å®žçŽ°é…¾|®ï¼Œä½†è¿™¿Uæ–¹æ³•在如今的系¾lŸå¼€å‘中昄¡„¶æ˜¯ä¸å¯å–的,能采用配¾|®æ–‡ä»¶çš„地方一定一定要用配¾|®æ–‡ä»¶ã€‚Log4j支持ä¸?¿Uæ ¼å¼çš„配置文äšgåQšXML格式和Javaçš„property格式åQŒæœ¬äººæ›´å–œæ¬¢åŽè€…,首先看一个简单的例子吧,如下åQ?br /><br /><pre class="overflow"> log4j.rootLogger=debug, stdout, R<br />  log4j.appender.stdout=org.apache.log4j.ConsoleAppender<br />  log4j.appender.stdout.layout=org.apache.log4j.PatternLayout<br /><br />  # Pattern to output the caller's file name and line number.<br />  log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n<br /><br />  log4j.appender.R=org.apache.log4j.RollingFileAppender<br />  log4j.appender.R.File=example.log<br />  log4j.appender.R.MaxFileSize=100KB<br /><br />  # Keep one backup file<br />  log4j.appender.R.MaxBackupIndex=1<br /><br />  log4j.appender.R.layout=org.apache.log4j.PatternLayout<br />  log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n</pre>         <br /><br />  首先åQŒæ˜¯è®„¡½®rootåQŒæ ¼å¼äØ“ log4j.rootLogger=[level],appenderName, ...åQŒå…¶ä¸­levelž®±æ˜¯è®„¡½®éœ€è¦è¾“å‡ÞZ¿¡æ¯çš„¾U§åˆ«åQŒåŽé¢æ˜¯appender的输出的目的圎ͼŒappenderNamež®±æ˜¯æŒ‡å®šæ—¥å¿—信息输出到哪个地斏V€‚您可以同时指定多个输出目的地。配¾|®æ—¥å¿—信息输出目的地AppenderåQŒå…¶è¯­æ³•ä¸?br />  log4j.appender.appenderName = fully.qualified.name.of.appender.class<br />  log4j.appender.appenderName.option1 = value1<br />  ...<br />  log4j.appender.appenderName.option = valueN<br />Log4j提供的appender有以下几¿Uï¼š<br />  org.apache.log4j.ConsoleAppenderåQˆæŽ§åˆ¶å°åQ?br />  org.apache.log4j.FileAppenderåQˆæ–‡ä»Óž¼‰<br />  org.apache.log4j.DailyRollingFileAppenderåQˆæ¯å¤©äñ”生一个日志文ä»Óž¼‰<br />  org.apache.log4j.RollingFileAppenderåQˆæ–‡ä»¶å¤§ž®åˆ°è¾¾æŒ‡å®šå°ºå¯¸çš„æ—¶å€™äñ”生新文äšgåQ?br />  org.apache.log4j.WriterAppenderåQˆå°†æ—¥å¿—信息以流格式发送到ä»ÀL„æŒ‡å®šçš„地方)<br />配置日志信息的格式(布局åQ‰ï¼Œå…¶è¯­æ³•䨓åQ?br />  log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class<br />  log4j.appender.appenderName.layout.option1 = value1<br />  ....<br />  log4j.appender.appenderName.layout.option = valueN<br />Log4j提供的layout有以下几¿Uï¼š<br />  org.apache.log4j.HTMLLayoutåQˆä»¥HTML表格形式布局åQ‰ï¼Œ<br />  org.apache.log4j.PatternLayoutåQˆå¯ä»¥çµ‹zÕdœ°æŒ‡å®šå¸ƒå±€æ¨¡å¼åQ‰ï¼Œ<br />  org.apache.log4j.SimpleLayoutåQˆåŒ…含日志信息的¾U§åˆ«å’Œä¿¡æ¯å­—½W¦ä¸²åQ‰ï¼Œ<br />  org.apache.log4j.TTCCLayoutåQˆåŒ…含日志äñ”生的旉™—´ã€çº¿½E‹ã€ç±»åˆ«ç­‰½{‰ä¿¡æ¯ï¼‰ <br /><br />3、Log4j在程序中的ä‹Éç”?br />  要在自己的类中ä‹É用Log4jåQŒé¦–先声明一个静态变量Logger logger=Logger.getLog("classname")åQ›åœ¨ä½¿ç”¨ä¹‹å‰åQŒç”¨PropertyConfigurator.configure ("配置文äšg")配置一下,现在ž®±å¯ä»¥ä‹É用了åQŒç”¨æ³•如下:logger.debug("debug message")或者logger.info("info message")åQŒçœ‹ä¸‹é¢ä¸€ä¸ªå°ä¾‹å­åQ?br /><br /><pre class="overflow"> import com.foo.Bar;<br />  import org.apache.log4j.Logger;<br />  import org.apache.log4j.PropertyConfigurator;<br />  public class MyApp {<br />    static Logger logger = Logger.getLogger(MyApp.class.getName());<br />    public static void main(String[] args) {<br />      // BasicConfigurator replaced with PropertyConfigurator.<br />      PropertyConfigurator.configure(args[0]);<br />      logger.info("Entering application.");<br />      Bar bar = new Bar();<br />      bar.doIt();<br />      logger.info("Exiting application.");<br />    }<br />  }</pre><br /><br /><br />[½Ž€ä»‹]<br /><br />对于一个典型的Web应用åQŒå®Œå–„的认证和授权机制是必不可少的,在SpringFramework中,Juergen Hoeller提供的范例JPetStore¾l™äº†ä¸€äº›è¿™æ–šw¢çš„介¾lï¼Œä½†è¿˜˜qœè¿œä¸å¤ŸåQŒAcegiæ˜¯ä¸€ä¸ªä¸“é—¨äØ“SpringFramework提供安全机制çš?™å¹ç›®åQŒå…¨¿UîCØ“Acegi Security System for SpringåQŒå½“å‰ç‰ˆæœ¬äØ“0.5.1åQŒå°±å…¶ç›®å‰æä¾›çš„功能åQŒåº”该可以满­‘³ç»å¤§å¤šæ•°åº”用的需求ã€?br /><br />本文的主要目的是希望能够说明如何在基于Spring构架的Web应用中ä‹É用AcegiåQŒè€Œä¸æ˜¯è¯¦¾l†ä»‹¾lå…¶ä¸­çš„æ¯ä¸ªæŽ¥å£ã€æ¯ä¸ªç±»ã€‚注意,即ä‹É对已¾lå­˜åœ¨çš„Spring应用åQŒé€šè¿‡ä¸‹é¢ä»‹ç»çš„æ­¥éª¤ï¼Œä¹Ÿå¯ä»¥é©¬ä¸Šäín受到Acegi提供的认证和授权ã€?br /><br />[基础工作]<br />在你的Web应用的lib中添加Acegi下蝲包中的acegi-security.jar<br /><br />[web.xml]<br />实现认证和授权的最常用的方法是通过filteråQŒAcegi亦是如此åQŒé€šå¸¸Acegi需要在web.xmlæ·ÕdР以䏋5个filter:<br /><br /><pre class="overflow"><filter><br />  <filter-name>Acegi Channel Processing Filter</filter-name><br />  <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class><br />  <init-param><br />    <param-name>targetClass</param-name><br />    <param-value>net.sf.acegisecurity.securechannel.ChannelProcessingFilter</param-value><br />  </init-param><br /></filter><br /><filter><br />  <filter-name>Acegi Authentication Processing Filter</filter-name><br />  <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class><br />  <init-param><br />    <param-name>targetClass</param-name><br />    <param-value>net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter</param-value><br />  </init-param><br /></filter><br /><filter><br />  <filter-name>Acegi HTTP BASIC Authorization Filter</filter-name><br />  <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class><br />  <init-param><br />    <param-name>targetClass</param-name><br />    <param-value>net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter</param-value><br />  </init-param><br /></filter><br /><filter><br />  <filter-name>Acegi Security System for Spring Auto Integration Filter</filter-name><br />  <filter-class>net.sf.acegisecurity.ui.AutoIntegrationFilter</filter-class><br /></filter><br /><filter><br />  <filter-name>Acegi HTTP Request Security Filter</filter-name><br />  <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class><br />  <init-param><br />    <param-name>targetClass</param-name><br />    <param-value>net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter</param-value><br />  </init-param><br /></filter></pre><br /><br />最先引赯‚¿·æƒ‘的是net.sf.acegisecurity.util.FilterToBeanProxyåQŒAcegi自己的文档上解释是: “What  FilterToBeanProxy does is delegate the Filter's methods through to a bean which is obtained from the <br />Spring application context. This enables the bean to benefit from the Spring application context lifecycle support and configuration flexibility.”,如希望深½I¶çš„话,åŽÈœ‹çœ‹æºä»£ç åº”该不难理解ã€?br /><br />再下来就是添加filter-mapping了:<br /><pre class="overflow"><filter-mapping><br />  <filter-name>Acegi Channel Processing Filter</filter-name><br />  <url-pattern>/*</url-pattern><br /></filter-mapping><br /><filter-mapping><br />  <filter-name>Acegi Authentication Processing Filter</filter-name><br />  <url-pattern>/*</url-pattern><br /></filter-mapping><br /><filter-mapping><br />  <filter-name>Acegi HTTP BASIC Authorization Filter</filter-name><br />  <url-pattern>/*</url-pattern><br /></filter-mapping><br /><filter-mapping><br />  <filter-name>Acegi Security System for Spring Auto Integration Filter</filter-name><br />  <url-pattern>/*</url-pattern><br /></filter-mapping><br /><filter-mapping><br />  <filter-name>Acegi HTTP Request Security Filter</filter-name><br />  <url-pattern>/*</url-pattern><br /></filter-mapping></pre><br /><br />˜q™é‡ŒåQŒéœ€è¦æ³¨æ„ä»¥ä¸‹ä¸¤ç‚¹ï¼š<br />1) ˜q™å‡ ä¸ªfilter的顺序是不能更改的,™åºåºä¸å¯¹ž®†æ— æ³•正常工作;<br />2) 如果你的应用不需要安全传输,如httpsåQŒåˆ™ž®?Acegi Channel Processing Filter"相关内容注释掉即可;<br />3) 如果你的应用不需要Spring提供的远½E‹è®¿é—®æœºåˆÓž¼Œå¦‚Hessian and BurlapåQŒå°†"Acegi HTTP BASIC Authorization <br />Filter"相关内容注释掉即可ã€?br /><br />[applicationContext.xml]<br />接下来就是要æ·ÕdŠ applicationContext.xml中的内容了,从刚才FilterToBeanFactory的解释可以看出,真正的filteréƒ?br />在Springçš„applicationContext中管理:<br /><br />1) 首先åQŒä½ çš„æ•°æ®åº“中必™åÕd…·æœ‰ä¿å­˜ç”¨æˆ·åå’Œå¯†ç çš„tableåQŒAcegi要求tableçš„schema必须如下åQ?br /><br /><pre class="overflow">CREATE TABLE users (<br />    username VARCHAR(50) NOT NULL PRIMARY KEY,<br />    password VARCHAR(50) NOT NULL,<br />    enabled BIT NOT NULL<br />);<br />CREATE TABLE authorities (<br />    username VARCHAR(50) NOT NULL,<br />    authority VARCHAR(50) NOT NULL<br />);<br />CREATE UNIQUE INDEX ix_auth_username ON authorities ( username, authority );<br />ALTER TABLE authorities ADD CONSTRAINT fk_authorities_users foreign key (username) REFERENCES users<br />(username);</pre><br /><br />2) æ·ÕdŠ è®‰K—®ä½ çš„æ•°æ®åº“çš„datasourceå’ŒAcegiçš„jdbcDaoåQŒå¦‚下:<br /><br /><pre class="overflow"><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><br />  <property name="driverClassName"><value>${jdbc.driverClassName}</value></property><br />  <property name="url"><value>${jdbc.url}</value></property><br />  <property name="username"><value>${jdbc.username}</value></property><br />  <property name="password"><value>${jdbc.password}</value></property><br /></bean><br /><bean id="jdbcDaoImpl" class="net.sf.acegisecurity.providers.dao.jdbc.JdbcDaoImpl"><br />  <property name="dataSource"><ref bean="dataSource"/></property><br /></bean></pre><br /><br />3) æ·ÕdŠ DaoAuthenticationProvider:<br /><br /><pre class="overflow"><bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider"><br />  <property name="authenticationDao"><ref bean="authenticationDao"/></property><br />  <property name="userCache"><ref bean="userCache"/></property><br /></bean><br /><br /><bean id="userCache" class="net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache"><br />  <property name="minutesToIdle"><value>5</value></property><br /></bean></pre><br /><br />如果你需要对密码加密åQŒåˆ™åœ¨daoAuthenticationProvider中加入:<property name="passwordEncoder"><ref <br />bean="passwordEncoder"/></property>åQŒAcegi提供了几¿UåŠ å¯†æ–¹æ³•ï¼Œè¯¦ç»†æƒ…å†µå¯çœ‹åŒ?br />net.sf.acegisecurity.providers.encoding<br /><br />4) æ·ÕdŠ authenticationManager:<br /><br /><pre class="overflow"><bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager"><br />  <property name="providers"><br />    <list><br />      <ref bean="daoAuthenticationProvider"/><br />    </list><br />   </property><br /></bean></pre><br /><br />5) æ·ÕdŠ accessDecisionManager:<br /><br /><pre class="overflow"><bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased"><br />  <property name="allowIfAllAbstainDecisions"><br />    <value>false</value><br />  </property><br />  <property name="decisionVoters"><br />    <list><ref bean="roleVoter"/></list><br />  </property><br /></bean><br /><bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/></pre><br /><br />6) æ·ÕdŠ authenticationProcessingFilterEntryPoint:<br /><br /><pre class="overflow"><bean id="authenticationProcessingFilterEntryPoint" <br />class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint"><br />  <property name="loginFormUrl"><value>/acegilogin.jsp</value></property><br />  <property name="forceHttps"><value>false</value></property><br /></bean></pre><br /><br />其中acegilogin.jsp是登陆页面,一个最½Ž€å•çš„ç™Õd½•™åµé¢å¦‚下åQ?br /><br /><pre class="overflow"><%@ taglib prefix='c' uri='http://java.sun.com/jstl/core' %><br /><%@ page import="net.sf.acegisecurity.ui.AbstractProcessingFilter" %><br /><%@ page import="net.sf.acegisecurity.AuthenticationException" %><br /><html><br />  <head><br />    <title>Login</title><br />  </head><br /><br />  <body><br />    <h1>Login</h1><br />    <form action="<c:url value='j_acegi_security_check'/>" method="POST"><br />      <table><br />        <tr><td>User:</td><td><input type='text' name='j_username'></td></tr><br />        <tr><td>Password:</td><td><input type='password' name='j_password'></td></tr><br />        <tr><td colspan='2'><input name="submit" type="submit"></td></tr><br />        <tr><td colspan='2'><input name="reset" type="reset"></td></tr><br />      </table><br />    </form><br />  </body><br /></html></pre><br /><br />7) æ·ÕdŠ filterInvocationInterceptor:<br /><br /><pre class="overflow"><bean id="filterInvocationInterceptor" <br />class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor"><br />  <property name="authenticationManager"><br />    <ref bean="authenticationManager"/><br />  </property><br />  <property name="accessDecisionManager"><br />    <ref bean="accessDecisionManager"/><br />  </property><br />  <property name="objectDefinitionSource"><br />    <value><br />      CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON<br />      \A/sec/administrator.*\Z=ROLE_SUPERVISOR<br />      \A/sec/user.*\Z=ROLE_TELLER<br />    </value><br />  </property><br /></bean></pre><br /><br />˜q™é‡Œè¯äh³¨æ„ï¼Œè¦objectDefinitionSource中定义哪些页面需要权限访问,需要根据自å·Þqš„应用需求进行修改,我上面给å‡?br />的定义的意思是˜q™æ ·çš„:<br />a. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON意思是在比较请求èµ\径时全部转换为小å†?br />b. \A/sec/administrator.*\Z=ROLE_SUPERVISOR意思是只有权限为ROLE_SUPERVISOR才能讉K—®/sec/administrator*的页é?br />c. \A/sec/user.*\Z=ROLE_TELLER意思是只有权限为ROLE_TELLER的用æˆäh‰èƒ½è®¿é—?sec/user*的页é?br /><br />8) æ·ÕdŠ securityEnforcementFilter:<br /><br /><pre class="overflow"><bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter"><br />  <property name="filterSecurityInterceptor"><br />    <ref bean="filterInvocationInterceptor"/><br />  </property><br />  <property name="authenticationEntryPoint"><br />    <ref bean="authenticationProcessingFilterEntryPoint"/><br />  </property><br /></bean></pre><br /><br />9) æ·ÕdŠ authenticationProcessingFilter:<br /><br /><pre class="overflow"><bean id="authenticationProcessingFilter" <br />class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter"><br />  <property name="authenticationManager"><br />    <ref bean="authenticationManager"/><br />  </property><br />  <property name="authenticationFailureUrl"><br />    <value>/loginerror.jsp</value><br />  </property><br />  <property name="defaultTargetUrl"><br />    <value>/</value><br />  </property><br />  <property name="filterProcessesUrl"><br />    <value>/j_acegi_security_check</value><br />  </property><br /></bean></pre><br />其中authenticationFailureUrl是认证失败的™åµé¢ã€?br /><br />10) 如果需要一些页面通过安全通道的话åQŒæ·»åŠ ä¸‹é¢çš„é…ç½®:<br /><br /><pre class="overflow"><bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter"><br />  <property name="channelDecisionManager"><br />    <ref bean="channelDecisionManager"/><br />  </property><br />  <property name="filterInvocationDefinitionSource"><br />    <value><br />      CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON<br />      \A/sec/administrator.*\Z=REQUIRES_SECURE_CHANNEL<br />      \A/acegilogin.jsp.*\Z=REQUIRES_SECURE_CHANNEL<br />      \A/j_acegi_security_check.*\Z=REQUIRES_SECURE_CHANNEL<br />      \A.*\Z=REQUIRES_INSECURE_CHANNEL<br />    </value><br />  </property><br /></bean><br /><br /><bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl"><br />  <property name="channelProcessors"><br />    <list><br />      <ref bean="secureChannelProcessor"/><br />      <ref bean="insecureChannelProcessor"/><br />    </list><br />  </property><br /></bean><br /><bean id="secureChannelProcessor" class="net.sf.acegisecurity.securechannel.SecureChannelProcessor"/><br /><bean id="insecureChannelProcessor" class="net.sf.acegisecurity.securechannel.InsecureChannelProcessor"/></pre><br /><br />[¾~ºå°‘了什么?]<br />Acegi目前提供了两¿U?secure object"åQŒåˆ†åˆ«å¯¹™åµé¢å’Œæ–¹æ³•进行安全认证管理,我这里介¾lçš„只是利用<br />FilterSecurityInterceptor对访问页面的权限控制åQŒé™¤æ­¤ä¹‹å¤–,Acegi˜q˜æä¾›äº†å¦å¤–一个Interceptor―â€?br />MethodSecurityInterceptoråQŒå®ƒ¾l“合runAsManager可实现对对象中的æ–ÒŽ³•的权限控åˆÓž¼Œä½¿ç”¨æ–ÒŽ³•可参看Acegi自带的文æ¡?br />å’Œcontact范例ã€?br /><br />[最后要说的]<br />æœ¬æ¥ä»¥äØ“åªæ˜¯è¯´æ˜Žå¦‚ä½•ä½¿ç”¨Acegi而已åQŒåº”该非常简单,但真正写èµäh¥æ‰å‘现想要条理清楚的理顺所有需要的bean˜q˜æ˜¯å¾?br />困难的,但愿我没有遗漏太多东西,如果我的文章有什么遗漏或错误的话åQŒè¿˜è¯·å‚看Acegi自带的quick-start范例åQŒä½†è¯?br />注意åQŒè¿™ä¸ªèŒƒä¾‹æ˜¯ä¸èƒ½ç›´æŽ¥æ‹¿æ¥ç”¨çš„ã€?br />分析和学习Spring中的jpetstore用户½Ž¡ç† <br />  存在用户的系¾lŸï¼Œå¿…然需要用æˆïLš„ç™Õd½•和认证,今天ž®±é€šè¿‡åˆ†æžSpring中自带的jpetstore的例子来学习一下如何实现在Spring构架的系¾lŸä¸­ç”¨æˆ·ç™Õd½•ã€?br />1、首先从注册用户开始,先看看jpetstore-servlet.xml中关于注册用æˆïLš„bean定义åQŒä»Žå®šä¹‰å‘½åä¸­å°±å¯ä»¥çœ‹å‡ºä¸‹é¢˜q™æ®µž®±æ˜¯æ³¨å†Œç”¨æˆ·çš„:<br />  <pre class="overflow"><bean name="/shop/newAccount.do" class="org.springframework.samples.jpetstore.web.spring.AccountFormController"><br />    <property name="petStore"><ref bean="petStore"/></property><br />    <property name="validator"><ref bean="accountValidator"/></property><br />    <property name="successView"><value>index</value></property><br />  </bean></pre><br />1). formView呢?从AccountFormController的构造函æ•îC¸­å¾—到åQŒåŽŸæ¥äØ“EditAccountFormåQ›Â Â?br />2). EditoAccountForm.jspä¸­æ˜¾å¾—éžå¸æ€Ø•åQŒå…¶å®žæ²¡æœ‰å¤šž®‘难理解的地方,最主要的是˜q™ä¸ªform既是æ·ÕdŠ æ–°ç”¨æˆïLš„åQŒåˆæ˜¯ç¼–辑用户信息的åQŒæ‰€ä»¥æ˜¾å¾—æœ‰ç‚¹äØ•¾pŸç³Ÿçš„ã€?br />2、添加好了新用户åQŒæŽ¥ä¸‹æ¥çœ‹çœ‹å¦‚何ç™Õd½•åQŒåœ¨jpetstore-servlet中发现这两个相关bean定义åQŒå¦‚下:<br />  <pre class="overflow"><bean name="/shop/signon.do" class="org.springframework.samples.jpetstore.web.spring.SignonController"><br />    <property name="petStore"><ref bean="petStore"/></property><br />  </bean><br />  <bean name="/shop/signonForm.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController"><br />    <property name="viewName"><value>SignonForm</value></property><br />  </bean></pre><br />1). ½W¬äºŒä¸ªbean是在˜qè¡Œæ—¶ç”¨æˆ¯‚¾“入用户名和密码的formåQŒå«åšSignonFormåQŒå¯¹äºŽè¿™ä¸?ParameterizableViewControlleråQŒç”¨æ–‡æ¡£é‡Œçš„话说˜q™æ˜¯æœ€½Ž€å•çš„ControlleråQŒå…¶ä½œç”¨ž®±æ˜¯åœ¨è¿è¡Œä¸­æŒ‡å‘ Controller而不是直接指向jspæ–‡äšgåQŒä»…此而已ã€?br />2). SignonForm.jspåQŒé‡Œé¢å°±æ˜¯ä¸€ä¸ªç®€å•çš„formåQŒå…¶actionž®±æ˜¯½W¬ä¸€ä¸ªbeanåQŒå³/shop/signon.doåQŒæœ€éœ€è¦æ³¨æ„çš„æ˜?signonForwardActionåQŒå…¶ä¸»è¦ä½œç”¨æ˜¯forward到需要输入用户名和密码的那个™åµé¢ä¸ŠåŽ»åQŒè¿™ä¸ªå˜é‡å“ªé‡Œæ¥çš„å‘¢åQŸçœ‹çœ‹ä¸‹é¢ï¼š<br />  <pre class="overflow"><bean id="secureHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"><br />    <property name="interceptors"><br />      <list><br />        <ref bean="signonInterceptor"/><br />      </list><br />    </property><br />    <property name="urlMap"><br />      <map><br />        <entry key="/shop/editAccount.do"><ref local="secure_editAccount"/></entry><br />        <entry key="/shop/listOrders.do"><ref local="secure_listOrders"/></entry><br />        <entry key="/shop/newOrder.do"><ref local="secure_newOrder"/></entry><br />        <entry key="/shop/viewOrder.do"><ref local="secure_viewOrder"/></entry><br />      </map><br />    </property><br />  </bean></pre><br />  原来åQŒä¸Šé¢çš„signonInterceptor实现了preHandleåQŒå› æ­¤åœ¨è¯äh±‚上面的map™åµé¢æ—Óž¼Œé¦–先要经˜q‡è¿™ä¸ªInterceptoråQŒçœ‹çœ?SignonInterceptorçš„æºç ï¼ŒåŽŸæ¥åœ¨å…¶ä¸­äØ“signon.jsp赋予一个signonForwardAction对象åQŒå‘µå‘µï¼Œæ€È®—明白了ã€?br />3). 接下来去学习一下SignonControlleråQŒå…¶ä¸ÖM½“部分中可以看出,首先取出用户输入的usernameå’ŒpasswordåQŒç„¶åŽåˆ°æ•°æ®åº“中验证 æœ‰æ²¡æœ‰è¿™ä¸ªç”¨æˆøP¼Œå¦‚果没有˜q™ä¸ªç”¨æˆ·åQŒè¿”回各错误™åµé¢åQ›å¦‚果成功,首先生成一个UserSession对象åQŒåœ¨requestçš„session加入˜q™ä¸ª userSessionåQŒæ³¨æ„è¿™éƒ¨åˆ†ä»£ç ä¸­ç»™å‡ÞZº†PagedListHolder分页的简单ä‹É用方法,关于分页昄¡¤ºåQŒä»¥åŽå†å­¦ä¹ å§ã€?br />3、登录成功后åQŒå°±å¯ä»¥æ ÒŽ®ä¸åŒçš„用戯‚®¾æ–½ä¸åŒçš„è¡ŒäØ“äº†ï¼Œå–å¾—ç”¨æˆ·ä¿¡æ¯åQŒæ— éžå°±æ˜¯ä»Žsession取出userSession卛_¯ã€?br /></div><img src ="http://www.aygfsteel.com/mkchen/aggbug/90397.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/mkchen/" target="_blank">‹¹äh€?/a> 2006-12-27 23:20 <a href="http://www.aygfsteel.com/mkchen/archive/2006/12/27/90397.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> Ö÷Õ¾Ö©Öë³ØÄ£°å£º <a href="http://" target="_blank">ɽÒõÏØ</a>| <a href="http://" target="_blank">ãÉÐÐÇø</a>| <a href="http://" target="_blank">¹ð¶«ÏØ</a>| <a href="http://" target="_blank">ÊÕ²Ø</a>| <a href="http://" target="_blank">»¨Á«ÏØ</a>| <a href="http://" target="_blank">Ρɽ</a>| <a href="http://" target="_blank">ÒÊË®ÏØ</a>| <a href="http://" target="_blank">ÂÞÉ½ÏØ</a>| <a href="http://" target="_blank">ÎåÕ¯ÏØ</a>| <a href="http://" target="_blank">»¸Ì¨ÏØ</a>| <a href="http://" target="_blank">³¤ÄþÏØ</a>| <a href="http://" target="_blank">¹àÔÆÏØ</a>| <a href="http://" target="_blank">·À³Ç¸ÛÊÐ</a>| <a href="http://" target="_blank">³çÑôÏØ</a>| <a href="http://" target="_blank">½¨Ê¼ÏØ</a>| <a href="http://" target="_blank">Á鱦ÊÐ</a>| <a href="http://" target="_blank">ÉñÅ©¼ÜÁÖÇø</a>| <a href="http://" target="_blank">ǰ¹ù¶û</a>| <a href="http://" target="_blank">°²ÈûÏØ</a>| <a href="http://" target="_blank">¼ÎÒåÊÐ</a>| <a href="http://" target="_blank">ТÒåÊÐ</a>| <a href="http://" target="_blank">̨ÖÐÊÐ</a>| <a href="http://" target="_blank">Äϲ¿ÏØ</a>| <a href="http://" target="_blank">º×ɽÊÐ</a>| <a href="http://" target="_blank">Ë绯ÊÐ</a>| <a href="http://" target="_blank">Æ½É½ÏØ</a>| <a href="http://" target="_blank">ÎôÑôÏØ</a>| <a href="http://" target="_blank">ÈÊ»¯ÏØ</a>| <a href="http://" target="_blank">Ô˳ÇÊÐ</a>| <a href="http://" target="_blank">ÉÛÑôÏØ</a>| <a href="http://" target="_blank">ÐËÂ¡ÏØ</a>| <a href="http://" target="_blank">¾ÅÁúÏØ</a>| <a href="http://" target="_blank">³Â°Í¶û»¢Æì</a>| <a href="http://" target="_blank">ÉÐÒåÏØ</a>| <a href="http://" target="_blank">³ØÖÝÊÐ</a>| <a href="http://" target="_blank">¾¸±ßÏØ</a>| <a href="http://" target="_blank">Èý¶¼</a>| <a href="http://" target="_blank">ñçÑôÊÐ</a>| <a href="http://" target="_blank">·ïÏèÏØ</a>| <a href="http://" target="_blank">ÁÙÏÄÊÐ</a>| <a href="http://" target="_blank">ÌÒÔ°ÊÐ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>