亚洲成a人片在线观看中文!!! ,亚洲乱码中文字幕小综合,久久亚洲免费视频http://www.tkk7.com/rocky/category/5208.html現(xiàn)實的中沒有幾個人能夠真為對方去死,甚至山盟海誓很快就會在金錢面前變的微不足道,這才是生活。沒有永遠的愛,除了你的父母對你,當然也就沒有永遠的恨,更沒有永遠的痛,時間是最好的治療大師,它會很快撫平你心靈上累累的傷痕。很多年以后你想起來時,那些在你生命中洶涌來往的人群至多是個模糊的影子或者毫無意義的名字zh-cnTue, 27 Feb 2007 11:42:50 GMTTue, 27 Feb 2007 11:42:50 GMT60關(guān)于 sitemesh 在weblogic spring下的亂碼問題解決http://www.tkk7.com/rocky/archive/2005/12/18/24467.html老妖老妖Sun, 18 Dec 2005 04:39:00 GMThttp://www.tkk7.com/rocky/archive/2005/12/18/24467.htmlhttp://www.tkk7.com/rocky/comments/24467.htmlhttp://www.tkk7.com/rocky/archive/2005/12/18/24467.html#Feedback0http://www.tkk7.com/rocky/comments/commentRss/24467.htmlhttp://www.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>
作業(yè)環(huán)境:
weblogic sp 5
spring 1.2.6
sitemesh 2.2.1
發(fā)現(xiàn)有中文亂碼問題。

在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 發(fā)表評論
]]>
新發(fā)現(xiàn)spring論壇的一個FAQ整理連接http://www.tkk7.com/rocky/archive/2005/11/23/21123.html老妖老妖Wed, 23 Nov 2005 06:26:00 GMThttp://www.tkk7.com/rocky/archive/2005/11/23/21123.htmlhttp://www.tkk7.com/rocky/comments/21123.htmlhttp://www.tkk7.com/rocky/archive/2005/11/23/21123.html#Feedback0http://www.tkk7.com/rocky/comments/commentRss/21123.htmlhttp://www.tkk7.com/rocky/services/trackbacks/21123.htmlhttp://forum.springframework.org/archive/index.php/

老妖 2005-11-23 14:26 發(fā)表評論
]]>
acegi擴展AbstractFilterInvocationDefinitionSourcehttp://www.tkk7.com/rocky/archive/2005/11/14/19627.html老妖老妖Sun, 13 Nov 2005 17:58:00 GMThttp://www.tkk7.com/rocky/archive/2005/11/14/19627.htmlhttp://www.tkk7.com/rocky/comments/19627.htmlhttp://www.tkk7.com/rocky/archive/2005/11/14/19627.html#Feedback4http://www.tkk7.com/rocky/comments/commentRss/19627.htmlhttp://www.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 發(fā)表評論
]]>
spring的mail如何發(fā)送html格式的郵件--轉(zhuǎn)自邢紅瑞的bloghttp://www.tkk7.com/rocky/archive/2005/11/12/19438.html老妖老妖Fri, 11 Nov 2005 18:36:00 GMThttp://www.tkk7.com/rocky/archive/2005/11/12/19438.htmlhttp://www.tkk7.com/rocky/comments/19438.htmlhttp://www.tkk7.com/rocky/archive/2005/11/12/19438.html#Feedback1http://www.tkk7.com/rocky/comments/commentRss/19438.htmlhttp://www.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 下面是具體的實現(xiàn)類
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 發(fā)表評論
]]>
using Spring Hotswapping for loading user classes from DBhttp://www.tkk7.com/rocky/archive/2005/11/09/19008.html老妖老妖Wed, 09 Nov 2005 08:50:00 GMThttp://www.tkk7.com/rocky/archive/2005/11/09/19008.htmlhttp://www.tkk7.com/rocky/comments/19008.htmlhttp://www.tkk7.com/rocky/archive/2005/11/09/19008.html#Feedback0http://www.tkk7.com/rocky/comments/commentRss/19008.htmlhttp://www.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 發(fā)表評論
    ]]>
    使用spring的mail發(fā)送帶有圖片的html的郵件--轉(zhuǎn)自邢紅瑞的bloghttp://www.tkk7.com/rocky/archive/2005/11/03/18004.html老妖老妖Thu, 03 Nov 2005 11:41:00 GMThttp://www.tkk7.com/rocky/archive/2005/11/03/18004.htmlhttp://www.tkk7.com/rocky/comments/18004.htmlhttp://www.tkk7.com/rocky/archive/2005/11/03/18004.html#Feedback0http://www.tkk7.com/rocky/comments/commentRss/18004.htmlhttp://www.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 發(fā)表評論
    ]]>
    使用spring的mail發(fā)送帶有附件的html的郵件--摘自邢紅瑞的bloghttp://www.tkk7.com/rocky/archive/2005/11/03/18002.html老妖老妖Thu, 03 Nov 2005 11:39:00 GMThttp://www.tkk7.com/rocky/archive/2005/11/03/18002.htmlhttp://www.tkk7.com/rocky/comments/18002.htmlhttp://www.tkk7.com/rocky/archive/2005/11/03/18002.html#Feedback0http://www.tkk7.com/rocky/comments/commentRss/18002.htmlhttp://www.tkk7.com/rocky/services/trackbacks/18002.html

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


     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 發(fā)表評論
    ]]>
    使用Spring郵件發(fā)送Emailhttp://www.tkk7.com/rocky/archive/2005/10/29/17375.html老妖老妖Sat, 29 Oct 2005 12:58:00 GMThttp://www.tkk7.com/rocky/archive/2005/10/29/17375.htmlhttp://www.tkk7.com/rocky/comments/17375.htmlhttp://www.tkk7.com/rocky/archive/2005/10/29/17375.html#Feedback0http://www.tkk7.com/rocky/comments/commentRss/17375.htmlhttp://www.tkk7.com/rocky/services/trackbacks/17375.htmlSpring提供了一個發(fā)送電子郵件的高級抽象層,它向用戶屏蔽了底層郵件系統(tǒng)的一些細節(jié),同時負責低層次的代表客戶端的資源處理。Spring郵件抽象層的主要包為org.springframework.mail。它包括了發(fā)送電子郵件的主要接口MailSender和 封裝了簡單郵件的屬性如from, to,cc, subject, text的值對象叫做SimpleMailMessage。
    首先:我們定義一個發(fā)送郵件的接口: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);
    }

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


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

    圖中綠色部分是安全攔截器的抽象基類,它包含有兩個管理類,AuthenticationManager和AccessDecisionManager,如圖中灰色部分。AuthenticationManager用于認證ContextHolder中的Authentication對象(包含了 Principal,Credential和Principal的授權(quán)信息);AccessDecissionManager則用于授權(quán)一個特定的操作。
    下面來看一個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的一個實現(xiàn)類。它包含了兩個管理器,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>
    準備工作做好了,現(xiàn)在我們來看看Acegi安全系統(tǒng)是如何實現(xiàn)認證和授權(quán)機制的。以使用HTTP BASIC認證的應用為例子,它包括下面的步驟:
    1. 用戶登錄系統(tǒng),Acegi從acegisecurity.ui子系統(tǒng)的安全攔截器(如BasicProcessingFilter)中得到用戶的登錄信息(包括Principal和Credential)并放入Authentication對象,并保存在ContextHolder對象中;
    2. 安全攔截器將Authentication對象交給AuthenticationManager進行身份認證,如果認證通過,返回帶有Principal 授權(quán)信息的Authentication對象。此時ContextHolder對象的Authentication對象已擁有Principal的詳細信息;
    3. 用戶登錄成功后,繼續(xù)進行業(yè)務操作;
    4. 安全攔截器(bankManagerSecurity)收到客戶端操作請求后,將操作請求的數(shù)據(jù)包裝成安全管理對象(FilterInvocation或MethodInvocation對象);
    5. 然后,從配置文件(ObjectDefinitionSource)中讀出相關(guān)的安全配置參數(shù)ConfigAttributeDefinition;
    6. 接著,安全攔截器取出ContextHolder中的Authentication對象,把它傳遞給AuthenticationManager進行身份認證,并用返回值更新ContextHolder的Authentication對象;
    7. 將Authentication對象,ConfigAttributeDefinition對象和安全管理對象(secure Object)交給AccessDecisionManager,檢查Principal的操作授權(quán);
    8. 如果授權(quán)檢查通過則執(zhí)行客戶端請求的操作,否則拒絕;
    AccessDecisionVoter
    注意上節(jié)的accessDecisionManager是一個AffirmativeBased類,它對于用戶授權(quán)的投票策略是,只要通過其中的一個授權(quán)投票檢查,即可通過;它的allowIfAllAbstainDecisions屬性值是false,意思是如果所有的授權(quán)投票是都是棄權(quán),則通不過授權(quán)檢查。
    Acegi安全系統(tǒng)包括了幾個基于投票策略的AccessDecisionManager,上節(jié)的RoleVoter就是其中的一個投票策略實現(xiàn),它是 AccessDecisionVoter的一個子類。AccessDecisionVoter的具體實現(xiàn)類通過投票來進行授權(quán)決策, AccessDecisionManager則根據(jù)投票結(jié)果來決定是通過授權(quán)檢查,還是拋出AccessDeniedException例外。
    AccessDecisionVoter接口共有三個方法:
    public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config);
    public boolean supports(ConfigAttribute attribute);
    public boolean supports(Class clazz);
    其中的vote方法返回int返回值,它們是AccessDecisionVoter的三個靜態(tài)成員屬性:ACCESS_ABSTAIN,,ACCESS_DENIED和ACCESS_GRANTED,它們分別是棄權(quán),否決和贊成。
    Acegi安全系統(tǒng)中,使用投票策略的AccessDecisionManager共有三個具體實現(xiàn)類:AffirmativeBased、 ConsensusBased和UnanimousBased。它們的投票策略是,AffirmativeBased類只需有一個投票贊成即可通過; ConsensusBased類需要大多數(shù)投票贊成即可通過;而UnanimousBased類需要所有的投票贊成才能通過。
    RoleVoter類是一個Acegi安全系統(tǒng)AccessDecisionVoter接口的實現(xiàn)。如果ConfigAttribute以ROLE_開頭,RoleVoter則進行投票。如果GrantedAuthority的getAutority方法的String返回值匹配一個或多個以ROLE_ 開頭的ConfigAttribute,則投票通過,否則不通過。如果沒有以ROLE_開頭的ConfigAttribute,RoleVoter則棄權(quán)。
    安全攔截器
    攔截器如何工作
    MethodInvocation攔截器
    FilterInvocation攔截器
    認證
    認證請求
    認證管理器
    Authentication Provider
    授權(quán)
    Access Decision Manager
    Voting Decision Manager
    授權(quán)管理推薦
    ContextHolder的用戶接口
    用戶接口目標
    HTTP會話認證
    HTTP Basic認證
    1、Log4j的概念
    Log4j中有三個主要的組件,它們分別是Logger、Appender和Layout,Log4j 允許開發(fā)人員定義多個Logger,每個Logger擁有自己的名字,Logger之間通過名字來表明隸屬關(guān)系。有一個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,當輸出時,只有級別高過配置中規(guī)定的級別的信息才能真正的輸出,這樣就很方便的來配置不同情況下要輸出的內(nèi)容,而不需要更改代碼,這點實在是方便啊。

    2、Log4j的配置文件
    雖然可以不用配置文件,而在程序中實現(xiàn)配置,但這種方法在如今的系統(tǒng)開發(fā)中顯然是不可取的,能采用配置文件的地方一定一定要用配置文件。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, ...,其中l(wèi)evel就是設置需要輸出信息的級別,后面是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(每天產(chǎn)生一個日志文件)
    org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的時候產(chǎn)生新文件)
    org.apache.log4j.WriterAppender(將日志信息以流格式發(fā)送到任意指定的地方)
    配置日志信息的格式(布局),其語法為:
    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(包含日志產(chǎn)生的時間、線程、類別等等信息)

    3、Log4j在程序中的使用
    要在自己的類中使用Log4j,首先聲明一個靜態(tài)變量Logger logger=Logger.getLog("classname");在使用之前,用PropertyConfigurator.configure ("配置文件")配置一下,現(xiàn)在就可以使用了,用法如下: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應用,完善的認證和授權(quán)機制是必不可少的,在SpringFramework中,Juergen Hoeller提供的范例JPetStore給了一些這方面的介紹,但還遠遠不夠,Acegi是一個專門為SpringFramework提供安全機制的項目,全稱為Acegi Security System for Spring,當前版本為0.5.1,就其目前提供的功能,應該可以滿足絕大多數(shù)應用的需求。

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

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

    [web.xml]
    實現(xiàn)認證和授權(quán)的最常用的方法是通過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"相關(guān)內(nèi)容注釋掉即可;
    3) 如果你的應用不需要Spring提供的遠程訪問機制,如Hessian and Burlap,將"Acegi HTTP BASIC Authorization
    Filter"相關(guān)內(nèi)容注釋掉即可。

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

    1) 首先,你的數(shù)據(jù)庫中必須具有保存用戶名和密碼的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) 添加訪問你的數(shù)據(jù)庫的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中定義哪些頁面需要權(quán)限訪問,需要根據(jù)自己的應用需求進行修改,我上面給出
    的定義的意思是這樣的:
    a. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON意思是在比較請求路徑時全部轉(zhuǎn)換為小寫
    b. \A/sec/administrator.*\Z=ROLE_SUPERVISOR意思是只有權(quán)限為ROLE_SUPERVISOR才能訪問/sec/administrator*的頁面
    c. \A/sec/user.*\Z=ROLE_TELLER意思是只有權(quán)限為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對訪問頁面的權(quán)限控制,除此之外,Acegi還提供了另外一個Interceptor——
    MethodSecurityInterceptor,它結(jié)合runAsManager可實現(xiàn)對對象中的方法的權(quán)限控制,使用方法可參看Acegi自帶的文檔
    和contact范例。

    [最后要說的]
    本來以為只是說明如何使用Acegi而已,應該非常簡單,但真正寫起來才發(fā)現(xiàn)想要條理清楚的理順所有需要的bean還是很
    困難的,但愿我沒有遺漏太多東西,如果我的文章有什么遺漏或錯誤的話,還請參看Acegi自帶的quick-start范例,但請
    注意,這個范例是不能直接拿來用的。
    分析和學習Spring中的jpetstore用戶管理
    存在用戶的系統(tǒng),必然需要用戶的登錄和認證,今天就通過分析Spring中自帶的jpetstore的例子來學習一下如何實現(xiàn)在Spring構(gòu)架的系統(tǒng)中用戶登錄。
    1、首先從注冊用戶開始,先看看jpetstore-servlet.xml中關(guān)于注冊用戶的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的構(gòu)造函數(shù)中得到,原來為EditAccountForm;
    2). EditoAccountForm.jsp中顯得非常亂,其實沒有多少難理解的地方,最主要的是這個form既是添加新用戶的,又是編輯用戶信息的,所以顯得有點亂糟糟的。
    2、添加好了新用戶,接下來看看如何登錄,在jpetstore-servlet中發(fā)現(xiàn)這兩個相關(guān)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實現(xiàn)了preHandle,因此在請求上面的map頁面時,首先要經(jīng)過這個Interceptor,看看 SignonInterceptor的源碼,原來在其中為signon.jsp賦予一個signonForwardAction對象,呵呵,總算明白了。
    3). 接下來去學習一下SignonController,其主體部分中可以看出,首先取出用戶輸入的username和password,然后到數(shù)據(jù)庫中驗證有沒有這個用戶,如果沒有這個用戶,返回各錯誤頁面;如果成功,首先生成一個UserSession對象,在request的session加入這個 userSession,注意這部分代碼中給出了PagedListHolder分頁的簡單使用方法,關(guān)于分頁顯示,以后再學習吧。
    3、登錄成功后,就可以根據(jù)不同的用戶設施不同的行為了,取得用戶信息,無非就是從session取出userSession即可。


    老妖 2005-10-29 20:46 發(fā)表評論
    ]]>
    acegi 拾遺http://www.tkk7.com/rocky/archive/2005/10/17/15711.html老妖老妖Mon, 17 Oct 2005 06:35:00 GMThttp://www.tkk7.com/rocky/archive/2005/10/17/15711.htmlhttp://www.tkk7.com/rocky/comments/15711.htmlhttp://www.tkk7.com/rocky/archive/2005/10/17/15711.html#Feedback0http://www.tkk7.com/rocky/comments/commentRss/15711.htmlhttp://www.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 發(fā)表評論
    ]]>
    acegi怎么去動態(tài)的實現(xiàn)role和privilege?http://www.tkk7.com/rocky/archive/2005/09/28/14354.html老妖老妖Wed, 28 Sep 2005 14:32:00 GMThttp://www.tkk7.com/rocky/archive/2005/09/28/14354.htmlhttp://www.tkk7.com/rocky/comments/14354.htmlhttp://www.tkk7.com/rocky/archive/2005/09/28/14354.html#Feedback0http://www.tkk7.com/rocky/comments/commentRss/14354.htmlhttp://www.tkk7.com/rocky/services/trackbacks/14354.html

    老妖 2005-09-28 22:32 發(fā)表評論
    ]]>
    主站蜘蛛池模板: 国产亚洲精品无码拍拍拍色欲| 亚洲国产成人久久精品大牛影视| 日韩免费观看视频| 免费观看久久精彩视频| 成a人片亚洲日本久久| 亚洲一区二区三区精品视频| 亚洲国产精品一区二区第一页 | 亚洲AV无码一区二区二三区软件| 免费无码黄网站在线观看| 免费黄色福利视频| 男女作爱在线播放免费网站| 国产视频精品免费视频| 久久精品国产亚洲av天美18| 久久综合久久综合亚洲| 亚洲综合激情视频| 亚洲一区二区三区首页| 亚洲av午夜福利精品一区人妖| 国产专区一va亚洲v天堂| 波多野结衣视频在线免费观看| 最近免费中文字幕4| 色婷婷7777免费视频在线观看| 1000部拍拍拍18勿入免费凤凰福利 | 国产精品永久免费视频| 精品女同一区二区三区免费播放| 亚洲日韩精品无码AV海量| va天堂va亚洲va影视中文字幕 | 4455永久在线观免费看| 99视频全部免费精品全部四虎| 6080午夜一级毛片免费看| 污污网站18禁在线永久免费观看| 国产婷婷成人久久Av免费高清| 中文成人久久久久影院免费观看 | www亚洲精品少妇裸乳一区二区| 国产婷婷高清在线观看免费| 国产在线不卡免费播放| 四虎成人精品在永久免费| 免费在线观看黄网站| 亚洲午夜爱爱香蕉片| 久久精品亚洲福利| 亚洲av无码成人黄网站在线观看| 亚洲AV人无码激艳猛片|