2007-03-12
Spring+Hibernate+Acegi 的初次体验
关键字: ACEGI
到现在我也没有弄明白Acegi里面很多的功能,刚刚开始学的时候我就已经被它那繁琐的配置震慑住了,不过当我动起手来一步步实现的时候,才发现其实它远没有那么难,当然随着学习的深入,会渐渐再发现这一点吧,现在就让我们初学者一切体验Acegi的功能吧!
还以我传统的例子为例:
毕业设计选题系统,三种角色:教师,学生,管理员,我想让他们的登陆都在一个界面下自动识别,而无需进行身份选择,登陆后,他们将分别到各自的admin.jsp,stu.jsp,teacher.jsp
在数据库中的表结构如下(很多属性略):
id--- user---password--type---about
type是用来存储用户的类别,分别有a,t,s分别对应三种角色
about对应的是acegi里所需要的enable,用户是否可用
在model里,我们采用了继承关系:
父类user:
子类的实现:
======================
================
=================
对于三者所共有的属性在数据库里,都存在一个字段,而依据不同的角色拥有不同的含义,学生的班级则存放在了about里,只要学生有班级,他就able,否则就enable了!而管理员和教师则默认为1!
这种是属于一个继承树存放在一个表的情况,Hibernate的配置如下:
=============================================
上面的这些都是模型的基础,下面再讲怎么样配合Spring和Acegi实现系统的安全与登陆
在Spring中Hibernate的配置只介绍不说明:
==================
上面具体的不用了解,无非就是调用和数据库的操作,
下面就要对Acegi进行声明了:
我不用Ctrl+c和Ctrl+V的方式对Acegi进行介绍,没有意义,随便google就一大堆
我们想主要在这样的系统中需要的安全策略都有哪些?
1.用户的登陆
2.防止多个用户登陆一个帐号
3.用户的注销
4.防止非法用户的访问
我这个程序所涉及到的只有这些,下面就进行说明:
在web.xml的声明:
Acegi通过实现了Filter接口的FilterToBeanProxy提供一种特殊的使用Servlet Filter的方式,它委托Spring中的Bean -- FilterChainProxy来完成过滤功能,这样就简化了web.xml的配置,并且利用Spring IOC的优势。FilterChainProxy包含了处理认证过程的filter列表,每个filter都有各自的功能。
大体上先介绍一下:
httpSessionContextIntegrationFilter:每次request前 HttpSessionContextIntegrationFilter从Session中获取Authentication对象,在request完后, 又把Authentication对象保存到Session中供下次request使用,此filter必须其他Acegi filter前使用,使之能跨越多个请求。
logoutFilter:用户的注销
authenticationProcessingFilter:处理登陆请求
exceptionTranslationFilter:异常转换过滤器
filterInvocationInterceptor:在访问前进行权限检查
这些就犹如在web.xml声明一系列的过滤器,不过当把他们都声明在spring中就可以享受Spring给我们带来的方便了。
下面就是对这些过滤器的具体声明:
只对有用的地方进行声明,别的地方几乎都是默许的
下面的这个过滤器,我们根据自己的需求有了自己的实现:
==============
对于上面登陆请求的处理器我借鉴了springSide,实现的方法如下:
在看看我的login.htm在登陆成功时是怎么工作的吧?
当然,Acegi需要介绍的东西太多了,我只把我这次认为有必要解释的东西写在了上面让大家来参考,作为能google到的东西,比如对于认证的方式还有很多,我就没有详细的介绍,在学习Acegi过程中,把它自带的例子弄清楚很关键,希望大家一起学习一起共勉!
还以我传统的例子为例:
毕业设计选题系统,三种角色:教师,学生,管理员,我想让他们的登陆都在一个界面下自动识别,而无需进行身份选择,登陆后,他们将分别到各自的admin.jsp,stu.jsp,teacher.jsp
在数据库中的表结构如下(很多属性略):
id--- user---password--type---about
type是用来存储用户的类别,分别有a,t,s分别对应三种角色
about对应的是acegi里所需要的enable,用户是否可用
在model里,我们采用了继承关系:
父类user:
package subject.model;
public abstract class User extends BaseObject
{
private Integer id;
private String user;
private String password;
private String name;
private String telphone;
//set and get method
//这个是用来反映用户角色的关键函数,在子类实现,从而实现多态
public abstract String getType();
}
子类的实现:
======================
package subject.model;
import subject.Constants;
public class Teacher extends User
{
private String level; //教师的职称
//set and get method
public String getType()
{
return Constants.TEACHER;
}
}
================
package subject.model;
import subject.Constants;
public class Student extends User
{
private static final long serialVersionUID = 1L;
private SchoolClass schoolClass; //学生的班级
private String sn; //学生的学号
//set and get method
public String getType()
{
return Constants.STUDENT;
}
}
=================
package subject.model;
import subject.Constants;
public class Admin extends User
{
private String grade; //管理员的级别
//set and get method
public String getType()
{
return Constants.ADMIN;
}
}
对于三者所共有的属性在数据库里,都存在一个字段,而依据不同的角色拥有不同的含义,学生的班级则存放在了about里,只要学生有班级,他就able,否则就enable了!而管理员和教师则默认为1!
这种是属于一个继承树存放在一个表的情况,Hibernate的配置如下:
<hibernate-mapping>
<class name="subject.model.User" discriminator-value="not null">
<id name="id">
<generator class="increment" />
</id>
<discriminator column="type" type="character" />
<property name="user" />
<property name="password" />
<property name="name" />
<property name="telphone" />
<subclass name="subject.model.Admin" discriminator-value="a">
<property name="grade" column="sn" />
</subclass>
<subclass name="subject.model.Teacher" discriminator-value="t">
<property name="level" column="sn" />
</subclass>
<subclass name="subject.model.Student" discriminator-value="s">
<property name="sn" />
<many-to-one name="schoolClass" class="subject.model.SchoolClass"
column="about" update="false" insert="false" />
</subclass>
</class>
</hibernate-mapping>
=============================================
上面的这些都是模型的基础,下面再讲怎么样配合Spring和Acegi实现系统的安全与登陆
在Spring中Hibernate的配置只介绍不说明:
<!-- 定义DBCP数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/subject?useUnicode=true&characterEncoding=gbk" />
<property name="username" value="root" />
<property name="password" value="" />
<property name="maxActive" value="100" />
<property name="maxIdle" value="30" />
<property name="maxWait" value="1000" />
<property name="defaultAutoCommit" value="true" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="60" />
</bean>
<!-- Hibernate -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>
<value>subject/model/User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- Dao对象 -->
<bean id="userDao" class="subject.dao.hibernate.UserDaoImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 业务逻辑 -->
<bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<bean id="userManager" parent="txProxyTemplate">
<property name="target">
<bean class="subject.service.impl.UserManagerImpl">
<property name="userDao" ref="userDao" />
</bean>
</property>
</bean>
<!-- Struts -->
<bean name="/user" class="subject.web.action.UserAction" singleton="false">
<property name="userManager">
<ref bean="userManager" />
</property>
</bean>
==================
上面具体的不用了解,无非就是调用和数据库的操作,
下面就要对Acegi进行声明了:
我不用Ctrl+c和Ctrl+V的方式对Acegi进行介绍,没有意义,随便google就一大堆
我们想主要在这样的系统中需要的安全策略都有哪些?
1.用户的登陆
2.防止多个用户登陆一个帐号
3.用户的注销
4.防止非法用户的访问
我这个程序所涉及到的只有这些,下面就进行说明:
在web.xml的声明:
<!-- Acegi安全控制 Filter 配置 -->
<filter>
<filter-name>securityFilter</filter-name>
<filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>org.acegisecurity.util.FilterChainProxy</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>securityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Acegi通过实现了Filter接口的FilterToBeanProxy提供一种特殊的使用Servlet Filter的方式,它委托Spring中的Bean -- FilterChainProxy来完成过滤功能,这样就简化了web.xml的配置,并且利用Spring IOC的优势。FilterChainProxy包含了处理认证过程的filter列表,每个filter都有各自的功能。
<!-- ======================== FILTER CHAIN ======================= -->
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,
securityContextHolderAwareRequestFilter,exceptionTranslationFilter,filterInvocationInterceptor
</value>
</property>
</bean>
大体上先介绍一下:
httpSessionContextIntegrationFilter:每次request前 HttpSessionContextIntegrationFilter从Session中获取Authentication对象,在request完后, 又把Authentication对象保存到Session中供下次request使用,此filter必须其他Acegi filter前使用,使之能跨越多个请求。
logoutFilter:用户的注销
authenticationProcessingFilter:处理登陆请求
exceptionTranslationFilter:异常转换过滤器
filterInvocationInterceptor:在访问前进行权限检查
这些就犹如在web.xml声明一系列的过滤器,不过当把他们都声明在spring中就可以享受Spring给我们带来的方便了。
下面就是对这些过滤器的具体声明:
只对有用的地方进行声明,别的地方几乎都是默许的
<!-- ======================== FILTER ======================= -->
<bean id="httpSessionContextIntegrationFilter"
class="org.acegisecurity.context.HttpSessionContextIntegrationFilter" />
<bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
<constructor-arg value="/index.htm" /> 离开后所转向的位置
<constructor-arg>
<list>
<bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
</list>
</constructor-arg>
<property name="filterProcessesUrl" value="/logout.htm" /> 定义用户注销的地址,
</bean>
下面的这个过滤器,我们根据自己的需求有了自己的实现:
<bean id="authenticationProcessingFilter" class="subject.web.filter.UserAuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/> 下面会介绍的用来起到认证管理的作用
<property name="authenticationFailureUrl" value="/login.htm?error=wrong"/> 登陆失败的地址
<property name="defaultTargetUrl" value="/login.htm"/> 登陆成功的地址
<property name="filterProcessesUrl" value="/j_security_check"/> 登陆请求的地址
<property name="userManager" ref="userManager"/> 自己添加的属性,这样就可以访问到我们的业务逻辑
<property name="exceptionMappings"> 出现异常所对应的地址
<value>
org.acegisecurity.AuthenticationException=/login.htm?error=fail 登陆失败 org.acegisecurity.concurrent.ConcurrentLoginException=/login.htm?error=too 已登陆了
</value>
</property>
</bean>
<bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/>
<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint">
<bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="/login.htm?error=please"/>//如果用户没登陆就想访问,先到这里登陆吧
<property name="forceHttps" value="false"/>
</bean>
</property>
</bean>
<bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/> 认证服务
<property name="accessDecisionManager">
<bean class="org.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions" value="false"/>
<property name="decisionVoters">
<list>
<bean class="org.acegisecurity.vote.RoleVoter">
<property name="rolePrefix" value=""/> //这里定义数据库中存放的角色和我们在这里声明的角色间是否需要加个前缀?我没加
</bean>
</list>
</property>
</bean>
</property>
<property name="objectDefinitionSource">
<value>
PATTERN_TYPE_APACHE_ANT
/admin.htm*=a 这里就是数据库中对应的tyep a
/student*=s 由于没有前缀和数据库里一样
/teacher*=t
</value>
</property>
</bean>
<bean id="loggerListener"
class="org.acegisecurity.event.authentication.LoggerListener"/> 记录事件
下面就要说明我们的认证服务了,其起到的关键作用就是用来保证用户登陆身份的验证:
它将验证的功能委托给多个Provider,并通过遍历Providers, 以保证获取不同来源的身份认证,若某个Provider能成功确认当前用户的身份,authenticate()方法会返回一个完整的包含用户授权信息的Authentication对象,否则会抛出一个AuthenticationException。
先声明一个管理器吧,在上面的过滤器中都已经用到过了
<!-- ======================== AUTHENTICATION ======================= -->
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider" /> 我仅仅用到 从数据库中读取用户信息验证身份
</list>
</property>
<property name="sessionController">
<bean id="concurrentSessionController"
class="org.acegisecurity.concurrent.ConcurrentSessionControllerImpl">
<property name="maximumSessions">
<value>1</value>每个用户同时登陆一位
</property>
<property name="sessionRegistry">
<bean id="sessionRegistry" class="org.acegisecurity.concurrent.SessionRegistryImpl" />
</property>
<property name="exceptionIfMaximumExceeded" value="true" />
</bean>
</property>
</bean>
来实现唯一的一个Provider,从数据库验证身份
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService">
<bean id="jdbcDaoImpl"
class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource" ref="dataSource"/>
<property name="usersByUsernameQuery">
<value>
select user,password,about from user where user = ? 查找用户的查询语句,只需要把你数据库中的用户和密码以及enable相对应上就行
</value>
</property>
<property name="authoritiesByUsernameQuery">
<value>
select user,type from user where user = ? 这里就是把用户和权限对应上,在appfuse中用的两个表,我都放一个表里了,所以就用这一个就行问题的关键是要让它能找到两个字段,构成一个对象
</value>
</property>
</bean>
</property>
<property name="userCache"> 缓存都这么写:
<bean class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
<property name="cache">
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager">
<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
</property>
<property name="cacheName" value="userCache"/>
</bean>
</property>
</bean>
</property>
</bean>
==============
对于上面登陆请求的处理器我借鉴了springSide,实现的方法如下:
package subject.web.filter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.acegisecurity.Authentication;
import org.acegisecurity.context.SecurityContext;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
import org.acegisecurity.userdetails.UserDetails;
import subject.Constants;
import subject.model.User;
import subject.service.UserManager;
public class UserAuthenticationProcessingFilter extends
AuthenticationProcessingFilter
{
private UserManager userManager;
public void setUserManager( UserManager userManager )
{
this.userManager = userManager;
}
protected boolean requiresAuthentication( HttpServletRequest request ,
HttpServletResponse response )
{
boolean requiresAuth = super.requiresAuthentication( request, response );
HttpSession httpSession = null;
try
{
httpSession = request.getSession( false );
}
catch ( IllegalStateException ignored )
{
}
if ( httpSession != null )
{
if ( httpSession.getAttribute( Constants.USER ) == null )
{
if ( !requiresAuth )
{
SecurityContext sc = SecurityContextHolder.getContext();
Authentication auth = sc.getAuthentication();
if ( auth != null
&& auth.getPrincipal() instanceof UserDetails )
{
UserDetails ud = (UserDetails) auth.getPrincipal();//上面声明的sql无非就是要包装成这个对象
User user = userManager.getUser( ud.getUsername() );从业务逻辑里找到用户,放到session里
httpSession.setAttribute( Constants.USER, user );
}
}
}
}
return requiresAuth;
}
}
在看看我的login.htm在登陆成功时是怎么工作的吧?
public class UserAction extends BaseAction
{
private UserManager mgr;
public void setUserManager( UserManager mgr )
{
this.mgr = mgr;
}
public ActionForward login( ActionMapping mapping , ActionForm form ,
HttpServletRequest request , HttpServletResponse response )
throws Exception
{
User user = (User) getSessionObject( request, Constants.USER );
ActionMessages msg = new ActionMessages();
if ( user != null )
{
return new ActionForward( user.getType() + ".htm", true );成功就去type.htm
}
else
{
String error = getParameter( request, Constants.ERROR );
if ( error != null )对于不同的错误,都加以提示
{
if ( error.equalsIgnoreCase( "wrong" ) )
msg.add( "msg", new ActionMessage( "fail.login.wrong" ) );
else if ( error.equalsIgnoreCase( "too" ) )
msg.add( "msg", new ActionMessage( "fail.login.too" ) );
else if ( error.equalsIgnoreCase( "fail" ) )
msg.add( "msg", new ActionMessage( "fail.login.fail" ) );
else
msg.add( "msg", new ActionMessage( "fail.login.please" ) );
}
else
msg.add( "msg", new ActionMessage( "fail.login.please" ) );
}
saveErrors( request, msg );
return mapping.findForward( "fail" );
}
}
当然,Acegi需要介绍的东西太多了,我只把我这次认为有必要解释的东西写在了上面让大家来参考,作为能google到的东西,比如对于认证的方式还有很多,我就没有详细的介绍,在学习Acegi过程中,把它自带的例子弄清楚很关键,希望大家一起学习一起共勉!
评论
cavenaghi
2007-09-14
为你而来 写道
呵呵,楼主不错啦!!也许我们这些东西都其他人来说不屑一顾吧,俺刚刚也才经历新手帖的问题
这帮SB,就是互相捧,什么都不是,不现实一点,还把自己弄的跟多神圣似的
为你而来
2007-09-13
呵呵,楼主不错啦!!也许我们这些东西都其他人来说不屑一顾吧,俺刚刚也才经历新手帖的问题
cavenaghi
2007-09-13
houshangjun 写道
,我觉得楼主的文章很不错,我也是看了很久的文章才明白一点acegi的,要是早看了楼主的文章,或许我早就能自己做例子了
谢谢支持,不希望大家都在这里炒写概念,写些真正有实际意义的代码出来,让人理解这些概念......
这就是新手帖!
houshangjun
2007-09-13
,我觉得楼主的文章很不错,我也是看了很久的文章才明白一点acegi的,要是早看了楼主的文章,或许我早就能自己做例子了
cavenaghi
2007-07-05
kafka0102 写道
cavenaghi 写道
JavaEye管理员 1 分钟前 发给你的消息
标题: 您的帖子被评为新手贴
正文:
您的帖子:Spring+Hibernate+Acegi 的初次体验 被JavaEye用户民主投票评为新手贴,减积分10分。发贴前请仔细阅读 JavaEye版规和提问的智慧,如有异议,等待封锁解除后,可以在海阔天空版申诉。
标题: 您的帖子被评为新手贴
正文:
您的帖子:Spring+Hibernate+Acegi 的初次体验 被JavaEye用户民主投票评为新手贴,减积分10分。发贴前请仔细阅读 JavaEye版规和提问的智慧,如有异议,等待封锁解除后,可以在海阔天空版申诉。
今天我也经历了。现在弄明白了,帖子不是随便发的。我发帖的时候,看到java版就发了,没想到下面还有个入门讨论的,原因就是你的帖子太简单了,是入门级的问题。
呵,入门级?
看来我写的这些都是废话啊,谁都会,没有用!呵呵....
kafka0102
2007-07-04
cavenaghi 写道
JavaEye管理员 1 分钟前 发给你的消息
标题: 您的帖子被评为新手贴
正文:
您的帖子:Spring+Hibernate+Acegi 的初次体验 被JavaEye用户民主投票评为新手贴,减积分10分。发贴前请仔细阅读 JavaEye版规和提问的智慧,如有异议,等待封锁解除后,可以在海阔天空版申诉。
标题: 您的帖子被评为新手贴
正文:
您的帖子:Spring+Hibernate+Acegi 的初次体验 被JavaEye用户民主投票评为新手贴,减积分10分。发贴前请仔细阅读 JavaEye版规和提问的智慧,如有异议,等待封锁解除后,可以在海阔天空版申诉。
今天我也经历了。现在弄明白了,帖子不是随便发的。我发帖的时候,看到java版就发了,没想到下面还有个入门讨论的,原因就是你的帖子太简单了,是入门级的问题。
bruce198
2007-07-04
你好,请教个问题好吗
刚开始学习Acegi,看了你的关于Acegi的帖子。我想学习Acegi应该一般都是从 acegi-sample 这个例子开始的吧,但是我这个例子一直跑不起来,弄了一天,在网上查也查不到。所以想请教你一下。这里先谢谢了。
我用的是Jetty,我把acegi-sample 这个例子放在了jetty-6.1.4rc1\webapps 目录下,跑Jetty自带的test是没问题的,可是http://localhost:8080/acegi-sample/index.jsp 对这个请求就出错:
HTTP ERROR: 503
SERVICE_UNAVAILABLE
RequestURI=/acegi-sample/index.jsp
Powered by jetty://
我按照例子的说明已经把下面的包放到了WEB-INF\lib下了。
spring-1.2.4.jar
acegi-security-0.8.3.jar
aopalliance-1.0.jar
c3p0-0.9.0.jar
commons-logging-1.0.4.jar
ehcache-1.1.jar
log4j-1.2.8.jar
mysql-connector-java-3.1.10-bin.jar
oro-2.0.8.jar
请问问题可能出在什么地方啊?可能在你们看来这个很简单,但初学就碰到这问题真的很头疼。
刚开始学习Acegi,看了你的关于Acegi的帖子。我想学习Acegi应该一般都是从 acegi-sample 这个例子开始的吧,但是我这个例子一直跑不起来,弄了一天,在网上查也查不到。所以想请教你一下。这里先谢谢了。
我用的是Jetty,我把acegi-sample 这个例子放在了jetty-6.1.4rc1\webapps 目录下,跑Jetty自带的test是没问题的,可是http://localhost:8080/acegi-sample/index.jsp 对这个请求就出错:
HTTP ERROR: 503
SERVICE_UNAVAILABLE
RequestURI=/acegi-sample/index.jsp
Powered by jetty://
我按照例子的说明已经把下面的包放到了WEB-INF\lib下了。
spring-1.2.4.jar
acegi-security-0.8.3.jar
aopalliance-1.0.jar
c3p0-0.9.0.jar
commons-logging-1.0.4.jar
ehcache-1.1.jar
log4j-1.2.8.jar
mysql-connector-java-3.1.10-bin.jar
oro-2.0.8.jar
请问问题可能出在什么地方啊?可能在你们看来这个很简单,但初学就碰到这问题真的很头疼。
qingzhuang
2007-05-14
看看先
cavenaghi
2007-03-22
测试................
cavenaghi
2007-03-17
谁能给我解释,这句话是什么意思啊?
cavenaghi
2007-03-17
JavaEye管理员 1 分钟前 发给你的消息
标题: 您的帖子被评为新手贴
正文:
您的帖子:Spring+Hibernate+Acegi 的初次体验 被JavaEye用户民主投票评为新手贴,减积分10分。发贴前请仔细阅读 JavaEye版规和提问的智慧,如有异议,等待封锁解除后,可以在海阔天空版申诉。
标题: 您的帖子被评为新手贴
正文:
您的帖子:Spring+Hibernate+Acegi 的初次体验 被JavaEye用户民主投票评为新手贴,减积分10分。发贴前请仔细阅读 JavaEye版规和提问的智慧,如有异议,等待封锁解除后,可以在海阔天空版申诉。
ricsson
2007-03-17
想死我了
生命火花
2007-03-13
我有一个问题想问N久了,Binding的意义到底在哪里?为什么web services要把Binding模块曝露出来!开个贴问不好意思,借楼主的帖子一下
cavenaghi
2007-03-12
忘记编辑了,呵呵,不好意思
xingqing2008
2007-03-12
楼主还是打个包传上来吧.这样看实在麻烦!
simohayha
2007-03-12
楼主,你把你的代码重新 编辑下吧,不然看得脑袋疼。
- 浏览: 9906 次
- 来自: 辽宁抚顺

- 详细资料
搜索本博客
最近加入圈子
最新评论
-
Spring+Hibernate+Acegi ...
为你而来 写道呵呵,楼主不错啦!!也许我们这些东西都其他人来说不屑一顾吧,俺刚刚 ...
-- by cavenaghi -
Spring+Hibernate+Acegi ...
呵呵,楼主不错啦!!也许我们这些东西都其他人来说不屑一顾吧,俺刚刚也才经历新手帖 ...
-- by 为你而来 -
Spring+Hibernate+Acegi ...
houshangjun 写道,我觉得楼主的文章很不错,我也是看了很久的文章才明白 ...
-- by cavenaghi -
Spring+Hibernate+Acegi ...
,我觉得楼主的文章很不错,我也是看了很久的文章才明白一点acegi的,要是早看了 ...
-- by houshangjun -
遇到prototyte一个很怪异 ...
function Test(url) { this.url ...
-- by campaign






评论排行榜