亚洲男人天堂2018av,国产亚洲精品自在线观看,亚洲综合无码精品一区二区三区http://m.tkk7.com/rocky/category/5208.html現實的中沒有幾個人能夠真為對方去死,甚至山盟海誓很快就會在金錢面前變的微不足道,這才是生活。沒有永遠的愛,除了你的父母對你,當然也就沒有永遠的恨,更沒有永遠的痛,時間是最好的治療大師,它會很快撫平你心靈上累累的傷痕。很多年以后你想起來時,那些在你生命中洶涌來往的人群至多是個模糊的影子或者毫無意義的名字zh-cnTue, 27 Feb 2007 11:42:50 GMTTue, 27 Feb 2007 11:42:50 GMT60關于 sitemesh 在weblogic spring下的亂碼問題解決http://m.tkk7.com/rocky/archive/2005/12/18/24467.html老妖老妖Sun, 18 Dec 2005 04:39:00 GMThttp://m.tkk7.com/rocky/archive/2005/12/18/24467.htmlhttp://m.tkk7.com/rocky/comments/24467.htmlhttp://m.tkk7.com/rocky/archive/2005/12/18/24467.html#Feedback0http://m.tkk7.com/rocky/comments/commentRss/24467.htmlhttp://m.tkk7.com/rocky/services/trackbacks/24467.html<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" " http://java.sun.com/dtd/web-app_2_3.dtd ">
 
<web-app>
 
    
<filter>
        
<filter-name>sitemesh</filter-name>
        
<filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class> 
    
</filter>
 
    
<filter-mapping>
        
<filter-name>sitemesh</filter-name>
        
<url-pattern>/*</url-pattern>
    
</filter-mapping>
 
<filter> 
  
<filter-name>encodingFilter</filter-name>
  
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  
<init-param>
   
<param-name>encoding</param-name> 
   
<param-value>UTF-8</param-value>
  
</init-param>
  
<init-param>
   
<param-name>forceEncoding</param-name>
   
<param-value>true</param-value>
  
</init-param> 
 
</filter>
  
<filter-mapping>
  
<filter-name>encodingFilter</filter-name>
  
<url-pattern>*.jsp</url-pattern>
 
</filter-mapping>
</web-app>
sitemesh.xml:
<?xml version="1.0" encoding="utf-8"?>
<sitemesh>
    
<property name="decorators-file" value="/WEB-INF/decorators.xml"/> 
    
<excludes file="${decorators-file}"/> 
    
<page-parsers>
        
<parser default="true" class="com.opensymphony.module.sitemesh.parser.HTMLPageParser"/>
        
<parser content-type="text/html" class=" com.opensymphony.module.sitemesh.parser.HTMLPageParser"/>
        
<parser content-type="text/html;charset=UTF-8" class="com.opensymphony.module.sitemesh.parser.HTMLPageParser"/>
    
</page-parsers> 
 
    
<decorator-mappers>
        
<mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper">
            
<param name="config" value="${decorators-file}"/> 
        
</mapper>
    
</decorator-mappers>
</sitemesh>
decorators.xml:
<?xml version="1.0" encoding="utf-8"?>
 
<decorators defaultdir="/decorators">
    
<decorator name="main" page="test.jsp">
        
<pattern>/*</pattern>
    
</decorator>
 
    
<decorator name="panel" page="panel.jsp"/>
    
<decorator name="printable" page="printable.jsp"/>
</decorators> 
decorator的頁面test.jsp:
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib uri=" http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>
<%@ taglib uri=" http://www.opensymphony.com/sitemesh/page" prefix="page" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml ">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><decorator:title default="Mysterious page" /></title> 
<decorator:head />
</head>
 
<body>
<table width="100%" height="100%" border="0">
  
<tr>
    
<td width="29%"></td>
    
<td width="71%">&nbsp;哈哈 哈哈 
     
</td>
  
</tr>
  
<tr>
    
<td><decorator:body /></td>
    
<td>&nbsp;</td>
  
</tr>
</table>
</body>
</html> 
被裝飾器頁面1.jsp:
<%@ page contentType="text/html;charset=utf-8"%>
<html>
    
<head>
    
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">  
    
<title>哈哈</title>
    
</head>        
    
<body>
        
<h2>哈哈</h2>
    
</body>
</html>
作業環境:
weblogic sp 5
spring 1.2.6
sitemesh 2.2.1
發現有中文亂碼問題。

在google上查找很久都沒有方法解決,后懷疑是處理編碼的org.springframework.web.filter.CharacterEncodingFilter中的代碼中只對request做了編碼處理而沒有對response做編碼處理
自己對其做了一點小的修改紅色字部分
protected void doFilterInternal(
            HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            
throws ServletException, IOException {
        
super.doFilter(request,response,filterChain);
        
        
if (this.forceEncoding || request.getCharacterEncoding() == null) {
            request.setCharacterEncoding(
this.encoding);
            response.setContentType(
"text/html; charset="+this.encoding);
        }
        filterChain.doFilter(request, response);
    }
解決亂碼問題

老妖 2005-12-18 12:39 發表評論
]]>
新發現spring論壇的一個FAQ整理連接http://m.tkk7.com/rocky/archive/2005/11/23/21123.html老妖老妖Wed, 23 Nov 2005 06:26:00 GMThttp://m.tkk7.com/rocky/archive/2005/11/23/21123.htmlhttp://m.tkk7.com/rocky/comments/21123.htmlhttp://m.tkk7.com/rocky/archive/2005/11/23/21123.html#Feedback0http://m.tkk7.com/rocky/comments/commentRss/21123.htmlhttp://m.tkk7.com/rocky/services/trackbacks/21123.htmlhttp://forum.springframework.org/archive/index.php/

老妖 2005-11-23 14:26 發表評論
]]>
acegi擴展AbstractFilterInvocationDefinitionSourcehttp://m.tkk7.com/rocky/archive/2005/11/14/19627.html老妖老妖Sun, 13 Nov 2005 17:58:00 GMThttp://m.tkk7.com/rocky/archive/2005/11/14/19627.htmlhttp://m.tkk7.com/rocky/comments/19627.htmlhttp://m.tkk7.com/rocky/archive/2005/11/14/19627.html#Feedback4http://m.tkk7.com/rocky/comments/commentRss/19627.htmlhttp://m.tkk7.com/rocky/services/trackbacks/19627.html 1 package com.rdk.security.intercept.web;
 2 
 3 import net.sf.acegisecurity.intercept.web.FilterInvocationDefinitionSource;
 4 import net.sf.acegisecurity.intercept.web.AbstractFilterInvocationDefinitionSource;
 5 import net.sf.acegisecurity.ConfigAttributeDefinition;
 6 import net.sf.acegisecurity.SecurityConfig;
 7 
 8 import java.util.Iterator;
 9 
10 import com.rdk.security.persistence.ActionDao;
11 import com.rdk.security.domain.Action;
12 import com.rdk.security.domain.RoleAction;
13 import com.rdk.core.NullParameterException;
14 import org.springframework.dao.IncorrectResultSizeDataAccessException;
15 
16 /**
17 * Clase encargada de implementar la propiedad ObjectDefinitionSource para la clase de acegi
18 * FilterSecurityInterceptor esta implementacion le entrega el objeto ConfigAttributeDefinition
19 * con los roles permitidos a acceder a la url pasada como parametro.
20 * User: Rodney Gallart (rodney@radikalsystems.com)
21 * Date: Jan 25, 2005
22 * Time: 4:20:04 PM
23 */
24 public class DaoBasedFilterInvocationDefinitionSource
25 extends AbstractFilterInvocationDefinitionSource
26 implements FilterInvocationDefinitionSource {
27 
28 private ActionDao actionDao;
29 /**
30 * Implementacion dao de los objetos de tipo Action
31 @param actionDao
32 */
33 public void setActionDao(ActionDao actionDao) {
34 this.actionDao = actionDao;
35 }
36 
37 /**
38 * A este metodo se le pasa como parametro la url que se quiere acceder y devuelve el objeto
39 * ConfigAttributeDefinition donde vienen los roles que pueden acceder a esa url
40 *
41 * ConfigifAttributeDefinition contiene una lista de objetos que implementan la interfaz ConfigAttribute
42 * puede ser SecurityConfig (Roles como String)
43 *
44 * Ahora con la url pasada como parametro debe hacerse una busqueda en una lista de acciones cuando se encuentre
45 * la accion a la cual pertenece la url entonces se devuelve la lista de Roles
46 * TODO Analizar la posibilidad de implementar un mecanismo de cache Mapa(url, Action) y bajo que condiciones vaciarlo
47 @param url Pasada como paremetro para buscar sus roles permitidos
48 @return ConfigAttributeDefinition
49 */
50 public ConfigAttributeDefinition lookupAttributes(String url) {
51 if (url == null)
52 throw new NullParameterException("Parametro url null");
53 try {
54 url = url.toLowerCase();
55 url = url.substring(1);
56 if (url.contains("&"))
57 url = url.substring(0, url.indexOf("&"));
58 Action act = actionDao.findByUrl(url);
59 return obtainRolesInConfigAttributeDefinitionObject(act);
60 }
61 catch (IncorrectResultSizeDataAccessException ex) {
62 return null;
63 }
64 }
65 
66 /**
67 * En este metodo se van a obtener los roles asociados a la accion y se va a crear el
68 * objeto de tipo ConfigAttributeDefinition con la lista de objetos SecurityConfig
69 @param act
70 @return
71 */
72 private ConfigAttributeDefinition obtainRolesInConfigAttributeDefinitionObject(Action act) {
73 ConfigAttributeDefinition cad = new ConfigAttributeDefinition();
74 Iterator it = act.getRoles().iterator();
75 while(it.hasNext()) {
76 RoleAction ra = (RoleAction) it.next();
77 SecurityConfig sc = new SecurityConfig(ra.getRole().getName());
78 cad.addConfigAttribute(sc);
79 }
80 return cad;
81 }
82 
83 public Iterator getConfigAttributeDefinitions() {
84 return null;
85 }
86 
87 }
88 

老妖 2005-11-14 01:58 發表評論
]]>
spring的mail如何發送html格式的郵件--轉自邢紅瑞的bloghttp://m.tkk7.com/rocky/archive/2005/11/12/19438.html老妖老妖Fri, 11 Nov 2005 18:36:00 GMThttp://m.tkk7.com/rocky/archive/2005/11/12/19438.htmlhttp://m.tkk7.com/rocky/comments/19438.htmlhttp://m.tkk7.com/rocky/archive/2005/11/12/19438.html#Feedback1http://m.tkk7.com/rocky/comments/commentRss/19438.htmlhttp://m.tkk7.com/rocky/services/trackbacks/19438.html先是一個抽象的基類
 1 package com.educast.mail;
 2 
 3 import org.springframework.mail.javamail.JavaMailSender;
 4 
 5 /**
 6  * @author  mfc42d
 7  *
 8  */
 9 public abstract class BaseMailSender {
10 
11  protected String to;
12  protected String from;
13  protected String subject;
14  protected JavaMailSender sender;
15 
16 
17  public void setTo(String to) {
18   this.to = to;
19  }
20 
21  public void setFrom(String from) {
22   this.from = from;
23  }
24 
25  public void setSubject(String subject) {
26   this.subject = subject;
27  }
28 
29  public void setJavaMailSender(JavaMailSender sender) {
30   this.sender = sender;
31  }
32 }
33 
34 下面是具體的實現類
35 package com.educast.mail;
36 
37 
38 import javax.mail.MessagingException;
39 import javax.mail.internet.MimeMessage;
40 
41 import org.springframework.context.ApplicationContext;
42 import org.springframework.context.support.FileSystemXmlApplicationContext;
43 import org.springframework.mail.javamail.MimeMessageHelper;
44 
45 /**
46  * @author mfc42d
47  *  
48  */
49 public class SimpleHtmlMailSender extends BaseMailSender {
50 
51  public void sendMessage() throws MessagingException {
52   MimeMessage msg = sender.createMimeMessage();
53   MimeMessageHelper helper = new MimeMessageHelper(msg, true"GB2312");
54 
55   helper.setTo(to);
56   helper.setFrom(from);
57   helper.setSubject(subject);
58   helper.setText("<html><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"></head><body><h1><a href='#'>郁悶!"
59     + "</a></h1></body></html>"true);
60 
61   sender.send(msg);
62  }
63 
64  public static void main(String[] args) throws Exception {
65   ApplicationContext ctx = new FileSystemXmlApplicationContext(
66     new String[] { "D:\\WORK\\JDBC\\mail\\src\\MailSender.xml" });
67 
68   SimpleHtmlMailSender sender = (SimpleHtmlMailSender) ctx
69     .getBean("messageSender");
70   sender.sendMessage();
71  }
72 }
73 
74 
最后是spring配置文件
 1 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
 2 <beans>
 3  <bean id="sender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
 4   <property name="host">
 5    <value>mail.mymail.cn</value>
 6   </property>
 7   <property name="username">
 8    <value>webmaster</value>
 9   </property>
10   <property name="password">
11    <value>password</value>
12   </property>
13         <property name="javaMailProperties">
14         <props>
15         <prop key="mail.smtp.auth">true</prop>
16         </props>
17         </property>
18 
19     </bean>
20 
21  <bean id="messageSender" class="com.educast.mail.SimpleHtmlMailSender">
22   <property name="javaMailSender">
23    <ref bean="sender"/>
24   </property>
25   <property name="to">
26    <value>mfc42d@163.com</value>
27   </property>
28   <property name="from">
29    <value>webmaster@mymail.cn</value>
30   </property>
31   <property name="subject">
32    <value>test</value>
33   </property>
34  </bean>
35 </beans>
36 使用esmtp認證必須添加紅色部分
37 


老妖 2005-11-12 02:36 發表評論
]]>
using Spring Hotswapping for loading user classes from DBhttp://m.tkk7.com/rocky/archive/2005/11/09/19008.html老妖老妖Wed, 09 Nov 2005 08:50:00 GMThttp://m.tkk7.com/rocky/archive/2005/11/09/19008.htmlhttp://m.tkk7.com/rocky/comments/19008.htmlhttp://m.tkk7.com/rocky/archive/2005/11/09/19008.html#Feedback0http://m.tkk7.com/rocky/comments/commentRss/19008.htmlhttp://m.tkk7.com/rocky/services/trackbacks/19008.html
  • Code something like a PropertyPlaceHolderConfigurer but acting on a Database, resulting in a DBPropertyPlaceholderConfigurer. The problem with this approach is that you dont have any datasource definitions at this point and it will be tricky to get it work this way.
  • The other approach is using a HotSwappableTargetSource as target of your ProxyFactoryBean. Here you simply code a DummyImplementation of the desired interface and replace the dummy on startup with the real implementation from the database or from whereever you want via reflection.
  • I decide to use the HotSwappable direction to achieve the overall goal.
    example ApplicationContext definition
     1 <bean id="erpDataCollectorTarget" class="de.logentis.DummyERPDataCollector">
     2    <property name="clientManagerService" ref="clientManagerService"/>
     3    <property name="erpDataSource" ref="erpDataSource"/>
     4  </bean>
     5 <bean id="swapper" class="org.springframework.aop.target.HotSwappableTargetSource">
     6    <constructor-arg ref="erpDataCollectorTarget"/>
     7 </bean><bean id="erpDataCollector" class="org.springframework.aop.framework.ProxyFactoryBean">
     8     <property name="targetSource" ref="swapper"/>
     9     <property name="proxyInterfaces" value="de.logentis.ERPDataCollector"/>
    10     <property name="interceptorNames">
    11       <list>
    12          <value>jdoTransactionInterceptor</value>
    13       </list>
    14     </property>
    15 </bean>

    Look at the erpDataCollector bean, its a transactional proxy in my scenario. But as you can see, i dont use the "target" attribute with a concrete and not changeable bean definition but a "targetSource" pointing to a HotSwappableTargetSource. This hotswappable things get a default implementation which is nothing more than an empty implementation of the ERPDataCollector interface.

    Now when my application starts up, the internal spring plumbing comes first, after that i have a section where i setup my application with various defaults and other stuff. Somewhere in that section, i am doing this:

    1 // get the swapper bean from the Context, not shown here
    2 HotSwappableTargetSource swapper = getFromContext();
    3 // get the user defined class name from DB
    4 String classToLoad = getClassNameFromDB();
    5 Object o = getInstanceFromClassName(classToLoad);// swap the instances, removes the dummy and put the real impl
    6 // oldObject is the dummy and will be returned, normally you dont need
    7 // it anymore, but you can printout to be sure that it works like exptected
    8 Object oldObject = swapper.swap(o);

    At this point, the dummy is replaced with the class from the DB. Of course the DB holds only the full name of the class and it will get loaded via reflection. I left that out because this is plain java programming. Retrieving the swapper from the applicationContext is also trivial. One way would be to put this very code inside a bean which is controlled by Spring, this way you can just define a setter for the swapper and add the needed XML definition for that bean. If you run this from a ServletContextListener (best way to place bootstrap code), you can use something like this.
    do Hotswapping in ServletContextListener

     1 public class ApplicationInitFilter implements ServletContextListener {    public void contextInitialized(ServletContextEvent event) {
     2         WebApplicationContext webAppContext =
     3                WebApplicationContextUtils.getWebApplicationContext(
     4                                     event.getServletContext());        HotSwappableTargetSource swapper = 
     5                (HotSwappableTargetSource)webAppContext.getBean("swapper");        String classToLoad = getClassNameFromDB();
     6         Object o = getInstanceFromClassName(classToLoad);
     7         Object oldObject = swapper.swap(o);
     8     }    public void contextDestroyed(ServletContextEvent event) {
     9       // empty impl
    10     }}

    The interessting thing is, you can program an admin frontend for defining classes like this (its a german screenshot, but it should be readable for everyone): http://www.logemann.org/divs/dynclassdef.gif

    All in all, you can see that i used the HotSwappableTargetSource in a slightly different way than its used to be. I think the inventors created this class mainly to switch from one "real" implementation to another. In our context, we are switching from a dummy implementation to the real one but technically its the same of course. Thanks to Daniel Potter from the Spring community for mentioning the HotSwappable class, this really speeded up in finding my overall solution.



    老妖 2005-11-09 16:50 發表評論
    ]]>
    使用spring的mail發送帶有圖片的html的郵件--轉自邢紅瑞的bloghttp://m.tkk7.com/rocky/archive/2005/11/03/18004.html老妖老妖Thu, 03 Nov 2005 11:41:00 GMThttp://m.tkk7.com/rocky/archive/2005/11/03/18004.htmlhttp://m.tkk7.com/rocky/comments/18004.htmlhttp://m.tkk7.com/rocky/archive/2005/11/03/18004.html#Feedback0http://m.tkk7.com/rocky/comments/commentRss/18004.htmlhttp://m.tkk7.com/rocky/services/trackbacks/18004.html 1 package com.educast.mail;
     2 
     3 import org.springframework.mail.javamail.MimeMessageHelper;
     4 import org.springframework.context.ApplicationContext;
     5 import org.springframework.context.support.FileSystemXmlApplicationContext;
     6 import org.springframework.core.io.FileSystemResource;
     7 
     8 import javax.mail.internet.MimeMessage;
     9 import javax.mail.MessagingException;
    10 import java.io.File;
    11 
    12 public class ImageMailSender extends BaseMailSender {
    13         public void sendMessage() throws MessagingException {
    14         MimeMessage msg = sender.createMimeMessage();
    15         MimeMessageHelper helper = new MimeMessageHelper(msg, true"GB2312");
    16 
    17         helper.setTo(to);
    18         helper.setFrom(from);
    19         helper.setSubject(subject);
    20 
    21         helper.setText("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=gb2312\"></head><body><h1><a href='#'>郁悶!"
    22                 + "<img src=\"cid:img\"></body></html>"true);
    23 
    24         // add the image
    25         FileSystemResource image = new FileSystemResource(new File(
    26                 "c:\\0.gif"));
    27         helper.addInline("img", image);
    28 
    29         sender.send(msg);
    30     }
    31 
    32     public static void main(String[] args) throws Exception {
    33        ApplicationContext ctx = new FileSystemXmlApplicationContext(
    34     new String[] { "D:\\WORK\\JDBC\\mail\\src\\javaMailSender.xml" });
    35         ImageMailSender sender = (ImageMailSender) ctx.getBean("messageSender");
    36         sender.sendMessage();
    37     }
    38 }
    39 
    40 
     1 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
     2 <beans>
     3  <bean id="sender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
     4   <property name="host">
     5    <value>localhost</value>
     6   </property>
     7   <property name="username">
     8    <value>webmaster</value>
     9   </property>
    10   <property name="password">
    11    <value>password</value>
    12   </property>
    13         <property name="javaMailProperties">
    14         <props>
    15         <prop key="mail.smtp.auth">true</prop>
    16         </props>
    17         </property>
    18 
    19     </bean>
    20 
    21  <bean id="messageSender" class="com.educast.mail.ImageMailSender">
    22   <property name="javaMailSender">
    23    <ref bean="sender"/>
    24   </property>
    25   <property name="to">
    26    <value>mfc42d@163.com</value>
    27   </property>
    28   <property name="from">
    29    <value>webmaster@mymail.cn</value>
    30   </property>
    31   <property name="subject">
    32    <value>HTML Mail</value>
    33   </property>
    34  </bean>
    35 </beans>
    36 
    37 


    老妖 2005-11-03 19:41 發表評論
    ]]>
    使用spring的mail發送帶有附件的html的郵件--摘自邢紅瑞的bloghttp://m.tkk7.com/rocky/archive/2005/11/03/18002.html老妖老妖Thu, 03 Nov 2005 11:39:00 GMThttp://m.tkk7.com/rocky/archive/2005/11/03/18002.htmlhttp://m.tkk7.com/rocky/comments/18002.htmlhttp://m.tkk7.com/rocky/archive/2005/11/03/18002.html#Feedback0http://m.tkk7.com/rocky/comments/commentRss/18002.htmlhttp://m.tkk7.com/rocky/services/trackbacks/18002.html

    有的朋友問我如何發送帶有附件的html的郵件,不要加入contentID,使用addAttachment即可
    實現代碼


     1 package com.educast.mail;
     2 
     3 import org.springframework.mail.javamail.MimeMessageHelper;
     4 import org.springframework.core.io.FileSystemResource;
     5 import org.springframework.context.ApplicationContext;
     6 import org.springframework.context.support.FileSystemXmlApplicationContext;
     7 
     8 import javax.mail.MessagingException;
     9 import javax.mail.internet.MimeMessage;
    10 import java.io.File;
    11 
    12 
    13 public class AttachmentMailSender extends BaseMailSender  {
    14    public void sendMessage() throws MessagingException {
    15         MimeMessage msg = sender.createMimeMessage();
    16         MimeMessageHelper helper = new MimeMessageHelper(msg, true"GB2312");
    17 
    18         helper.setTo(to);
    19         helper.setFrom(from);
    20         helper.setSubject(subject);
    21 
    22         helper.setText("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=gb2312\"></head><body><h1><a href='#'>郁悶!"
    23                 + "</body></html>"true);
    24 
    25 
    26 // add the rar file
    27        FileSystemResource rarfile = new FileSystemResource(new File(
    28                "c:\\a.rar"));
    29        helper.addAttachment("a.rar", rarfile);
    30 
    31 
    32         sender.send(msg);
    33     }
    34 
    35     public static void main(String[] args) throws Exception {
    36           ApplicationContext ctx = new FileSystemXmlApplicationContext(
    37                 new String[] { "D:\\WORK\\JDBC\\mail\\src\\javaMailSender.xml" });
    38         AttachmentMailSender sender = (AttachmentMailSender) ctx.getBean("messageSender");
    39         sender.sendMessage();
    40     }
    41 }
    42 
    43 
    配置文件
     1 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
     2 <beans>
     3  <bean id="sender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
     4   <property name="host">
     5    <value>localhost</value>
     6   </property>
     7   <property name="username">
     8    <value>webmaster</value>
     9   </property>
    10   <property name="password">
    11    <value>password</value>
    12   </property>
    13         <property name="javaMailProperties">
    14         <props>
    15         <prop key="mail.smtp.auth">true</prop>
    16         </props>
    17         </property>
    18 
    19     </bean>
    20 
    21  <bean id="messageSender" class="com.educast.mail.AttachmentMailSender">
    22   <property name="javaMailSender">
    23    <ref bean="sender"/>
    24   </property>
    25   <property name="to">
    26    <value>mfc42d@sohu.com</value>
    27   </property>
    28   <property name="from">
    29    <value>webmaster@mymail.cn</value>
    30   </property>
    31   <property name="subject">
    32    <value>HTML Mail</value>
    33   </property>
    34  </bean>
    35 </beans>
    36 
    37 


    老妖 2005-11-03 19:39 發表評論
    ]]>
    使用Spring郵件發送Emailhttp://m.tkk7.com/rocky/archive/2005/10/29/17375.html老妖老妖Sat, 29 Oct 2005 12:58:00 GMThttp://m.tkk7.com/rocky/archive/2005/10/29/17375.htmlhttp://m.tkk7.com/rocky/comments/17375.htmlhttp://m.tkk7.com/rocky/archive/2005/10/29/17375.html#Feedback0http://m.tkk7.com/rocky/comments/commentRss/17375.htmlhttp://m.tkk7.com/rocky/services/trackbacks/17375.htmlSpring提供了一個發送電子郵件的高級抽象層,它向用戶屏蔽了底層郵件系統的一些細節,同時負責低層次的代表客戶端的資源處理。Spring郵件抽象層的主要包為org.springframework.mail。它包括了發送電子郵件的主要接口MailSender和 封裝了簡單郵件的屬性如from, to,cc, subject, text的值對象叫做SimpleMailMessage。
    首先:我們定義一個發送郵件的接口:IMailManager.java
    /*
    * IMailManager.java
    * Copyright 2005, All rights reserved.
    */
    package test.mail.manager;

    import test.common.logic.IManager;
    import test.model.Order;

    /**
    * Note:this interface mainly deal with the sendOrder
    */
    public interface IMailManager extends IManager{

    void sendOrder(Order order);
    }

    然后實現這個接口:MailManager.java
    /*
    * MailManager.java
    * Copyright 2005, All rights reserved.
    */
    package test.mail.manager;

    import org.springframework.mail.MailException;
    import org.springframework.mail.MailSender;
    import org.springframework.mail.SimpleMailMessage;

    import test.common.logic.impl.Manager;
    import test.model.Order;

    /**
    * Note:the implements of IMailManager
    */
    public class MailManager extends Manager implements IMailManager {

    private MailSender mailSender;
    private SimpleMailMessage message;

    public void sendOrder(Order order) {
    SimpleMailMessage mailMessage = new SimpleMailMessage(this.message);
    mailMessage.setTo(order.getUser().getEmail());
    mailMessage.setText("Dear"
    + order.getUser().getFirstName()
    + order.getUser().getLastName()
    + ", thank you for placing order. Your order code is "
    + order.getCode());
    try{
    mailSender.send(mailMessage);
    }catch(MailException ex) {
    System.err.println(ex.getMessage());
    }

    }

    /**
    * @param mailSender The mailSender to set.
    */
    public void setMailSender(MailSender mailSender) {
    this.mailSender = mailSender;
    }
    /**
    * @param message The message to set.
    */
    public void setMessage(SimpleMailMessage message) {
    this.message = message;
    }
    }

    然后我們在Action 里面調用: SendMailAction.java
    /*
    * SendMail.java
    * Copyright 2005, All rights reserved.
    */
    package test.mail.action;

    import test.common.action.BaseAction;
    import test.mail.manager.IMailManager;
    import test.order.dao.IOrderDao;
    import test.model.Order;


    /**
    * Note: SendMailAction
    */
    public class SendMailAction extends BaseAction {
    private IMailManager mailManager;
    private IOrderDao orderDao;
    private long orderId;

    public String execute() throws Exception {
    Order order = orderDao.getOrder(orderId);
    mailManager.sendOrder(order);
    return SUCCESS;
    }


    /**
    * @return Returns the mailManager.
    */
    public IMailManager getMailManager() {
    return mailManager;
    }
    /**
    * @param mailManager The mailManager to set.
    */
    public void setMailManager(IMailManager mailManager) {
    this.mailManager = mailManager;
    }

    /**
    * @return Returns the orderDao.
    */
    public IOrderDao getOrderDao() {
    return orderDao;
    }
    /**
    * @param orderDao The orderDao to set.
    */
    public void setOrderDao(IOrderDao orderDao) {
    this.orderDao = orderDao;
    }
    /**
    * @return Returns the orderId.
    */
    public long getOrderId() {
    return orderId;
    }
    /**
    * @param orderId The orderId to set.
    */
    public void setOrderId(long orderId) {
    this.orderId = orderId;
    }
    }

    最后的就是配置了.在ApplicationContext.xml文件里加上如下的內容:
    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host"><value>smtp服務器</value></property>
    <property name="username"><value>用戶名</value></property>
    <property name="password"><value>密碼</value></property>
    /**如果服務器要求驗證,加上此**/
    <property name="javaMailProperties">
    <props>
    <prop key="mail.smtp.auth">true</prop>
    <prop key="mail.smtp.timeout">25000</prop>
    </props>
    </property>
    </bean>

    <bean id="mailMessage"
    class="org.springframework.mail.SimpleMailMessage">
    <property name="from">
    <value>你的電子郵件地址</value>
    </property>
    <property name="subject">
    <value>郵件標題</value>
    </property>
    </bean>


    <bean id="mailManager" class=" test.mail.manager.MailManager" >
    <property name="mailSender">
    <ref bean="mailSender" />
    </property>
    <property name="message">
    <ref bean="mailMessage" />
    </property>
    </bean>
    在對應的action配置文件中加入:
    <bean id="SendMailAction"
    class=" test.mail.action.SendMailAction" singleton="false" >
    <property name="mailManager">
    <ref bean="mailManager" />
    </property>
    <property name="orderDao">
    <ref bean="orderDao"/>
    </property>
    </bean>

    在xwork配置文件中:
    <action name="sendMailBG" class="SendMailAction">
    <interceptor-ref name="defaultStack" />
    <result name="success" type="freemarker">success.ftl</result>
    <result name="error" type="freemarker">error.ftl</result>
    </action>


    老妖 2005-10-29 20:58 發表評論
    ]]>
    Acegi簡介http://m.tkk7.com/rocky/archive/2005/10/29/17373.html老妖老妖Sat, 29 Oct 2005 12:46:00 GMThttp://m.tkk7.com/rocky/archive/2005/10/29/17373.htmlhttp://m.tkk7.com/rocky/comments/17373.htmlhttp://m.tkk7.com/rocky/archive/2005/10/29/17373.html#Feedback0http://m.tkk7.com/rocky/comments/commentRss/17373.htmlhttp://m.tkk7.com/rocky/services/trackbacks/17373.htmlAcegi安全系統,是一個用于Spring Framework的安全框架,能夠和目前流行的Web容器無縫集成。它使用了Spring的方式提供了安全和認證安全服務,包括使用Bean Context,攔截器和面向接口的編程方式。因此,Acegi安全系統能夠輕松地適用于復雜的安全需求。
    安全涉及到兩個不同的概念,認證和授權。前者是關于確認用戶是否確實是他們所宣稱的身份。授權則是關于確認用戶是否有允許執行一個特定的操作。
    在Acegi安全系統中,需要被認證的用戶,系統或代理稱為"Principal"。Acegi安全系統和其他的安全系統不同,它并沒有角色和用戶組的概念。
    Acegi系統設計
    關鍵組件
    Acegi安全系統包含以下七個關鍵的功能組件:
    l Authentication對象,包含了Principal,Credential和Principal的授權信息。同時還可以包含關于發起認證請求的客戶的其他信息,如IP地址。
    2 ContextHolder對象,使用ThreadLocal儲存Authentication對象的地方。
    3 AuthenticationManager,用于認證ContextHolder中的Authentication對象。
    4 AccessDecissionManager,用于授權一個特定的操作。
    5 RunAsManager,當執行特定的操作時,用于選擇性地替換Authentication對象。
    6 Secure Object攔截器,用于協調AuthenticationManager,AccessDecissionManager,RunAsManager和特定操作的執行。
    7 ObjectDefinitionSource,包含了特定操作的授權定義。
    這七個關鍵的功能組件的關系如下圖所示(圖中灰色部分是關鍵組件):


    安全管理對象
    Acegi安全系統目前支持兩類安全管理對象。
    第一類的安全管理對象管理AOP Alliance的MethodInvocation,開發人員可以用它來保護Spring容器中的業務對象。為了使Spring管理的Bean可以作為 MethodInvocation來使用,Bean可以通過ProxyFactoryBean和BeanNameAutoProxyCreator來管理,就像在Spring的事務管理一樣使用。
    第二類是FilterInvocation。它用過濾器(Filter)來創建,并簡單地包裝了HTTP的ServletRequest, ServletResponse和FilterChain。FilterInvocation可以用來保護HTTP資源。通常,開發人員并不需要了解它的工作機制,因為他們只需要將Filter加入web.xml,Acegi安全系統就可以工作了。
    安全配置參數
    每個安全管理對象都可以描述數量不限的各種安全認證請求。例如,MethodInvocation對象可以描述帶有任意參數的任意方法的調用,而FilterInvocation可以描述任意的HTTP URL。
    Acegi安全系統需要記錄應用于每個認證請求的安全配置參數。例如,對于BankManager.getBalance(int accountNumber)方法和BankManager.approveLoan(int applicationNumber)方法,它們需要的認證請求的安全配置很不相同。
    為了保存不同的認證請求的安全配置,需要使用配置參數。從實現的視角來看,配置參數使用ConfigAttribute接口來表示。Acegi安全系統提供了ConfigAttribute接口的一個實現,SecurityConfig,它把配置參數保存為一個字符串。
    ConfigAttributeDefinition類是ConfigAttribute對象的一個簡單的容器,它保存了和特定請求相關的ConfigAttribute的集合。
    當安全攔截器收到一個安全認證請求時,需要決定應用哪一個配置參數。換句話說,它需要找出應用于這個請求的 ConfigAttributeDefinition對象。這個查找的過程是由ObjectDefinitionSource接口來處理的。這個接口的主要方法是public ConfigAttributeDefinition getAttributes(Object object),其中Object參數是一個安全管理對象。因為安全管理對象包含有認證請求的詳細信息,所以 ObjectDefinitionSource接口的實現類可以從中獲得所需的詳細信息,以查找相關的ConfigAttributeDefiniton 對象。
    Acegi如何工作
    為了說明Acegi安全系統如何工作,我們設想一個使用Acegi的例子。通常,一個安全系統需要發揮作用,它必須完成以下的工作:
    l 首先,系統從客戶端請求中獲得Principal和Credential;
    2 然后系統認證Principal和Credential信息;
    3 如果認證通過,系統取出Principal的授權信息;
    4 接下來,客戶端發起操作請求;
    5 系統根據預先配置的參數檢查Principal對于該操作的授權;
    6 如果授權檢查通過則執行操作,否則拒絕。
    那么,Acegi安全系統是如何完成這些工作的呢?首先,我們來看看Acegi安全系統的認證和授權的相關類圖:

    圖中綠色部分是安全攔截器的抽象基類,它包含有兩個管理類,AuthenticationManager和AccessDecisionManager,如圖中灰色部分。AuthenticationManager用于認證ContextHolder中的Authentication對象(包含了 Principal,Credential和Principal的授權信息);AccessDecissionManager則用于授權一個特定的操作。
    下面來看一個MethodSecurityInterceptor的例子:
    <bean id="bankManagerSecurity"
    class="net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor">
    <property name="validateConfigAttributes">
    <value>true</value>
    </property>
    <property name="authenticationManager">
    <ref bean="authenticationManager"/>
    </property>
    <property name="accessDecisionManager">
    <ref bean="accessDecisionManager"/>
    </property>
    <property name="objectDefinitionSource">
    <value>
    net.sf.acegisecurity.context.BankManager.delete*=
    ROLE_SUPERVISOR,RUN_AS_SERVER
    net.sf.acegisecurity.context.BankManager.getBalance=
    ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER,RUN_
    </value>
    </property>
    </bean>
    上面的配置文件中,MethodSecurityInterceptor是AbstractSecurityInterceptor的一個實現類。它包含了兩個管理器,authenticationManager和accessDecisionManager。這兩者的配置如下:
    <bean id="authenticationDao" class="net.sf.acegisecurity.providers.dao.jdbc.JdbcDaoImpl">
    <property name="dataSource"><ref bean="dataSource"/></property>
    </bean>
    <bean id="daoAuthenticationProvider"
    class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider">
    <property name="authenticationDao"><ref bean="authenticationDao"/></property>
    </bean>
    <bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
    <property name="providers">
    <list><ref bean="daoAuthenticationProvider"/></list>
    </property>
    </bean>
    <bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>
    <bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
    <property name="allowIfAllAbstainDecisions"><value>false</value></property>
    <property name="decisionVoters">
    <list><ref bean="roleVoter"/></list>
    </property>
    </bean>
    準備工作做好了,現在我們來看看Acegi安全系統是如何實現認證和授權機制的。以使用HTTP BASIC認證的應用為例子,它包括下面的步驟:
    1. 用戶登錄系統,Acegi從acegisecurity.ui子系統的安全攔截器(如BasicProcessingFilter)中得到用戶的登錄信息(包括Principal和Credential)并放入Authentication對象,并保存在ContextHolder對象中;
    2. 安全攔截器將Authentication對象交給AuthenticationManager進行身份認證,如果認證通過,返回帶有Principal 授權信息的Authentication對象。此時ContextHolder對象的Authentication對象已擁有Principal的詳細信息;
    3. 用戶登錄成功后,繼續進行業務操作;
    4. 安全攔截器(bankManagerSecurity)收到客戶端操作請求后,將操作請求的數據包裝成安全管理對象(FilterInvocation或MethodInvocation對象);
    5. 然后,從配置文件(ObjectDefinitionSource)中讀出相關的安全配置參數ConfigAttributeDefinition;
    6. 接著,安全攔截器取出ContextHolder中的Authentication對象,把它傳遞給AuthenticationManager進行身份認證,并用返回值更新ContextHolder的Authentication對象;
    7. 將Authentication對象,ConfigAttributeDefinition對象和安全管理對象(secure Object)交給AccessDecisionManager,檢查Principal的操作授權;
    8. 如果授權檢查通過則執行客戶端請求的操作,否則拒絕;
    AccessDecisionVoter
    注意上節的accessDecisionManager是一個AffirmativeBased類,它對于用戶授權的投票策略是,只要通過其中的一個授權投票檢查,即可通過;它的allowIfAllAbstainDecisions屬性值是false,意思是如果所有的授權投票是都是棄權,則通不過授權檢查。
    Acegi安全系統包括了幾個基于投票策略的AccessDecisionManager,上節的RoleVoter就是其中的一個投票策略實現,它是 AccessDecisionVoter的一個子類。AccessDecisionVoter的具體實現類通過投票來進行授權決策, AccessDecisionManager則根據投票結果來決定是通過授權檢查,還是拋出AccessDeniedException例外。
    AccessDecisionVoter接口共有三個方法:
    public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config);
    public boolean supports(ConfigAttribute attribute);
    public boolean supports(Class clazz);
    其中的vote方法返回int返回值,它們是AccessDecisionVoter的三個靜態成員屬性:ACCESS_ABSTAIN,,ACCESS_DENIED和ACCESS_GRANTED,它們分別是棄權,否決和贊成。
    Acegi安全系統中,使用投票策略的AccessDecisionManager共有三個具體實現類:AffirmativeBased、 ConsensusBased和UnanimousBased。它們的投票策略是,AffirmativeBased類只需有一個投票贊成即可通過; ConsensusBased類需要大多數投票贊成即可通過;而UnanimousBased類需要所有的投票贊成才能通過。
    RoleVoter類是一個Acegi安全系統AccessDecisionVoter接口的實現。如果ConfigAttribute以ROLE_開頭,RoleVoter則進行投票。如果GrantedAuthority的getAutority方法的String返回值匹配一個或多個以ROLE_ 開頭的ConfigAttribute,則投票通過,否則不通過。如果沒有以ROLE_開頭的ConfigAttribute,RoleVoter則棄權。
    安全攔截器
    攔截器如何工作
    MethodInvocation攔截器
    FilterInvocation攔截器
    認證
    認證請求
    認證管理器
    Authentication Provider
    授權
    Access Decision Manager
    Voting Decision Manager
    授權管理推薦
    ContextHolder的用戶接口
    用戶接口目標
    HTTP會話認證
    HTTP Basic認證
    1、Log4j的概念
    Log4j中有三個主要的組件,它們分別是Logger、Appender和Layout,Log4j 允許開發人員定義多個Logger,每個Logger擁有自己的名字,Logger之間通過名字來表明隸屬關系。有一個Logger稱為Root,它永遠存在,且不能通過名字檢索或引用,可以通過Logger.getRootLogger()方法獲得,其它Logger通過 Logger.getLogger(String name)方法。
    Appender則是用來指明將所有的log信息存放到什么地方,Log4j中支持多種appender,如 console、files、GUI components、NT Event Loggers等,一個Logger可以擁有多個Appender,也就是你既可以將Log信息輸出到屏幕,同時存儲到一個文件中。
    Layout的作用是控制Log信息的輸出方式,也就是格式化輸出的信息。
    Log4j中將要輸出的Log信息定義了5種級別,依次為DEBUG、INFO、WARN、ERROR和FATAL,當輸出時,只有級別高過配置中規定的級別的信息才能真正的輸出,這樣就很方便的來配置不同情況下要輸出的內容,而不需要更改代碼,這點實在是方便啊。

    2、Log4j的配置文件
    雖然可以不用配置文件,而在程序中實現配置,但這種方法在如今的系統開發中顯然是不可取的,能采用配置文件的地方一定一定要用配置文件。Log4j支持兩種格式的配置文件:XML格式和Java的property格式,本人更喜歡后者,首先看一個簡單的例子吧,如下:

    log4j.rootLogger=debug, stdout, R
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

    # Pattern to output the caller's file name and line number.
    log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

    log4j.appender.R=org.apache.log4j.RollingFileAppender
    log4j.appender.R.File=example.log
    log4j.appender.R.MaxFileSize=100KB

    # Keep one backup file
    log4j.appender.R.MaxBackupIndex=1

    log4j.appender.R.layout=org.apache.log4j.PatternLayout
    log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n

    首先,是設置root,格式為 log4j.rootLogger=[level],appenderName, ...,其中level就是設置需要輸出信息的級別,后面是appender的輸出的目的地,appenderName就是指定日志信息輸出到哪個地方。您可以同時指定多個輸出目的地。配置日志信息輸出目的地Appender,其語法為
    log4j.appender.appenderName = fully.qualified.name.of.appender.class
    log4j.appender.appenderName.option1 = value1
    ...
    log4j.appender.appenderName.option = valueN
    Log4j提供的appender有以下幾種:
    org.apache.log4j.ConsoleAppender(控制臺)
    org.apache.log4j.FileAppender(文件)
    org.apache.log4j.DailyRollingFileAppender(每天產生一個日志文件)
    org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的時候產生新文件)
    org.apache.log4j.WriterAppender(將日志信息以流格式發送到任意指定的地方)
    配置日志信息的格式(布局),其語法為:
    log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
    log4j.appender.appenderName.layout.option1 = value1
    ....
    log4j.appender.appenderName.layout.option = valueN
    Log4j提供的layout有以下幾種:
    org.apache.log4j.HTMLLayout(以HTML表格形式布局),
    org.apache.log4j.PatternLayout(可以靈活地指定布局模式),
    org.apache.log4j.SimpleLayout(包含日志信息的級別和信息字符串),
    org.apache.log4j.TTCCLayout(包含日志產生的時間、線程、類別等等信息)

    3、Log4j在程序中的使用
    要在自己的類中使用Log4j,首先聲明一個靜態變量Logger logger=Logger.getLog("classname");在使用之前,用PropertyConfigurator.configure ("配置文件")配置一下,現在就可以使用了,用法如下:logger.debug("debug message")或者logger.info("info message"),看下面一個小例子:

    import com.foo.Bar;
    import org.apache.log4j.Logger;
    import org.apache.log4j.PropertyConfigurator;
    public class MyApp {
    static Logger logger = Logger.getLogger(MyApp.class.getName());
    public static void main(String[] args) {
    // BasicConfigurator replaced with PropertyConfigurator.
    PropertyConfigurator.configure(args[0]);
    logger.info("Entering application.");
    Bar bar = new Bar();
    bar.doIt();
    logger.info("Exiting application.");
    }
    }
    [簡介]
    對于一個典型的Web應用,完善的認證和授權機制是必不可少的,在SpringFramework中,Juergen Hoeller提供的范例JPetStore給了一些這方面的介紹,但還遠遠不夠,Acegi是一個專門為SpringFramework提供安全機制的項目,全稱為Acegi Security System for Spring,當前版本為0.5.1,就其目前提供的功能,應該可以滿足絕大多數應用的需求。

    本文的主要目的是希望能夠說明如何在基于Spring構架的Web應用中使用Acegi,而不是詳細介紹其中的每個接口、每個類。注意,即使對已經存在的Spring應用,通過下面介紹的步驟,也可以馬上享受到Acegi提供的認證和授權。

    [基礎工作]
    在你的Web應用的lib中添加Acegi下載包中的acegi-security.jar

    [web.xml]
    實現認證和授權的最常用的方法是通過filter,Acegi亦是如此,通常Acegi需要在web.xml添加以下5個filter:

    <filter>
    <filter-name>Acegi Channel Processing Filter</filter-name>
    <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
    <init-param>
    <param-name>targetClass</param-name>
    <param-value>net.sf.acegisecurity.securechannel.ChannelProcessingFilter</param-value>
    </init-param>
    </filter>
    <filter>
    <filter-name>Acegi Authentication Processing Filter</filter-name>
    <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
    <init-param>
    <param-name>targetClass</param-name>
    <param-value>net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter</param-value>
    </init-param>
    </filter>
    <filter>
    <filter-name>Acegi HTTP BASIC Authorization Filter</filter-name>
    <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
    <init-param>
    <param-name>targetClass</param-name>
    <param-value>net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter</param-value>
    </init-param>
    </filter>
    <filter>
    <filter-name>Acegi Security System for Spring Auto Integration Filter</filter-name>
    <filter-class>net.sf.acegisecurity.ui.AutoIntegrationFilter</filter-class>
    </filter>
    <filter>
    <filter-name>Acegi HTTP Request Security Filter</filter-name>
    <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
    <init-param>
    <param-name>targetClass</param-name>
    <param-value>net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter</param-value>
    </init-param>
    </filter>

    最先引起迷惑的是net.sf.acegisecurity.util.FilterToBeanProxy,Acegi自己的文檔上解釋是: “What FilterToBeanProxy does is delegate the Filter's methods through to a bean which is obtained from the
    Spring application context. This enables the bean to benefit from the Spring application context lifecycle support and configuration flexibility.”,如希望深究的話,去看看源代碼應該不難理解。

    再下來就是添加filter-mapping了:
    <filter-mapping>
    <filter-name>Acegi Channel Processing Filter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
    <filter-name>Acegi Authentication Processing Filter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
    <filter-name>Acegi HTTP BASIC Authorization Filter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
    <filter-name>Acegi Security System for Spring Auto Integration Filter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
    <filter-name>Acegi HTTP Request Security Filter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>

    這里,需要注意以下兩點:
    1) 這幾個filter的順序是不能更改的,順序不對將無法正常工作;
    2) 如果你的應用不需要安全傳輸,如https,則將"Acegi Channel Processing Filter"相關內容注釋掉即可;
    3) 如果你的應用不需要Spring提供的遠程訪問機制,如Hessian and Burlap,將"Acegi HTTP BASIC Authorization
    Filter"相關內容注釋掉即可。

    [applicationContext.xml]
    接下來就是要添加applicationContext.xml中的內容了,從剛才FilterToBeanFactory的解釋可以看出,真正的filter都
    在Spring的applicationContext中管理:

    1) 首先,你的數據庫中必須具有保存用戶名和密碼的table,Acegi要求table的schema必須如下:

    CREATE TABLE users (
    username VARCHAR(50) NOT NULL PRIMARY KEY,
    password VARCHAR(50) NOT NULL,
    enabled BIT NOT NULL
    );
    CREATE TABLE authorities (
    username VARCHAR(50) NOT NULL,
    authority VARCHAR(50) NOT NULL
    );
    CREATE UNIQUE INDEX ix_auth_username ON authorities ( username, authority );
    ALTER TABLE authorities ADD CONSTRAINT fk_authorities_users foreign key (username) REFERENCES users
    (username);

    2) 添加訪問你的數據庫的datasource和Acegi的jdbcDao,如下:

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
    <property name="url"><value>${jdbc.url}</value></property>
    <property name="username"><value>${jdbc.username}</value></property>
    <property name="password"><value>${jdbc.password}</value></property>
    </bean>
    <bean id="jdbcDaoImpl" class="net.sf.acegisecurity.providers.dao.jdbc.JdbcDaoImpl">
    <property name="dataSource"><ref bean="dataSource"/></property>
    </bean>

    3) 添加DaoAuthenticationProvider:

    <bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider">
    <property name="authenticationDao"><ref bean="authenticationDao"/></property>
    <property name="userCache"><ref bean="userCache"/></property>
    </bean>

    <bean id="userCache" class="net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
    <property name="minutesToIdle"><value>5</value></property>
    </bean>

    如果你需要對密碼加密,則在daoAuthenticationProvider中加入:<property name="passwordEncoder"><ref
    bean="passwordEncoder"/></property>,Acegi提供了幾種加密方法,詳細情況可看包
    net.sf.acegisecurity.providers.encoding

    4) 添加authenticationManager:

    <bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
    <property name="providers">
    <list>
    <ref bean="daoAuthenticationProvider"/>
    </list>
    </property>
    </bean>

    5) 添加accessDecisionManager:

    <bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
    <property name="allowIfAllAbstainDecisions">
    <value>false</value>
    </property>
    <property name="decisionVoters">
    <list><ref bean="roleVoter"/></list>
    </property>
    </bean>
    <bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>

    6) 添加authenticationProcessingFilterEntryPoint:

    <bean id="authenticationProcessingFilterEntryPoint"
    class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
    <property name="loginFormUrl"><value>/acegilogin.jsp</value></property>
    <property name="forceHttps"><value>false</value></property>
    </bean>

    其中acegilogin.jsp是登陸頁面,一個最簡單的登錄頁面如下:

    <%@ taglib prefix='c' uri='http://java.sun.com/jstl/core' %>
    <%@ page import="net.sf.acegisecurity.ui.AbstractProcessingFilter" %>
    <%@ page import="net.sf.acegisecurity.AuthenticationException" %>
    <html>
    <head>
    <title>Login</title>
    </head>

    <body>
    <h1>Login</h1>
    <form action="<c:url value='j_acegi_security_check'/>" method="POST">
    <table>
    <tr><td>User:</td><td><input type='text' name='j_username'></td></tr>
    <tr><td>Password:</td><td><input type='password' name='j_password'></td></tr>
    <tr><td colspan='2'><input name="submit" type="submit"></td></tr>
    <tr><td colspan='2'><input name="reset" type="reset"></td></tr>
    </table>
    </form>
    </body>
    </html>

    7) 添加filterInvocationInterceptor:

    <bean id="filterInvocationInterceptor"
    class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor">
    <property name="authenticationManager">
    <ref bean="authenticationManager"/>
    </property>
    <property name="accessDecisionManager">
    <ref bean="accessDecisionManager"/>
    </property>
    <property name="objectDefinitionSource">
    <value>
    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
    \A/sec/administrator.*\Z=ROLE_SUPERVISOR
    \A/sec/user.*\Z=ROLE_TELLER
    </value>
    </property>
    </bean>

    這里請注意,要objectDefinitionSource中定義哪些頁面需要權限訪問,需要根據自己的應用需求進行修改,我上面給出
    的定義的意思是這樣的:
    a. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON意思是在比較請求路徑時全部轉換為小寫
    b. \A/sec/administrator.*\Z=ROLE_SUPERVISOR意思是只有權限為ROLE_SUPERVISOR才能訪問/sec/administrator*的頁面
    c. \A/sec/user.*\Z=ROLE_TELLER意思是只有權限為ROLE_TELLER的用戶才能訪問/sec/user*的頁面

    Cool 添加securityEnforcementFilter:

    <bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">
    <property name="filterSecurityInterceptor">
    <ref bean="filterInvocationInterceptor"/>
    </property>
    <property name="authenticationEntryPoint">
    <ref bean="authenticationProcessingFilterEntryPoint"/>
    </property>
    </bean>

    9) 添加authenticationProcessingFilter:

    <bean id="authenticationProcessingFilter"
    class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
    <property name="authenticationManager">
    <ref bean="authenticationManager"/>
    </property>
    <property name="authenticationFailureUrl">
    <value>/loginerror.jsp</value>
    </property>
    <property name="defaultTargetUrl">
    <value>/</value>
    </property>
    <property name="filterProcessesUrl">
    <value>/j_acegi_security_check</value>
    </property>
    </bean>
    其中authenticationFailureUrl是認證失敗的頁面。

    10) 如果需要一些頁面通過安全通道的話,添加下面的配置:

    <bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter">
    <property name="channelDecisionManager">
    <ref bean="channelDecisionManager"/>
    </property>
    <property name="filterInvocationDefinitionSource">
    <value>
    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
    \A/sec/administrator.*\Z=REQUIRES_SECURE_CHANNEL
    \A/acegilogin.jsp.*\Z=REQUIRES_SECURE_CHANNEL
    \A/j_acegi_security_check.*\Z=REQUIRES_SECURE_CHANNEL
    \A.*\Z=REQUIRES_INSECURE_CHANNEL
    </value>
    </property>
    </bean>

    <bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl">
    <property name="channelProcessors">
    <list>
    <ref bean="secureChannelProcessor"/>
    <ref bean="insecureChannelProcessor"/>
    </list>
    </property>
    </bean>
    <bean id="secureChannelProcessor" class="net.sf.acegisecurity.securechannel.SecureChannelProcessor"/>
    <bean id="insecureChannelProcessor" class="net.sf.acegisecurity.securechannel.InsecureChannelProcessor"/>

    [缺少了什么?]
    Acegi目前提供了兩種"secure object",分別對頁面和方法進行安全認證管理,我這里介紹的只是利用
    FilterSecurityInterceptor對訪問頁面的權限控制,除此之外,Acegi還提供了另外一個Interceptor——
    MethodSecurityInterceptor,它結合runAsManager可實現對對象中的方法的權限控制,使用方法可參看Acegi自帶的文檔
    和contact范例。

    [最后要說的]
    本來以為只是說明如何使用Acegi而已,應該非常簡單,但真正寫起來才發現想要條理清楚的理順所有需要的bean還是很
    困難的,但愿我沒有遺漏太多東西,如果我的文章有什么遺漏或錯誤的話,還請參看Acegi自帶的quick-start范例,但請
    注意,這個范例是不能直接拿來用的。
    分析和學習Spring中的jpetstore用戶管理
    存在用戶的系統,必然需要用戶的登錄和認證,今天就通過分析Spring中自帶的jpetstore的例子來學習一下如何實現在Spring構架的系統中用戶登錄。
    1、首先從注冊用戶開始,先看看jpetstore-servlet.xml中關于注冊用戶的bean定義,從定義命名中就可以看出下面這段就是注冊用戶的:
    <bean name="/shop/newAccount.do" class="org.springframework.samples.jpetstore.web.spring.AccountFormController">
    <property name="petStore"><ref bean="petStore"/></property>
    <property name="validator"><ref bean="accountValidator"/></property>
    <property name="successView"><value>index</value></property>
    </bean>
    1). formView呢?從AccountFormController的構造函數中得到,原來為EditAccountForm;
    2). EditoAccountForm.jsp中顯得非常亂,其實沒有多少難理解的地方,最主要的是這個form既是添加新用戶的,又是編輯用戶信息的,所以顯得有點亂糟糟的。
    2、添加好了新用戶,接下來看看如何登錄,在jpetstore-servlet中發現這兩個相關bean定義,如下:
    <bean name="/shop/signon.do" class="org.springframework.samples.jpetstore.web.spring.SignonController">
    <property name="petStore"><ref bean="petStore"/></property>
    </bean>
    <bean name="/shop/signonForm.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
    <property name="viewName"><value>SignonForm</value></property>
    </bean>
    1). 第二個bean是在運行時用戶輸入用戶名和密碼的form,叫做SignonForm,對于這個 ParameterizableViewController,用文檔里的話說這是最簡單的Controller,其作用就是在運行中指向 Controller而不是直接指向jsp文件,僅此而已。
    2). SignonForm.jsp,里面就是一個簡單的form,其action就是第一個bean,即/shop/signon.do,最需要注意的是 signonForwardAction,其主要作用是forward到需要輸入用戶名和密碼的那個頁面上去,這個變量哪里來的呢?看看下面:
    <bean id="secureHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="interceptors">
    <list>
    <ref bean="signonInterceptor"/>
    </list>
    </property>
    <property name="urlMap">
    <map>
    <entry key="/shop/editAccount.do"><ref local="secure_editAccount"/></entry>
    <entry key="/shop/listOrders.do"><ref local="secure_listOrders"/></entry>
    <entry key="/shop/newOrder.do"><ref local="secure_newOrder"/></entry>
    <entry key="/shop/viewOrder.do"><ref local="secure_viewOrder"/></entry>
    </map>
    </property>
    </bean>
    原來,上面的signonInterceptor實現了preHandle,因此在請求上面的map頁面時,首先要經過這個Interceptor,看看 SignonInterceptor的源碼,原來在其中為signon.jsp賦予一個signonForwardAction對象,呵呵,總算明白了。
    3). 接下來去學習一下SignonController,其主體部分中可以看出,首先取出用戶輸入的username和password,然后到數據庫中驗證有沒有這個用戶,如果沒有這個用戶,返回各錯誤頁面;如果成功,首先生成一個UserSession對象,在request的session加入這個 userSession,注意這部分代碼中給出了PagedListHolder分頁的簡單使用方法,關于分頁顯示,以后再學習吧。
    3、登錄成功后,就可以根據不同的用戶設施不同的行為了,取得用戶信息,無非就是從session取出userSession即可。


    老妖 2005-10-29 20:46 發表評論
    ]]>
    acegi 拾遺http://m.tkk7.com/rocky/archive/2005/10/17/15711.html老妖老妖Mon, 17 Oct 2005 06:35:00 GMThttp://m.tkk7.com/rocky/archive/2005/10/17/15711.htmlhttp://m.tkk7.com/rocky/comments/15711.htmlhttp://m.tkk7.com/rocky/archive/2005/10/17/15711.html#Feedback0http://m.tkk7.com/rocky/comments/commentRss/15711.htmlhttp://m.tkk7.com/rocky/services/trackbacks/15711.html      //construct secureObjectName
          String secureObjectName=mi.getMethod().getDeclaringClass().getName() +"."+ mi.getMethod().getName();
          SecureObject secureObject=securityManager.getSecureObject(secureObjectName);
          if(secureObject==null)//if secure object not exist in database
             return null;
          //retrieving roles associated with this secure object
          List secureObjectRoles=(List)securityManager.getSecureObjectRoles(secureObject);
          //creating ConfigAttributeDefinition
          if(!secureObjectRoles.isEmpty()){
             ConfigAttributeEditor configAttrEditor=new ConfigAttributeEditor();
             StringBuffer rolesStr=new StringBuffer();
             for(int i=0;i<secureObjectRoles.size();i++){
                SecureObjectRole sor=(SecureObjectRole)secureObjectRoles.get(i);
                rolesStr.append(sor.getRole().getRoleName()).append(",");
             }
             configAttrEditor.setAsText( rolesStr.toString().substring(0,rolesStr.length()-1) );
             ConfigAttributeDefinition configAttrDef=(ConfigAttributeDefinition)configAttrEditor.getValue();
             return configAttrDef;
          }
          return null;
          
       }

    老妖 2005-10-17 14:35 發表評論
    ]]>
    acegi怎么去動態的實現role和privilege?http://m.tkk7.com/rocky/archive/2005/09/28/14354.html老妖老妖Wed, 28 Sep 2005 14:32:00 GMThttp://m.tkk7.com/rocky/archive/2005/09/28/14354.htmlhttp://m.tkk7.com/rocky/comments/14354.htmlhttp://m.tkk7.com/rocky/archive/2005/09/28/14354.html#Feedback0http://m.tkk7.com/rocky/comments/commentRss/14354.htmlhttp://m.tkk7.com/rocky/services/trackbacks/14354.html

    老妖 2005-09-28 22:32 發表評論
    ]]>
    主站蜘蛛池模板: 最新亚洲人成网站在线观看 | 精品久久久久久国产免费了 | 亚洲日韩欧洲无码av夜夜摸| 桃子视频在线观看高清免费视频| 全免费a级毛片免费看| 亚洲一区二区三区亚瑟| 亚洲AV无码成人精品区大在线| 国产成人AV片无码免费| 亚洲乱理伦片在线观看中字| 日韩精品免费一级视频| 免费国产黄网站在线看| 亚洲天堂在线播放| 又粗又大又猛又爽免费视频| 无码毛片一区二区三区视频免费播放| 免费人成视频在线观看视频| 精品一区二区三区免费毛片爱| 亚洲午夜精品一区二区| 成人午夜亚洲精品无码网站| 日本免费久久久久久久网站| 日韩在线视频播放免费视频完整版 | 亚洲精品国产第1页| 亚洲午夜久久久久久久久电影网 | 亚洲欧洲精品无码AV| 国产猛烈高潮尖叫视频免费| 亚洲一区二区三区免费视频| a毛片在线看片免费| 免费无毒a网站在线观看| 亚洲成av人无码亚洲成av人| 亚洲妓女综合网99| 久久亚洲精品国产精品| 3344免费播放观看视频| a毛片免费全部在线播放**| 免费人成又黄又爽的视频在线电影| 亚洲一区中文字幕在线电影网| 亚洲高清不卡视频| 久久久无码精品亚洲日韩京东传媒| 亚洲精品成人片在线播放 | 国产vA免费精品高清在线观看| 无忧传媒视频免费观看入口| 成人免费观看男女羞羞视频| 久香草视频在线观看免费|