亚洲精品视频在线播放,久久91导航,国产精品av久久久久久麻豆网http://www.aygfsteel.com/rocky/category/5208.html現(xiàn)實(shí)的中沒有幾個人能夠真為對方去死,甚至山盟海誓很快就會在金錢面前變的微不足道,這才是生活。沒有永遠(yuǎn)的愛,除了你的父母對你,當(dāng)然也就沒有永遠(yuǎn)的恨,更沒有永遠(yuǎn)的痛,時間是最好的治療大師,它會很快撫平你心靈上累累的傷痕。很多年以后你想起來時,那些在你生命中洶涌來往的人群至多是個模糊的影子或者毫無意義的名字zh-cnTue, 27 Feb 2007 11:42:50 GMTTue, 27 Feb 2007 11:42:50 GMT60關(guān)于 sitemesh 在weblogic spring下的亂碼問題解決http://www.aygfsteel.com/rocky/archive/2005/12/18/24467.html老妖老妖Sun, 18 Dec 2005 04:39:00 GMThttp://www.aygfsteel.com/rocky/archive/2005/12/18/24467.htmlhttp://www.aygfsteel.com/rocky/comments/24467.htmlhttp://www.aygfsteel.com/rocky/archive/2005/12/18/24467.html#Feedback0http://www.aygfsteel.com/rocky/comments/commentRss/24467.htmlhttp://www.aygfsteel.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做編碼處理
自己對其做了一點(diǎn)小的修改紅色字部分
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.aygfsteel.com/rocky/archive/2005/11/23/21123.html老妖老妖Wed, 23 Nov 2005 06:26:00 GMThttp://www.aygfsteel.com/rocky/archive/2005/11/23/21123.htmlhttp://www.aygfsteel.com/rocky/comments/21123.htmlhttp://www.aygfsteel.com/rocky/archive/2005/11/23/21123.html#Feedback0http://www.aygfsteel.com/rocky/comments/commentRss/21123.htmlhttp://www.aygfsteel.com/rocky/services/trackbacks/21123.htmlhttp://forum.springframework.org/archive/index.php/

老妖 2005-11-23 14:26 發(fā)表評論
]]>
acegi擴(kuò)展AbstractFilterInvocationDefinitionSourcehttp://www.aygfsteel.com/rocky/archive/2005/11/14/19627.html老妖老妖Sun, 13 Nov 2005 17:58:00 GMThttp://www.aygfsteel.com/rocky/archive/2005/11/14/19627.htmlhttp://www.aygfsteel.com/rocky/comments/19627.htmlhttp://www.aygfsteel.com/rocky/archive/2005/11/14/19627.html#Feedback4http://www.aygfsteel.com/rocky/comments/commentRss/19627.htmlhttp://www.aygfsteel.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.aygfsteel.com/rocky/archive/2005/11/12/19438.html老妖老妖Fri, 11 Nov 2005 18:36:00 GMThttp://www.aygfsteel.com/rocky/archive/2005/11/12/19438.htmlhttp://www.aygfsteel.com/rocky/comments/19438.htmlhttp://www.aygfsteel.com/rocky/archive/2005/11/12/19438.html#Feedback1http://www.aygfsteel.com/rocky/comments/commentRss/19438.htmlhttp://www.aygfsteel.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 下面是具體的實(shí)現(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認(rèn)證必須添加紅色部分
37 


老妖 2005-11-12 02:36 發(fā)表評論
]]>
using Spring Hotswapping for loading user classes from DBhttp://www.aygfsteel.com/rocky/archive/2005/11/09/19008.html老妖老妖Wed, 09 Nov 2005 08:50:00 GMThttp://www.aygfsteel.com/rocky/archive/2005/11/09/19008.htmlhttp://www.aygfsteel.com/rocky/comments/19008.htmlhttp://www.aygfsteel.com/rocky/archive/2005/11/09/19008.html#Feedback0http://www.aygfsteel.com/rocky/comments/commentRss/19008.htmlhttp://www.aygfsteel.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.aygfsteel.com/rocky/archive/2005/11/03/18004.html老妖老妖Thu, 03 Nov 2005 11:41:00 GMThttp://www.aygfsteel.com/rocky/archive/2005/11/03/18004.htmlhttp://www.aygfsteel.com/rocky/comments/18004.htmlhttp://www.aygfsteel.com/rocky/archive/2005/11/03/18004.html#Feedback0http://www.aygfsteel.com/rocky/comments/commentRss/18004.htmlhttp://www.aygfsteel.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.aygfsteel.com/rocky/archive/2005/11/03/18002.html老妖老妖Thu, 03 Nov 2005 11:39:00 GMThttp://www.aygfsteel.com/rocky/archive/2005/11/03/18002.htmlhttp://www.aygfsteel.com/rocky/comments/18002.htmlhttp://www.aygfsteel.com/rocky/archive/2005/11/03/18002.html#Feedback0http://www.aygfsteel.com/rocky/comments/commentRss/18002.htmlhttp://www.aygfsteel.com/rocky/services/trackbacks/18002.html

    有的朋友問我如何發(fā)送帶有附件的html的郵件,不要加入contentID,使用addAttachment即可
    實(shí)現(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.aygfsteel.com/rocky/archive/2005/10/29/17375.html老妖老妖Sat, 29 Oct 2005 12:58:00 GMThttp://www.aygfsteel.com/rocky/archive/2005/10/29/17375.htmlhttp://www.aygfsteel.com/rocky/comments/17375.htmlhttp://www.aygfsteel.com/rocky/archive/2005/10/29/17375.html#Feedback0http://www.aygfsteel.com/rocky/comments/commentRss/17375.htmlhttp://www.aygfsteel.com/rocky/services/trackbacks/17375.htmlSpring提供了一個發(fā)送電子郵件的高級抽象層,它向用戶屏蔽了底層郵件系統(tǒng)的一些細(xì)節(jié),同時負(fù)責(zé)低層次的代表客戶端的資源處理。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);
    }

    然后實(shí)現(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服務(wù)器</value></property>
    <property name="username"><value>用戶名</value></property>
    <property name="password"><value>密碼</value></property>
    /**如果服務(wù)器要求驗(yàn)證,加上此**/
    <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>郵件標(biāo)題</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>
    在對應(yīng)的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.aygfsteel.com/rocky/archive/2005/10/29/17373.html老妖老妖Sat, 29 Oct 2005 12:46:00 GMThttp://www.aygfsteel.com/rocky/archive/2005/10/29/17373.htmlhttp://www.aygfsteel.com/rocky/comments/17373.htmlhttp://www.aygfsteel.com/rocky/archive/2005/10/29/17373.html#Feedback0http://www.aygfsteel.com/rocky/comments/commentRss/17373.htmlhttp://www.aygfsteel.com/rocky/services/trackbacks/17373.htmlAcegi安全系統(tǒng),是一個用于Spring Framework的安全框架,能夠和目前流行的Web容器無縫集成。它使用了Spring的方式提供了安全和認(rèn)證安全服務(wù),包括使用Bean Context,攔截器和面向接口的編程方式。因此,Acegi安全系統(tǒng)能夠輕松地適用于復(fù)雜的安全需求。
    安全涉及到兩個不同的概念,認(rèn)證和授權(quán)。前者是關(guān)于確認(rèn)用戶是否確實(shí)是他們所宣稱的身份。授權(quán)則是關(guān)于確認(rèn)用戶是否有允許執(zhí)行一個特定的操作。
    在Acegi安全系統(tǒng)中,需要被認(rèn)證的用戶,系統(tǒng)或代理稱為"Principal"。Acegi安全系統(tǒng)和其他的安全系統(tǒng)不同,它并沒有角色和用戶組的概念。
    Acegi系統(tǒng)設(shè)計(jì)
    關(guān)鍵組件
    Acegi安全系統(tǒng)包含以下七個關(guān)鍵的功能組件:
    l Authentication對象,包含了Principal,Credential和Principal的授權(quán)信息。同時還可以包含關(guān)于發(fā)起認(rèn)證請求的客戶的其他信息,如IP地址。
    2 ContextHolder對象,使用ThreadLocal儲存Authentication對象的地方。
    3 AuthenticationManager,用于認(rèn)證ContextHolder中的Authentication對象。
    4 AccessDecissionManager,用于授權(quán)一個特定的操作。
    5 RunAsManager,當(dāng)執(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ā)人員可以用它來保護(hù)Spring容器中的業(yè)務(wù)對象。為了使Spring管理的Bean可以作為 MethodInvocation來使用,Bean可以通過ProxyFactoryBean和BeanNameAutoProxyCreator來管理,就像在Spring的事務(wù)管理一樣使用。
    第二類是FilterInvocation。它用過濾器(Filter)來創(chuàng)建,并簡單地包裝了HTTP的ServletRequest, ServletResponse和FilterChain。FilterInvocation可以用來保護(hù)HTTP資源。通常,開發(fā)人員并不需要了解它的工作機(jī)制,因?yàn)樗麄冎恍枰獙ilter加入web.xml,Acegi安全系統(tǒng)就可以工作了。
    安全配置參數(shù)
    每個安全管理對象都可以描述數(shù)量不限的各種安全認(rèn)證請求。例如,MethodInvocation對象可以描述帶有任意參數(shù)的任意方法的調(diào)用,而FilterInvocation可以描述任意的HTTP URL。
    Acegi安全系統(tǒng)需要記錄應(yīng)用于每個認(rèn)證請求的安全配置參數(shù)。例如,對于BankManager.getBalance(int accountNumber)方法和BankManager.approveLoan(int applicationNumber)方法,它們需要的認(rèn)證請求的安全配置很不相同。
    為了保存不同的認(rèn)證請求的安全配置,需要使用配置參數(shù)。從實(shí)現(xiàn)的視角來看,配置參數(shù)使用ConfigAttribute接口來表示。Acegi安全系統(tǒng)提供了ConfigAttribute接口的一個實(shí)現(xiàn),SecurityConfig,它把配置參數(shù)保存為一個字符串。
    ConfigAttributeDefinition類是ConfigAttribute對象的一個簡單的容器,它保存了和特定請求相關(guān)的ConfigAttribute的集合。
    當(dāng)安全攔截器收到一個安全認(rèn)證請求時,需要決定應(yīng)用哪一個配置參數(shù)。換句話說,它需要找出應(yīng)用于這個請求的 ConfigAttributeDefinition對象。這個查找的過程是由ObjectDefinitionSource接口來處理的。這個接口的主要方法是public ConfigAttributeDefinition getAttributes(Object object),其中Object參數(shù)是一個安全管理對象。因?yàn)榘踩芾韺ο蟀姓J(rèn)證請求的詳細(xì)信息,所以 ObjectDefinitionSource接口的實(shí)現(xiàn)類可以從中獲得所需的詳細(xì)信息,以查找相關(guān)的ConfigAttributeDefiniton 對象。
    Acegi如何工作
    為了說明Acegi安全系統(tǒng)如何工作,我們設(shè)想一個使用Acegi的例子。通常,一個安全系統(tǒng)需要發(fā)揮作用,它必須完成以下的工作:
    l 首先,系統(tǒng)從客戶端請求中獲得Principal和Credential;
    2 然后系統(tǒng)認(rèn)證Principal和Credential信息;
    3 如果認(rèn)證通過,系統(tǒng)取出Principal的授權(quán)信息;
    4 接下來,客戶端發(fā)起操作請求;
    5 系統(tǒng)根據(jù)預(yù)先配置的參數(shù)檢查Principal對于該操作的授權(quán);
    6 如果授權(quán)檢查通過則執(zhí)行操作,否則拒絕。
    那么,Acegi安全系統(tǒng)是如何完成這些工作的呢?首先,我們來看看Acegi安全系統(tǒng)的認(rèn)證和授權(quán)的相關(guān)類圖:

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

    2、Log4j的配置文件
    雖然可以不用配置文件,而在程序中實(shí)現(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

    首先,是設(shè)置root,格式為 log4j.rootLogger=[level],appenderName, ...,其中l(wèi)evel就是設(shè)置需要輸出信息的級別,后面是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(文件大小到達(dá)指定尺寸的時候產(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應(yīng)用,完善的認(rèn)證和授權(quán)機(jī)制是必不可少的,在SpringFramework中,Juergen Hoeller提供的范例JPetStore給了一些這方面的介紹,但還遠(yuǎn)遠(yuǎn)不夠,Acegi是一個專門為SpringFramework提供安全機(jī)制的項(xiàng)目,全稱為Acegi Security System for Spring,當(dāng)前版本為0.5.1,就其目前提供的功能,應(yīng)該可以滿足絕大多數(shù)應(yīng)用的需求。

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

    [基礎(chǔ)工作]
    在你的Web應(yīng)用的lib中添加Acegi下載包中的acegi-security.jar

    [web.xml]
    實(shí)現(xiàn)認(rè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.”,如希望深究的話,去看看源代碼應(yīng)該不難理解。

    再下來就是添加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>

    這里,需要注意以下兩點(diǎn):
    1) 這幾個filter的順序是不能更改的,順序不對將無法正常工作;
    2) 如果你的應(yīng)用不需要安全傳輸,如https,則將"Acegi Channel Processing Filter"相關(guān)內(nèi)容注釋掉即可;
    3) 如果你的應(yīng)用不需要Spring提供的遠(yuǎn)程訪問機(jī)制,如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提供了幾種加密方法,詳細(xì)情況可看包
    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ù)自己的應(yīng)用需求進(jìn)行修改,我上面給出
    的定義的意思是這樣的:
    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是認(rèn)證失敗的頁面。

    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",分別對頁面和方法進(jìn)行安全認(rèn)證管理,我這里介紹的只是利用
    FilterSecurityInterceptor對訪問頁面的權(quán)限控制,除此之外,Acegi還提供了另外一個Interceptor——
    MethodSecurityInterceptor,它結(jié)合runAsManager可實(shí)現(xiàn)對對象中的方法的權(quán)限控制,使用方法可參看Acegi自帶的文檔
    和contact范例。

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


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

    老妖 2005-09-28 22:32 發(fā)表評論
    ]]>
    主站蜘蛛池模板: 三河市| 宝丰县| 垣曲县| 二连浩特市| 保康县| 盐源县| 甘肃省| 方山县| 嫩江县| 南安市| 南城县| 安阳市| 灌云县| 板桥市| 山阳县| 巫山县| 开原市| 嘉义县| 庆元县| 津南区| 龙山县| 昌图县| 大姚县| 通辽市| 达州市| 克什克腾旗| 大足县| 芷江| 阿拉善左旗| 惠水县| 和田市| 兖州市| 苍梧县| 尼玛县| 绿春县| 连州市| 怀远县| 垣曲县| 墨竹工卡县| 永平县| 扎囊县|