Shenzhen Hiblue Software
hiQblue.co?/span>
H i b l u e S o f t w a r e
???????开 ?????/span>
S h e n z h e n H i b l u e
??????所 ?/span>
Q??Q?Q????Q?Q???/span>
?/strong> 对于一个典型的Web应用Q完善的认证和授权机制是必不可少的,在SpringFramework中,Juergen Hoeller提供的范例JPetStorel了一些这斚w的介l,但还q远不够QAcegi是一个专门ؓSpringFramework提供安全机制的项目,全称为Acegi Security System for SpringQ当前版本ؓ0.5.1Q就其目前提供的功能Q应该可以满绝大多数应用的需求?/p> 本文的主要目的是希望能够说明如何在基于Spring构架的Web应用中用AcegiQ而不是详l介l其中的每个接口、每个类。注意,即对已l存在的Spring应用Q通过下面介绍的步骤,也可以马上n受到Acegi提供的认证和授权?/p> 基础工作 在你的Web应用的lib中添加Acegi下蝲包中的acegi-security.jar web.xml 实现认证和授权的最常用的方法是通过filterQAcegi亦是如此Q通常Acegi需要在web.xmld以下5个filterQ?/p>
最先引赯惑的是net.sf.acegisecurity.util.FilterToBeanProxyQAcegi自己的文上解释是:“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.”,如希望深I的话,ȝ看源代码应该不难理解?/p> 再下来就是添加filter-mapping了:
q里Q需要注意以下三点: 1) q几个filter的顺序是不能更改的,序不对无法正常工作; 2) 如果你的应用不需要安全传输,如httpsQ则?Acegi Channel Processing Filter"相关内容注释掉即可; 3) 如果你的应用不需要Spring提供的远E访问机Ӟ如Hessian and BurlapQ将"Acegi HTTP BASIC Authorization Filter"相关内容注释掉即可?p>#p# applicationContext.xml 接下来就是要dapplicationContext.xml中的内容了,从刚才FilterToBeanFactory的解释可以看出,真正的filter都在Spring的applicationContext中管理: 1)首先Q你的数据库中必d有保存用户名和密码的tableQAcegi要求table的schema必须如下Q?/p>
2)d讉K你的数据库的datasource和Acegi的jdbcDaoQ如下:
3)dDaoAuthenticationProviderQ?/p>
如果你需要对密码加密Q则在daoAuthenticationProvider中加入:<property name="passwordEncoder"><ref bean="passwordEncoder"/></property>QAcegi提供了几U加密方法,详细情况可看包net.sf.acegisecurity.providers.encoding 4)dauthenticationManagerQ?/p>
5)daccessDecisionManagerQ?/p>
6)dauthenticationProcessingFilterEntryPointQ?/p>
其中acegilogin.jsp是登陆页面,一个最单的d面如下Q?/p>
7)dfilterInvocationInterceptorQ?/p>
q里h意,要objectDefinitionSource中定义哪些页面需要权限访问,需要根据自q应用需求进行修改,我上面给出的定义的意思是q样的: #p# a. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON意思是在比较请求\径时全部转换为小?span class="Apple-converted-space"> 8)dsecurityEnforcementFilterQ?/p>
9)dauthenticationProcessingFilterQ?/p>
其中authenticationFailureUrl是认证失败的面?/p> 10)如果需要一些页面通过安全通道的话Q添加下面的配置Q?/p>
~少了什么? Acegi目前提供了两U“secure object”,分别寚w面和Ҏq行安全认证理Q我q里介绍的只是利用FilterSecurityInterceptor对访问页面的权限控制Q除此之外,Acegiq提供了另外一个Interceptor——MethodSecurityInterceptorQ它l合runAsManager可实现对对象中的Ҏ的权限控Ӟ使用Ҏ可参看Acegi自带的文和contact范例?/p> 最后要说的 本来以ؓ只是说明如何使用Acegi而已Q应该非常简单,但真正写h才发现想要条理清楚的理顺所有需要的beanq是很困隄Q但愿我没有遗漏太多东西Q如果我的文章有什么遗漏或错误的话Q还请参看Acegi自带的quick-start范例Q但h意,q个范例是不能直接拿来用的?/p> |
prototype.js常用函数及其用法
|
prototype.js常用函数:
基本用法:prototype.jsl每个主要的c都分了一个Class,使用h很方?要生特定的效果,只要用new Class.function(<argument>)可以了.例如: <DIV id="div1"><a href="#" onclick="new Element.toggle('div2')">Click Me</a></DIV> 当点击Click Me的时?div2׃交替隐藏或显C?注意,你可以给toggle加上无限个parameter,比如Element.toggle(''div2'',''div3'',''div4'',...) |
本周,我回{了两个使用Javaq行数据压羃的问? W一个问题是: 我怎样才能压羃那些不在文g中的数据. W二个问题是: 我以极大的热情阅MTodd Sundsted?压羃你的数据,从而提高你的网l应用程序的性能",但是d后我却有点失?当我d文章标题时我很高?我想我ȝ扑ֈ了解决问题的办法? 在我们的公司,我们试图提高一个组l数据的RMI应用E序的性能.服务器端q行了绝大部分的处理和优?我们׃一q半的时间去提高性能,但是现在看来瓉在于数据的传输上.在一天的M旉?我们都有可能在客户和服务器之间传送成千上万的数据. 一U可能的解决办法,我徏议我们能够在把数据返回给客户端时先压~这些数?q在Todd的文章中已经说得很清楚了.但是,文章中的例子却是压羃文g,而不是我们所需要的----Ҏ据进行压~? 在RMI中的实现?我们先从数据库取得数?再把数据攑օ一个列表中,接着把这个列表返回给客户?最后再把它们插入JTable?我想在把数据q回l客h,首先把列表中的数据压~?然后在客L解压~?最后把数据插入到表g. q样的想法可行吗? A:最q我收到了一些关于Todd的文章的疑问.很多读者看hҎ章中的D例很疑惑.因ؓ文章中的例子是以文g压羃为核心的. 首先回答W一个问?当你使用ZipInputStream ?nbsp;ZipOutputStream q没有强制你必须使用文g.唯一要注意的是你必须把数据{换ؓ字节数组的Ş? W二个问题比较棘?在网l中,以RMI方式通信需要作一些调整了.Z在传送数据之前就让RMIq行数据压羃,你必dZ个能够压~数据的新的套接?然后,当你创徏了一个套接字?你得告诉RMI使用q一套接? 以下是创Z个RMI形式的套接字的简要步? 1:选择或者创Z个新的套接字.(可以参看SUN'S?创徏一个典型的套接?). 2:创徏一个服务器端的套接? 3:创徏一个RMIClientSocketFactory 4:创徏一个RMIServerSocketFactory 5:创徏一个承了UnicastRemoteObjec的远E对?从而用新的factories. Ҏq一大致的想?我们来看每一步如何具体的实现. 步骤1: 创徏ZipSocket ׃要进行Zip压羃,我们重新创徏q样的套接字 mport java.io.InputStream; import java.io.OutputStream; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; import java.net.Socket; public class ZipSocket extends Socket { private InputStream in; private OutputStream out; public ZipSocket() { super(); } public ZipSocket(String host, int port) throws IOException { super(host, port); } public InputStream getInputStream() throws IOException { if (in == null) { in = new ZipInputStream(super.getInputStream()); } return in; } public OutputStream getOutputStream() throws IOException { if (out == null) { out = new ZipOutputStream(super.getOutputStream()); } return out; } public synchronized void close() throws IOException { OutputStream o = getOutputStream(); o.flush(); super.close(); } } 步骤2: 创徏ZipServerSocket import java.net.ServerSocket; import java.net.Socket; import java.io.IOException; public class ZipServerSocket extends ServerSocket { public ZipServerSocket(int port) throws IOException { super(port); } public Socket accept() throws IOException { Socket socket = new ZipSocket(); implAccept(socket); return socket; } } 步骤3:创徏ZipClientSocketFactory 客户端的factory的创建必遵循以下的形式: import java.io.IOException; import java.io.Serializable; import java.net.Socket; import java.rmi.server.RMIClientSocketFactory; public class ZipClientSocketFactory implements RMIClientSocketFactory, Serializable { public Socket createSocket(String host, int port) throws IOException { ZipSocket socket = new ZipSocket(host, port); return socket; } } 步骤4:创徏ZipServerSocketFactory import java.io.IOException; import java.io.Serializable; import java.net.ServerSocket; import java.rmi.server.RMIServerSocketFactory; public class ZipServerSocketFactory implements RMIServerSocketFactory, Serializable { public ServerSocket createServerSocket(int port) throws IOException { ZipServerSocket server = new ZipServerSocket(port); return server; } } 步骤5: 创徏一个承了UnicastRemoteObjec的远E对?从而用新的factories. public class YourRMIObject extends UnicastRemoteObject { public YourRemoteObject( int port ) { super( port, new ZipClientSocketFactory(), new ZipServerSocketFactory() ); } // 剩下的是你自qE序实现 } 现在你的通信数据得到了压~? 关于作? Tony Sintes 是一个独立咨询h,同时也是First Class Consulting, Inc. 的创始h.q一咨询公司主要致力与对各个不同的企业系l进行量w定制和培训 . 业余旉,Tony 是一个积极的自由作家,同时也是Sams出版?lt;<21天学通面向对象编E?gt;>的作?nbsp;(Sams, 2001; ISBN: 0672321092). |
与我聊天?INPUT id=hiden type=hidden value=ok name=hiden> |
java.sql.DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); //装蝲JDBC驱动E序
conn = java.sql.DriverManager.getConnection("jdbc:oracle:thin:@192.168.1.2:1521:lqxm","lqxm","lqxm"); //q接数据?/P>
request.setCharacterEncoding("GBK");
String title = request.getParameter("title");
String content = request.getParameter("content");
String sort = request.getParameter("sort");
String type = request.getParameter("type");
String rq = request.getParameter("rq");
String qy = request.getParameter("qy");
//插入数据,此时blob字段中插入的是空?BR>sql="insert into t_flfg (xlh,title,content,rq,sort,type,qy) ";
sql=sql+"Values(FLFG_SEQ.NEXTVAL,'" + title + "',empty_clob(),'" + rq + "','" + sort + "','" + type + "','" + qy + "')";
stmt=conn.createStatement();
stmt.executeUpdate(sql);
conn.commit();
conn.setAutoCommit(false);
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENS99vIVE,ResultSet.CONCUR_UPDATABLE);
//取得刚才插入的ID
sql="select max(xlh) as xlh from t_flfg ";
rs=stmt.executeQuery(sql);
if(rs.next()) {
id=rs.getInt("xlh");
}
rs.close();
sql = "select content from t_flfg where xlh="+id+" for update";
rs = stmt.executeQuery(sql);
if (rs.next()) {
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob(1);
clob.putString(1, content);
sql = "update t_flfg set content=? where xlh=" + id + ""; //大文本更新q去Q呵?BR>PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setClob(1, clob);
pstmt.executeUpdate();
}
conn.commit();
stmt.close();
conn.close();
%>
二、检索显C数据:
<%
ResultSet rs = flfgSave.searchOneInfo(request.getParameter("xlh")); //查询数据库获取记录集
rs.next();
int y;
String content = "";
oracle.sql.CLOB clob1;
char ac[] = new char[299];
String title = rs.getString("title");
clob1 = (oracle.sql.CLOB)rs.getObject("content");
Reader reader = clob1.getCharacterStream();
while((y = reader.read(ac, 0, 299)) != -1)
content += new String(ac, 0, y); //q就是取出来的大文本
%>