经过若干天断断续续地研究,终于做出了第一个spring security的实例,真是艰难啊,配置太复杂了,若干个Bean之间存在着这样或那样的关系......
下面给出我的小例子,主要是配置文件拉~~别的东西自己看源码吧!
Code
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<!-- 过滤器链配置,其中filterInvocationDefinitionSource属性为配置过滤器的种类与先后顺序,注意,顺序不能配置错误哦 -->
<bean id="filterChainProxy"
class="org.springframework.security.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value><![CDATA[
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionIntegrationFilter,authenticationProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor]]>
</value>
</property>
</bean>
<!-- 看看你是否已经登录了,如果登录了就略过下面的过滤器了,直接访问资源 -->
<bean id="httpSessionIntegrationFilter"
class="org.springframework.security.context.HttpSessionContextIntegrationFilter" />
<!-- 安全验证入口 -->
<bean id="authenticationEntryPoint"
class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="/index.jsp" /><!--默认登录页面-->
<property name="forceHttps" value="true" /><!--使登录页面通过HTTPS安全地进行显示-->
</bean>
<!-- 身份验证过滤器,就是验证身份用的嘛 -->
<bean id="authenticationProcessingFilter"
class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">
<!-- 验证连接名称,对应表单的action -->
<property name="filterProcessesUrl"
value="/j_spring_security_check" />
<!-- 验证失败后去哪 -->
<property name="authenticationFailureUrl"
value="/index.jsp?error=1" />
<!-- 验证成功后去哪 -->
<property name="defaultTargetUrl"
value="/security/security.jsp" />
<!--依靠一个身份验证管理器来验证身份 其实这个才是干活的BEAN-->
<property name="authenticationManager"
ref="authenticationManager" />
</bean>
<!-- 用于处理登录失败异常和权限不足异常 -->
<bean id="exceptionTranslationFilter"
class="org.springframework.security.ui.ExceptionTranslationFilter">
<!--配置出现exception时跳转到登录页-->
<property name="authenticationEntryPoint"
ref="authenticationEntryPoint" />
<!--配置403(权限不足)错误后跳转的页面-->
<property name="accessDeniedHandler" ref="accessDeniedHandler" />
</bean>
<!-- 配置权限不足时跳转到的页面 -->
<bean id="accessDeniedHandler"
class="org.springframework.security.ui.AccessDeniedHandlerImpl">
<property name="errorPage" value="/error.jsp" />
</bean>
<!-- 安全拦截器,下面看看它是干嘛的 -->
<bean id="filterSecurityInterceptor"
class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
<!-- 验证管理者 -->
<property name="authenticationManager"
ref="authenticationManager" />
<!-- 权限决定管理者,他手下的一帮人投票决定登录者是否有权访问该资源 -->
<property name="accessDecisionManager"
ref="accessDecisionManager" />
<!--受保护资源-->
<property name="objectDefinitionSource">
<!-- 下面表示/security/security.jsp需要ROLE_ADMIN权限才能访问 -->
<value><![CDATA[
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/security/security.jsp=ROLE_ADMIN]]>
</value>
</property>
</bean>
<!-- 验证管理者,他管理DAO验证提供者来验证 -->
<bean id="authenticationManager"
class="org.springframework.security.providers.ProviderManager">
<property name="providers">
<list>
<!-- DAO验证提供者,SPRING SECURITY支持各种验证,这里可以添加相应配置 -->
<ref local="daoAuthenticationProvider" />
</list>
</property>
</bean>
<!-- -->
<bean id="accessDecisionManager"
class="org.springframework.security.vote.AffirmativeBased">
<!-- 如果所有投票者都弃权则不让访问 -->
<property name="allowIfAllAbstainDecisions">
<value>false</value>
</property>
<!-- 参加投票的BEAN -->
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.vote.RoleVoter">
<!-- 权限的前缀 -->
<property name="rolePrefix" value="ROLE_" />
</bean>
<bean class="org.springframework.security.vote.AuthenticatedVoter" />
</list>
</property>
</bean>
<!-- DAO验证提供者依靠userDetailsService获得一个userDetails实例,进而验证权限 -->
<bean id="daoAuthenticationProvider"
class="org.springframework.security.providers.dao.DaoAuthenticationProvider">
<!-- jdbcDaoImpl实现了userDetailsService接口 -->
<property name="userDetailsService">
<ref local="jdbcDaoImpl" />
</property>
</bean>
<bean id="jdbcDaoImpl"
class="org.springframework.security.userdetails.jdbc.JdbcDaoImpl">
<!-- 根据用户名获得用户名、密码、用户是否启用等信息 -->
<property name="usersByUsernameQuery">
<value>
select username,password,enabled from user where
username=?
</value>
</property>
<!-- 通过用户名获取用户权限 -->
<property name="authoritiesByUsernameQuery">
<value>
select username,authority from authentication where
username=?
</value>
</property>
<!-- DataSource,不用我说了吧 -->
<property name="dataSource">
<ref local="dataSource" />
</property>
</bean>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"
value="org.gjt.mm.mysql.Driver">
</property>
<property name="url" value="jdbc:mysql://localhost:3306/user">
</property>
<property name="username" value="root"></property>
<property name="password" value="hicc"></property>
</bean>
</beans>
这个是最简单的一个例子,配了141行,呼~~继续研究其深入功能,离成功越来越近了
ps.传说spring security2.0有了超级简单的配置方法,还没有学到手,努力ing
源码下载(需要自己添加spring和mysql的jar包)
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/08/04/1259523.html
posted @
2008-08-04 00:46 破名超难起 阅读(661) |
评论 (0) |
编辑 收藏
你觉得自己是一个Java专家吗?是否肯定自己已经全面掌握了Java的异常处理机制?在下面这段代码中,你能够迅速找出异常处理的六个问题吗?
Code
OutputStreamWriter out =
java.sql.Connection conn =
try { // ⑸
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery(
"select uid, name from user");
while (rs.next())
{
out.println("ID:" + rs.getString("uid") // ⑹
",姓名:" + rs.getString("name"));
}
conn.close(); // ⑶
out.close();
}
catch(Exception ex) // ⑵
{
ex.printStackTrace(); // ⑴,⑷
}
作为一个Java程序员,你至少应该能够找出两个问题。但是,如果你不能找出全部六个问题,请继续阅读本文。
本文讨论的不是Java异常处理的一般性原则,因为这些原则已经被大多数人熟知。我们要做的是分析各种可称为“反例”(anti-pattern)的违背优秀编码规范的常见坏习惯,帮助读者熟悉这些典型的反面例子,从而能够在实际工作中敏锐地察觉和避免这些问题。
反例之一:丢弃异常
代码:15行-18行。
这段代码捕获了异常却不作任何处理,可以算得上Java编程中的杀手。从问题出现的频繁程度和祸害程度来看,它也许可以和C/C++程序的一个恶名远播的问题相提并论——不检查缓冲区是否已满。如果你看到了这种丢弃(而不是抛出)异常的情况,可以百分之九十九地肯定代码存在问题(在极少数情况下,这段代码有存在的理由,但最好加上完整的注释,以免引起别人误解)。
这段代码的错误在于,异常(几乎)总是意味着某些事情不对劲了,或者说至少发生了某些不寻常的事情,我们不应该对程序发出的求救信号保持沉默和无动于衷。调用一下printStackTrace算不上“处理异常”。不错,调用printStackTrace对调试程序有帮助,但程序调试阶段结束之后,printStackTrace就不应再在异常处理模块中担负主要责任了。
丢弃异常的情形非常普遍。打开JDK的ThreadDeath类的文档,可以看到下面这段说明:“特别地,虽然出现ThreadDeath是一种‘正常的情形’,但ThreadDeath类是Error而不是Exception的子类,因为许多应用会捕获所有的Exception然后丢弃它不再理睬。”这段话的意思是,虽然ThreadDeath代表的是一种普通的问题,但鉴于许多应用会试图捕获所有异常然后不予以适当的处理,所以JDK把ThreadDeath定义成了Error的子类,因为Error类代表的是一般的应用不应该去捕获的严重问题。可见,丢弃异常这一坏习惯是如此常见,它甚至已经影响到了Java本身的设计。
那么,应该怎样改正呢?主要有四个选择:
1、处理异常。针对该异常采取一些行动,例如修正问题、提醒某个人或进行其他一些处理,要根据具体的情形确定应该采取的动作。再次说明,调用printStackTrace算不上已经“处理好了异常”。
2、重新抛出异常。处理异常的代码在分析异常之后,认为自己不能处理它,重新抛出异常也不失为一种选择。
3、把该异常转换成另一种异常。大多数情况下,这是指把一个低级的异常转换成应用级的异常(其含义更容易被用户了解的异常)。
4、不要捕获异常。
结论一:既然捕获了异常,就要对它进行适当的处理。不要捕获异常之后又把它丢弃,不予理睬。
反例之二:不指定具体的异常
代码:15行。
许多时候人们会被这样一种“美妙的”想法吸引:用一个catch语句捕获所有的异常。最常见的情形就是使用catch(Exception ex)语句。但实际上,在绝大多数情况下,这种做法不值得提倡。为什么呢?
要理解其原因,我们必须回顾一下catch语句的用途。catch语句表示我们预期会出现某种异常,而且希望能够处理该异常。异常类的作用就是告诉Java编译器我们想要处理的是哪一种异常。由于绝大多数异常都直接或间接从java.lang.Exception派生,catch(Exception ex)就相当于说我们想要处理几乎所有的异常。
再来看看前面的代码例子。我们真正想要捕获的异常是什么呢?最明显的一个是SQLException,这是JDBC操作中常见的异常。另一个可能的异常是IOException,因为它要操作OutputStreamWriter。显然,在同一个catch块中处理这两种截然不同的异常是不合适的。如果用两个catch块分别捕获SQLException和IOException就要好多了。这就是说,catch语句应当尽量指定具体的异常类型,而不应该指定涵盖范围太广的Exception类。
另一方面,除了这两个特定的异常,还有其他许多异常也可能出现。例如,如果由于某种原因,executeQuery返回了null,该怎么办?答案是让它们继续抛出,即不必捕获也不必处理。实际上,我们不能也不应该去捕获可能出现的所有异常,程序的其他地方还有捕获异常的机会——直至最后由JVM处理。
结论二:在catch语句中尽可能指定具体的异常类型,必要时使用多个catch。不要试图处理所有可能出现的异常。
反例之三:占用资源不释放
代码:3行-14行。
异常改变了程序正常的执行流程。这个道理虽然简单,却常常被人们忽视。如果程序用到了文件、Socket、JDBC连接之类的资源,即使遇到了异常,也要正确释放占用的资源。为此,Java提供了一个简化这类操作的关键词finally。
finally是样好东西:不管是否出现了异常,Finally保证在try/catch/finally块结束之前,执行清理任务的代码总是有机会执行。遗憾的是有些人却不习惯使用finally。
当然,编写finally块应当多加小心,特别是要注意在finally块之内抛出的异常——这是执行清理任务的最后机会,尽量不要再有难以处理的错误。
结论三:保证所有资源都被正确释放。充分运用finally关键词。
反例之四:不说明异常的详细信息
代码:3行-18行。
仔细观察这段代码:如果循环内部出现了异常,会发生什么事情?我们可以得到足够的信息判断循环内部出错的原因吗?不能。我们只能知道当前正在处理的类发生了某种错误,但却不能获得任何信息判断导致当前错误的原因。
printStackTrace的堆栈跟踪功能显示出程序运行到当前类的执行流程,但只提供了一些最基本的信息,未能说明实际导致错误的原因,同时也不易解读。
因此,在出现异常时,最好能够提供一些文字信息,例如当前正在执行的类、方法和其他状态信息,包括以一种更适合阅读的方式整理和组织printStackTrace提供的信息。
结论四:在异常处理模块中提供适量的错误原因信息,组织错误信息使其易于理解和阅读。
反例之五:过于庞大的try块
代码:3行-14行。
经常可以看到有人把大量的代码放入单个try块,实际上这不是好习惯。这种现象之所以常见,原因就在于有些人图省事,不愿花时间分析一大块代码中哪几行代码会抛出异常、异常的具体类型是什么。把大量的语句装入单个巨大的try块就象是出门旅游时把所有日常用品塞入一个大箱子,虽然东西是带上了,但要找出来可不容易。
一些新手常常把大量的代码放入单个try块,然后再在catch语句中声明Exception,而不是分离各个可能出现异常的段落并分别捕获其异常。这种做法为分析程序抛出异常的原因带来了困难,因为一大段代码中有太多的地方可能抛出Exception。
结论五:尽量减小try块的体积。
反例之六:输出数据不完整
代码:7行-11行。
不完整的数据是Java程序的隐形杀手。仔细观察这段代码,考虑一下如果循环的中间抛出了异常,会发生什么事情。循环的执行当然是要被打断的,其次,catch块会执行——就这些,再也没有其他动作了。已经输出的数据怎么办?使用这些数据的人或设备将收到一份不完整的(因而也是错误的)数据,却得不到任何有关这份数据是否完整的提示。对于有些系统来说,数据不完整可能比系统停止运行带来更大的损失。
较为理想的处置办法是向输出设备写一些信息,声明数据的不完整性;另一种可能有效的办法是,先缓冲要输出的数据,准备好全部数据之后再一次性输出。
结论六:全面考虑可能出现的异常以及这些异常对执行流程的影响。
改写后的代码
根据上面的讨论,下面给出改写后的代码。也许有人会说它稍微有点啰嗦,但是它有了比较完备的异常处理机制。
Code
OutputStreamWriter out =
java.sql.Connection conn =
try {
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("select uid, name from user");
while (rs.next())
{
out.println("ID:" + rs.getString("uid") + ",姓名: " + rs.getString("name"));
}
}
catch(SQLException sqlex)
{
out.println("警告:数据不完整");
throw new ApplicationException("读取数据时出现SQL错误", sqlex);
}
catch(IOException ioex)
{
throw new ApplicationException("写入数据时出现IO错误", ioex);
}
finally
{
if (conn != null) {
try {
conn.close();
}
catch(SQLException sqlex2)
{
System.err(this.getClass().getName() + ".mymethod - 不能关闭数据库连接: " + sqlex2.toString());
}
}
if (out != null) {
try {
out.close();
}
catch(IOException ioex2)
{
System.err(this.getClass().getName() + ".mymethod - 不能关闭输出文件" + ioex2.toString());
}
}
}
本文的结论不是放之四海皆准的教条,有时常识和经验才是最好的老师。如果你对自己的做法没有百分之百的信心,务必加上详细、全面的注释。
一方面,不要笑话这些错误,不妨问问你自己是否真地彻底摆脱了这些坏习惯。即使最有经验的程序员偶尔也会误入歧途,原因很简单,因为它们确确实实带来了“方便”。所有这些反例都可以看作Java编程世界的恶魔,它们美丽动人,无孔不入,时刻诱惑着你。也许有人会认为这些都属于鸡皮蒜毛的小事,不足挂齿,但请记住:勿以恶小而为之,勿以善小而不为。
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/08/01/1258247.html
posted @
2008-08-01 15:57 破名超难起 阅读(77) |
评论 (0) |
编辑 收藏
请求有效性处理,使用令牌可以有效的防止重复提交。
protected String generateToken(HttpServletRequest request) 创建一个令牌.
protected boolean isTokenValid(HttpServletRequest request) 检查令牌是否有效
protected boolean isTokenValid(HttpServletRequest request,Boolean reset) 检查令牌是否有效,并且重置令牌(如果reset 是true)
protected void resetToken(HttpServletRequest request) 重置令牌
protected void saveToken(HttpServletRequest request) 添加令牌
基本原理:
服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,
看是否匹配。在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给
客户端以外,也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次
提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。
实例:
Code
/*
* Generated by MyEclipse Struts
* Template path: templates/java/JavaClass.vtl
*/
package com.yourcompany.struts.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
/**
* MyEclipse Struts
* Creation date: 08-01-2008
*
* XDoclet definition:
* @struts.action validate="true"
* @struts.action-forward name="add" path="/add.jsp"
*/
public class ToAddAction extends Action {
/*
* Generated Methods
*/
/**
* Method execute
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
// TODO Auto-generated method stub
saveToken(request);
return mapping.findForward("add");
}
}
这个Action主要作用就是在跳转的页面上加入Token,只有加入Token才能实现Token的验证。执行完这个Action后,跳转到的页面会出现类似如下的一个hidden控件
Code
<div><input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="b030d9188a218097211d9061907cde5d"></div>
那么恭喜你,Token生效拉,注意,跳转到的页面里面,表单指可以用Struts标签来生成,不可以用HTML来生成,不然Token是无效的。
使用Token的第一步完成,第二步,在提交的Action中验证Token是否符合,代码如下:
Code
/*
* Generated by MyEclipse Struts
* Template path: templates/java/JavaClass.vtl
*/
package com.yourcompany.struts.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import com.lc.sqlhelp.Access;
import com.yourcompany.struts.form.AddForm;
/**
* MyEclipse Struts Creation date: 08-01-2008
*
* XDoclet definition:
*
* @struts.action path="/add" name="addForm" input="/form/add.jsp"
* scope="request" validate="true"
* @struts.action-forward name="add_suc" path="/add_suc.jsp"
* @struts.action-forward name="add_fail" path="/add_fail.jsp"
*/
public class AddAction extends Action {
/*
* Generated Methods
*/
/**
* Method execute
*
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
AddForm af = (AddForm) form;
if (isTokenValid(request, true))//验证Token是否符合要求
{
String sql = "insert into user (username,password) values('"
+ af.getUsername() + "','" + af.getPassword() + "')";
System.out.println(sql);
Access sh = new Access();
sh.loadMyDriver();
sh.setMyConnection();
sh.createMyStatement();
sh.executeMyUpdata(sql);
sh.closeMyStatement();
sh.closeMyConnection();
return mapping.findForward("add_suc");
}
return mapping.getInputForward();
}
}
这样就完成了防止表单重复提交的功能。
实例源码下载
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/08/01/1258067.html
posted @
2008-08-01 12:07 破名超难起 阅读(109) |
评论 (0) |
编辑 收藏
在用户登录输入密码时,常常会有因为大写锁定开启而造成输入密码错误的情况,如果在用户大写锁定开启时给予提示,就可以尽量避免这种情况的发生。
一下是代码:
Code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>检测大写锁定键</title>
<style type="text/css">
<!--
*{margin:0;padding:0;}
body{padding:2em;background:#242424;color:#ccc;}
h1{text-align:center;line-height:200%;}
h3{text-indent:1em;line-height:160%;color:#666;font-weight:normal;font-size:1em;}
h3 a{color:#bbb; text-decoration:none;margin:0 0.5em;}
h3 a:hover{color:#fff;}
p{margin:5em;}
span{margin:0 0.5em;font-size:85.7%;}
-->
</style>
</head>
<body>
<h1>检测大写锁定键 </h1>
<form action="#" method="post">
<p><label for="password">密码:</label><input type="password" id="password" name="password" /><span style="display:none;">大写锁定键被按下,请注意大小写</span></p>
</form>
<script type="text/javascript">
//<![CDATA[
function detectCapsLock(event){
var e = event||window.event;
var o = e.target||e.srcElement;
var oTip = o.nextSibling;
var keyCode = e.keyCode||e.which; // 按键的keyCode
var isShift = e.shiftKey ||(keyCode == 16 ) || false ; // shift键是否按住
if (
((keyCode >= 65 && keyCode <= 90 ) && !isShift) // Caps Lock 打开,且没有按住shift键
|| ((keyCode >= 97 && keyCode <= 122 ) && isShift)// Caps Lock 打开,且按住shift键
){oTip.style.display = '';}
else{oTip.style.display = 'none';}
}
document.getElementById('password').onkeypress = detectCapsLock;
//]]>
</script>
</body>
</html>
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/07/31/1257624.html
posted @
2008-07-31 21:18 破名超难起 阅读(243) |
评论 (0) |
编辑 收藏
摘要: 前一段时间朱哥一直在搞视频转换这个东东,我也一直很有兴趣,就尝试了一下。
首先是文件上传功能的完成,做得很粗糙,没有验证上传文件是否为视频文件。利用前一段时间看视频学来的部分代码很轻松搞定。
接下来,就是视频转换了,...
阅读全文
posted @
2008-07-31 16:41 破名超难起 阅读(142) |
评论 (0) |
编辑 收藏
使用ffmpeg转换视频为flv文件:
./ffmpeg -i "/opt/input/1.mpg" -y -ab 32 -ar 22050 -b 800000 -s 640*480 /opt/output/1.flv"
ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)
对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等),
可以先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式.
./mencoder /input/a.rmvb -oac lavc -lavcopts acodec=mp3:abitrate=64 -ovc xvid -xvidencopts bitrate=600 -of avi -o /output/a.avi
在执行./ffmpeg -i "/opt/input/a.avi" -y -ab 32 -ar 22050 -b 800000 -s 640*480 /opt/output/a.flv"就可以转了。
视频抓图:
./ffmpeg -i "/opt/input/a.flv" -y -f image2 -t 1 -s 300*200 "/opt/output/1.jpg" //获取静态图
./ffmpeg -i "/opt/input/a.mpg" -vframes 30 -y -f gif "/output/1.gif" //获取动态图;
不提倡抓gif文件;因为抓出的gif文件大而播放不流畅。
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/07/30/1256896.html
posted @
2008-07-30 23:59 破名超难起 阅读(186) |
评论 (0) |
编辑 收藏
下午搞了一下Struts处理异常的框架,不错,确实很好用,可以省很多事,闲话暂且不表,进入正题
首先新建一个项目,然后要做的第一步当然是——添加Struts支持啦~~呵呵。
找到struts-config.xml文件,如果想配置全局异常处理,则需要在<global-exceptions></global-exceptions>之间设置,如果只想单独为某个Action设置其异常处理,则将设置写在<action></action>之间即可,具体配置很简单,代码如下:
Code
<exception
key="unLogin"<!--对应资源文件中的key,用于错误显示-->
path="/index.jsp"<!--出错了程序会跳到哪里去.-->
type="java.lang.Exception" <!--捕获异常的类型-->/>
接下来测试一下吧,写一个登陆页面,提交到某个action里面,当用户名为空时抛出Exception,当然你也可以编写自己的Exception类,然后在配置文件中作相应的修改就可以了。
index.jsp代码如下:
Code
<%@ page language="java" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>
<%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html:html lang="true">
<head>
<html:base />
<title>index.jsp</title>
</head>
<body><html:errors/>
<html:form action="/login" method="post" focus="login">
<table border="0">
<tr>
<td>Login:</td>
<td><html:text property="username" /></td>
</tr>
<tr>
<td>Password:</td>
<td><html:password property="password" /></td>
</tr>
<tr>
<td colspan="2" align="center"><html:submit /></td>
</tr>
</table>
</html:form>
</body>
</html:html>
loginAction代码如下:
Code
/*
* Generated by MyEclipse Struts
* Template path: templates/java/JavaClass.vtl
*/
package com.lc.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import com.lc.LoginForm;
/**
* MyEclipse Struts
* Creation date: 07-30-2008
*
* XDoclet definition:
* @struts.action path="/login" name="loginForm" input="/form/login.jsp" scope="request" validate="true"
* @struts.action-exception key="unLogin" path="/index.jsp"
*/
public class LoginAction extends Action {
/*
* Generated Methods
*/
/**
* Method execute
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
* @throws Exception
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception {
LoginForm loginForm = (LoginForm) form;// TODO Auto-generated method stub
if(loginForm.getUsername()==null||loginForm.getUsername().equals("")){
throw new Exception();
}
return mapping.findForward("login");
}
}
接下来测试一下吧,异常被捕获了,login.do被重定向到了index.jsp中去,测试结束。
虽然这是一个很小的例子,但是足以感觉到运用到实际中可以省很多事,项目中异常的处理不再需要无数个try/catch块组合,只需要在xml文件中进行简单设置即可。
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/07/30/1256650.html
posted @
2008-07-30 17:15 破名超难起 阅读(96) |
评论 (0) |
编辑 收藏
1. 用代理,通过这个地址访问:
http://www.mirrorservice.org/sites/download.sourceforge.net/pub/sourceforge/c/cr/
2. 用FTP
http://www.cnblogs.com/xiaoao808/admin/ftp://ftp.jaist.ac.jp/pub/sourceforge/
http://www.cnblogs.com/xiaoao808/admin/ftp://sourceforge.nchc.org.tw/
http://mirror.optus.net/sourceforge/
访问如上URL地址,这是一个sourceforge的下载镜像站点,按照字母顺序分目录列出来sourceforge上面所有的软件下载了,我们可以按目录一级一级找到自己要下载的软件。
如:要下载Hibernate,那么寻找 /h/hi/hibernate 目录就找到了,该目录下面是所有Hibernate相关软件各个版本的下载地址:
http://mirror.optus.net/sourceforge/h/hi/hibernate/
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/07/22/1248527.html
posted @
2008-07-22 10:53 破名超难起 阅读(196) |
评论 (0) |
编辑 收藏
Acegi配置总结
1、 在web.xml中配置contextConfigLocation,并且配置acegi filter chain即过滤器链
例如:
<!—配置过滤器链-->
<filter>
<filter-name>Acegi Filter Chain Proxy</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>Acegi Filter Chain Proxy</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--将事物提交给web applicationContext-->
<listener>
<listener-class>org.acegisecurity.ui.session.HttpSessionEventPublisher</listener-class>
</listener>
2、在applicationContext-acegi.xml中配置
1-配置过滤器链
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
<!--配置过滤器链的内容及其执行顺序-->
<property name="filterInvocationDefinitionSource">
<value><![CDATA[
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,basicProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,switchUserProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
]]></value>
</property>
</bean>
另外,从某论坛上看到,如果配置文件中出现<>""等字符时除了可以用html符号外还可以用<![CDATA[ ]]> 来包含配置信息
2-
<!--最先要配置的过滤器,用于提供安全上下文实例-->
<bean id="httpSessionContextIntegrationFilter"
class="org.acegisecurity.context.HttpSessionContextIntegrationFilter" />
3-
<!-- 登出过滤器 -->
<bean id="logoutFilter"
class="org.acegisecurity.ui.logout.LogoutFilter">
<constructor-arg value="/logoutSuccess.jsp" />
<constructor-arg>
<list>
<bean
class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler" />
</list>
</constructor-arg>
</bean>
4-
<!-- 登陆验证过滤器 -->
<bean id="authenticationProcessingFilter"
class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<!-- 验证管理器 -->
<property name="authenticationManager"
ref="authenticationManager" />
<!-- 验证失败后跳转到的页面 -->
<property name="authenticationFailureUrl"
value="/login.jsp?login_error=1" />
<!--登陆成功时跳转到的页面-->
<property name="defaultTargetUrl"
value="/index.jsp"/>
<property name="filterProcessesUrl"
value="/j_acegi_security_check" />
</bean>
5-
<!--配置验证管理器-->
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
<property name="providers"><!--提供者属性-->
<list><!--配置其依赖的DAO-->
<ref local="daoAuthenticationProvider"/><!--基于数据库提供验证-->
<ref local="PasswordDaoAuthenticationProvider"/><!--基于数据库提供验证,但让底层的数据源完成实际的身份验证。-->
<ref local="anonymousAuthenticationProvider"/><!--匿名验证-->
<ref local="rememberMeAuthenticationProvider"/><!--再次登陆时从缓存中验证-->
</list>
</property>
</bean>
6-
<!--数据提供者-->
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService"><ref local="jdbcDaoImpl"/></property>
<property name="userCache"><ref local="userCache"/></property><!-- 用户缓存,可选 -->
<property name="passwordEncoder"><ref local="passwordEncoder"/></property><!--密码加密,可选-->
</bean>
7
<!--配置用户缓存,可选-->
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
<bean id="userCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager">
<ref local="cacheManager"/>
</property>
<property name="cacheName">
<value>userCache</value>
</property>
</bean>
<bean id="userCache" class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
<property name="cache"><ref local="userCacheBackend"/></property>
</bean>
8-
<--密码加密,可选,共3种方式-->
<bean id="passwordEncoder" class="org.acegisecurity.providers.encoding.PlaintextPasswordEncoder"/><!--不加密,默认-->
<bean id="passwordEncoder" class="org.acegisecurity.providers.encoding.Md5PasswordEncoder"/><!--MD5加密-->
<bean id="passwordEncoder" class="org.acegisecurity.providers.encoding.SHAPasswordEncoder"/><--SHA加密-->
9-
<!--配置jdbcDaoImpl-->
<bean id="jdbcDaoImpl" class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource"><ref bean="dataSource"/></property>
</bean>
10-配置DateSource
DateSource自己会配置吧~~那啥,我就不说了
本贴个人原创,如有不正确之处,请指正......
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/07/18/1246286.html
posted @
2008-07-18 18:39 破名超难起 阅读(75) |
评论 (0) |
编辑 收藏
摘要: Acegi 的配置看起来非常复杂,但事实上在实际项目的安全应用中我们并不需要那么多功能,清楚的了解Acegi配置中各项的功能,有助于我们灵活的运用Acegi于实践中。
2.1 在Web.xml中的配置
1) FilterToBeanProxy
Acegi通过实现了Filter接口的FilterToBeanProxy提供一种特殊的使用Servlet Filter的方式,它委托S...
阅读全文
posted @
2008-07-17 00:42 破名超难起 阅读(66) |
评论 (0) |
编辑 收藏