每日一得

不求多得,只求一得 about java,hibernate,spring,design,database,Ror,ruby,快速开发
最近关心的内容:SSH,seam,flex,敏捷,TDD
本站的官方站点是:颠覆软件

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  220 随笔 :: 9 文章 :: 421 评论 :: 0 Trackbacks

#

Q1.怎样创建表?
A. CREATE TABLE ROYAL_MTABLE
(
RM_INT_FIELD INTEGER,
RM_STR_FIELD VARCHAR2(64)
)
CREATE TABLE ROYAL_DTABLE
(
RD_INT_FIELD INTEGER,
RD_STR_FIELD VARCHAR2(32)
)
Q2.怎样删除表?
A. DROP TABLE ROYAL_DTABLE;
Q3.怎样创建视图?
A. CREATE OR REPLACE VIEW ROYAL_MDVIEW AS
SELECT T1.RM_STR_FIELD AS F1, T2.RD_STR_FIELD AS F2 FROM ROYAL_MTABLE T1, ROYAL_DTABLE T2
WHERE T1.RM_INT_FIELD = T2.RM_INT_FIELD
Q4.怎样删除视图?
A. DROP VIEW ROYAL_MDVIEW;
Q5.怎样给表添加字段?
A. ALTER TABLE ROYAL_DTABLE ADD RM_INT_FIELD INTEGER;
Q6.怎样删除表中某个字段?
A. ALTER TABLE ROYAL_DTABLE DROP COLUMN RM_INT_FIELD;
Q7.怎样给某个字段添加约束?
A. ALTER TABLE ROYAL_MTABLE MODIFY RM_STR_FIELD NOT NULL;
Q8.怎样去除某个字段上的约束?
A. ALTER TABLE ROYAL_MTABLE MODIFY RM_STR_FIELD NULL;
Q9.怎样给表加上主键?
A. ALTER TABLE ROYAL_MTABLE ADD CONSTRAINT PK_ROYAL_MTABLE PRIMARY KEY (RM_INT_FIELD);
Q10.怎样删除表的主键?
A. ALTER TABLE ROYAL_MTABLE DROP CONSTRAINT PK_ROYAL_MTABLE CASCADE;
Q11.怎样给表添加一个外键?
A. ALTER TABLE ROYAL_DTABLE ADD CONSTRAINT FK_ROYAL_DTABLE FOREIGN KEY (RM_INT_FIELD) REFERENCES ROYAL_MTABLE (RM_INT_FIELD) ON DELETE CASCADE;
Q12.怎样删除表的一个外键?
A. ALTER TABLE ROYAL_DTABLE DROP CONSTRAINT FK_ROYAL_DTABLE;
Q13.怎样给字段加上CHECK?
A. ALTER TABLE ROYAL_MTABLE ADD CONSTRAINT CHK_RM_STR_FIELD CHECK (RM_STR_FIELD IN ('Y','N'));
Q14.怎样去掉字段上的CHECK?
A. ALTER TABLE ROYAL_MTABLE DROP CONSTRAINT CHK_RM_STR_FIELD;
Q15.怎样给字段设置默认值?
A. ALTER TABLE ROYAL_DTABLE MODIFY RD_STR_FIELD DEFAULT 'ROYAL';
Q16.怎样移去字段的默认值?
A. ALTER TABLE ROYAL_DTABLE MODIFY RD_STR_FIELD DEFAULT NULL;
Q17.怎样创建索引?
A. CREATE UNIQUE INDEX IDX_ROYAL_DTABLE ON ROYAL_DTABLE (RM_INT_FIELD);
Q18.怎样删除索引?
A. DROP INDEX IDX_ROYAL_DTABLE;
Q19.怎样创建用户?
A. CREATE USER TESTUSER IDENTIFIED EXTERNALLY DEFAULT TABLESPACE USERS TEMPORARY TABLESPACE TEMP PROFILE DEFAULT;
Q20.怎样删除用户?
A. DROP USER TESTUSER CASCADE;
21.怎样将对象权限(object privileges)授予用户?
A. GRANT SELECT, INSERT, UPDATE, DELETE, ALTER ON ROYAL_MTABLE TO TESTUSER;
GRANT INSERT, UPDATE, DELETE ON ROYAL_DTABLE TO TESTUSER;
GRANT SELECT, ALTER ON ROYAL_DTABLE TO TESTUSER WITH GRANT OPTION;
Q22.怎样从用户收回对象权限?
A. REVOKE SELECT, INSERT, UPDATE, DELETE, ALTER ON ROYAL_DTABLE FROM TESTUSER;
Q23.怎样将角色权限(role privileges)授予用户?
A. GRANT CONNECT TO TESTUSER WITH ADMIN OPTION;
GRANT DBA TO TESTUSER;
Q24.怎样从用户收回角色权限?
A. REVOKE DBA FROM TESTUSER;
Q25.怎样将系统权限(system privileges)授予用户?
A. GRANT ALTER ANY TABLE TO TESTUSER WITH ADMIN OPTION;
Q26.怎样从用户收回系统权限?
A. REVOKE ALTER ANY TABLE FROM TESTUSER;
Q27.怎样创建序列?
A. CREATE SEQUENCE RM_INT_FIELD_SEQ
MINvalue 1
MAXvalue 999999999999999999999999999
START WITH 1
INCREMENT BY 1
CACHE 10
ORDER;
Q28.怎样删除序列?
A. DROP SEQUENCE RM_INT_FIELD_SEQ;
Q29.怎样获取序列值?
A. SELECT RM_INT_FIELD_SEQ.NEXTVAL FROM DUAL;
Q30.怎样创建角色?
A. CREATE ROLE TESTROLE;
Q31.怎样删除角色?
A. DROP ROLE TESTROLE;
Q32.怎样将对象权限(object privileges)授予角色?
A. GRANT SELECT, INSERT, UPDATE, DELETE, ALTER ON ROYAL_MTABLE TO TESTROLE;
Q33.怎样从角色收回对象权限?
A. REVOKE SELECT, INSERT, UPDATE, DELETE, ALTER ON ROYAL_MTABLE FROM TESTROLE;
Q34.怎样将角色权限(role privileges)授予角色?
A. GRANT DBA TO TESTROLE;
Q35.怎样从角色收回角色权限?
A. REVOKE DBA FROM TESTROLE;
Q36.怎样将系统权限(system privileges)授予角色?
A. GRANT CREATE TABLE TO TESTROLE;
Q37.怎样从角色收回系统权限?
A. REVOKE CREATE TABLE FROM TESTROLE;
Q38.不等于条件有哪几种写法?(茴香豆问题
A. SELECT * FROM ROYAL_MTABLE WHERE RM_STR_FIELD != 'Y';
SELECT * FROM ROYAL_MTABLE WHERE RM_STR_FIELD ^= 'Y';
SELECT * FROM ROYAL_MTABLE WHERE RM_STR_FIELD <> 'Y';
Q39.like子句的用法?
A. SELECT * FROM ROYAL_DTABLE WHERE RD_STR_FIELD LIKE '%Y%';
SELECT * FROM ROYAL_DTABLE WHERE RD_STR_FIELD LIKE '_Y%';
Q40.请举出一个where子查询简单例子?
A. SELECT * FROM ROYAL_DTABLE WHERE RM_INT_FIELD IN (SELECT RM_INT_FIELD FROM ROYAL_MTABLE WHERE RM_STR_FIELD NOT IN ('Y','B'));
Q41.Oracle常用字符串处理函数有哪些?
A. || 连接两个字符串; LENGTH 字符串长度; TRIM/LTRIM/RTRIM 截断串左(右)指定字符串(包括空串); LOWER/UPPER 将字符串转换为小/大写,等等。
例如:SELECT RM_INT_FIELD||'--'||RM_STR_FIELD||'YES' FROM ROYAL_MTABLE;
Q42.Oracle支持哪些数字处理函数?
A. Oracle支持所有常用数字函数,包括(但不限于)+、-、*、/、ABS、COS、EXP、LN、LOG、MOD、POWER、ROUND、SIN、 SINH、SQRT、TAN、TRUNC、AVG、COUNT、MAX、MIN、SUM、GREATEST、LEAST等等。
例如:
SELECT GREATEST(3, 4, 5)*4 FROM DUAL;
SELECT POWER(2,3) FROM DUAL;
Q43.怎样取得数据库服务器当前日期、时间?
A. SELECT SYSDATE FROM DUAL;
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH:MI:SS') FROM DUAL;
Q44.怎样将字符串转换为日期、时间格式?
A. SELECT TO_DATE('2002-11-27', 'YYYY-MM-DD') FROM DUAL;
SELECT TO_DATE('2002-11-27 09:28:55', 'YYYY-MM-DD HH:MI:SS') FROM DUAL;
Q45.常用日期函数有哪些?
A. NEXT_DAY LAST_DAY ADD_MONTHS MONTHS_BETWEEN等等。
例如:SELECT LAST_DAY(SYSDATE) FROM DUAL;
Q46.能给出一个DECODE函数用法的例子吗?
A. DECODE函数的格式为DECODE(value, if1, then1, if2, then2...,else)。假设表ROYAL_DTABLE中有如下数据:
RD_INT_FIELD RD_STR_FIELD RM_INT_FIELD
-------------------------------------
1 royal 1
2 bill 2
3 joy 1

请观察如下SQL语句输出结果。
SELECT DECODE(RD_STR_FIELD, 'royal', 'royaltest', 'bill', 'billgates', RD_STR_FIELD) AS DC FROM ROYAL_DTABLE;
DC
---------
royaltest
billgates
joy

Q47.能给出一个group by、having和order by用法的例子吗?
A. SQL> SELECT * FROM ROYAL_MTABLE;
RM_INT_FIELD RM_STR_FIELD
-------------------------
1 Y
2 N
3 Y
SQL> SELECT * FROM ROYAL_DTABLE;
RD_INT_FIELD RD_STR_FIELD RM_INT_FIELD
--------------------------------------
1 royal 1
2 bill 2
3 joy 1
SQL> SELECT RM_INT_FIELD, SUM(RD_INT_FIELD) FROM ROYAL_DTABLE GROUP BY RM_INT_FIELD HAVING SUM(RD_INT_FIELD) >= 2 ORDER BY SUM(RD_INT_FIELD) ASC;

RM_INT_FIELD SUM(RD_INT_FIELD)
------------------------------
2 2
1 4
Q48.Oracle有哪些常用数据字典?
A. USER_TABLES(TABS)、USER_TAB_COLUMNS(COLS)、USER_VIEWS、USER_SEQUENCES(SEQ)、 USER_CONSTRAINTS、USER_CONS_COLUMNS、USER_TAB_COMMENTS、USER_COL_COMMENTS、 USER_INDEXES(IND)、USER_IND_COLUMNS、USER_USERS、DBA_USERS、ALL_USERS、 USER_TABLESPACES等等。
例如:SELECT * FROM USER_CONSTRAINTS WHERE CONSTRAINT_NAME = 'FK_ROYAL_DTABLE';
Q49.怎样将日期、时间插入date型字段中?
A. INSERT INTO ROYAL_MTABLE (RM_INT_FIELD, RM_STR_FIELD, RM_DATE_FIELD) valueS (9, 'Y', TO_DATE('2002-05-23', 'YYYY-MM-DD'));
INSERT INTO ROYAL_MTABLE (RM_INT_FIELD, RM_STR_FIELD, RM_DATE_FIELD) valueS (10, 'Y', TO_DATE('2002-10-10 8:23:33', 'YYYY-MM-DD HH:MI:SS'));
Q50.能介绍一下connect by的用法吗?
A. connect by子句提供了遍历“树”的手段。
假设有这样一个表:CREATE TABLE ROYAL_TREETABLE (ID INTEGER, PARENT_ID INTEGER, NAME VARCHAR2(32));
表中有如下数据:
ID PARENT_ID NAME
-----------------
2 1 AAA
3 1 BBB
4 2 CCC
5 2 DDD
6 4 EEE
8 7 GGG
假如我们现在需要从NAME = 'EEE'的记录开始,向上查找所有有父子关系的记录,可执行如下SQL语句:
SELECT * FROM ROYAL_TREETABLE START WITH NAME = 'EEE' CONNECT BY ID = PRIOR PARENT_ID;
ID PARENT_ID NAME
-----------------
6 4 EEE
4 2 CCC
2 1 AAA
posted @ 2006-06-12 13:52 Alex 阅读(397) | 评论 (0)编辑 收藏

     摘要: key words: wiki tiddlyWiki 客户端wiki 今天的主角是 tiddlywiki这个玩意真不错,N多时候其实说实在的,用服务器并不方便,能有一个放在我自己笔记本硬盘里的wiki,那是多么幸福的事啊  :)今天真的有这样的wiki,纯粹用javaScript + css + html实现的wiki,功能强大,可配置性好,你只需要在里面增加某个标题的内容,就可以实现样式,功能,...  阅读全文
posted @ 2006-06-11 15:38 Alex 阅读(2996) | 评论 (3)编辑 收藏

key words: jsp验证码 jcaptcha

原文参考 这里

安装

Add jcaptcha-all.jar (provided in bin-distribution) and ehcache.jar (not provided see ehcache site) to your application class path, ie in you WEB-INF/lib folder.

实例一个jcaptcha服务,注意,必须是单例模式的
import com.octo.captcha.service.image.ImageCaptchaService;
import com.octo.captcha.service.image.DefaultManageableImageCaptchaService;

public class CaptchaServiceSingleton {
    
    
private static ImageCaptchaService instance = new DefaultManageableImageCaptchaService();
    
    
public static ImageCaptchaService getInstance(){
        
return instance;
    }
}

注:以上是默认的一个实现,下面是其他更多的实现
  • SimpleListSoundCaptchaEngine   //还可以用声音,真爽哦
  • SpellerSoundCaptchaEngine
  • SpellerSoundCaptchaEngine
  • DefaultGimpyEngineCaptcha           
  • BaffleListGimpyEngineCaptcha           
  • BasicListGimpyEngineCaptcha           
  • DeformedBaffleListGimpyEngineCaptcha           
  • DoubleRandomListGimpyEngineCaptcha           
  • SimpleListImageCaptchaEngineCaptcha           
  • SimpleFishEyeEngineCaptcha
具体请参考官方说明

编写一个产生图片的servlet


import com.octo.captcha.service.CaptchaServiceException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;


public class ImageCaptchaServlet extends HttpServlet {


    
public void init(ServletConfig servletConfig) throws ServletException {

        
super.init(servletConfig);

    }


    
protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
        
       
byte[] captchaChallengeAsJpeg = null;
       
// the output stream to render the captcha image as jpeg into
        ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
        
try {
        
// get the session id that will identify the generated captcha. 
        
//the same id must be used to validate the response, the session id is a good candidate!
        String captchaId = httpServletRequest.getSession().getId();
        
// call the ImageCaptchaService getChallenge method
            BufferedImage challenge =
                    CaptchaServiceSingleton.getInstance().getImageChallengeForID(captchaId,
                            httpServletRequest.getLocale());
            
            
// a jpeg encoder
            JPEGImageEncoder jpegEncoder =
                    JPEGCodec.createJPEGEncoder(jpegOutputStream);
            jpegEncoder.encode(challenge);
        } 
catch (IllegalArgumentException e) {
            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
            
return;
        } 
catch (CaptchaServiceException e) {
            httpServletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            
return;
        }

        captchaChallengeAsJpeg 
= jpegOutputStream.toByteArray();

        
// flush it in the response
        httpServletResponse.setHeader("Cache-Control""no-store");
        httpServletResponse.setHeader(
"Pragma""no-cache");
        httpServletResponse.setDateHeader(
"Expires"0);
        httpServletResponse.setContentType(
"image/jpeg");
        ServletOutputStream responseOutputStream 
=
                httpServletResponse.getOutputStream();
        responseOutputStream.write(captchaChallengeAsJpeg);
        responseOutputStream.flush();
        responseOutputStream.close();
    }
}


为servlet修改web.xml配置文件
<servlet>
        
<servlet-name>jcaptcha</servlet-name>
        
<servlet-class>ImageCaptchaServlet</servlet-class>
        
<load-on-startup>0</load-on-startup>
    
</servlet>


<servlet-mapping>
        
<servlet-name>jcaptcha</servlet-name>
        
<url-pattern>/jcaptcha</url-pattern>
</servlet-mapping>


编写你的客户端的展示
<img src="jcaptcha">
<input type='text' name='j_captcha_response' value=''>

上面的src="jcaptcha"  就是调用了上面的servlet,text里是用户填写的确认验证码

后台逻辑验证
Boolean isResponseCorrect =Boolean.FALSE;
           
//remenber that we need an id to validate!
           String captchaId = httpServletRequest.getSession().getId();
           
//retrieve the response
           String response = httpServletRequest.getParameter("j_captcha_response");
           
// Call the Service method
            try {
                isResponseCorrect 
= CaptchaServiceSingleton.getInstance().validateResponseForID(captchaId,
                        response);
            } 
catch (CaptchaServiceException e) {
                 
//should not happen, may be thrown if the id is not valid 
            }


OK,大功告成了.

posted @ 2006-06-11 13:11 Alex 阅读(21023) | 评论 (28)编辑 收藏

key words: HttpClient LDAP LDAP验证

LDAP目前应用得非常广泛,在企业环境里可以供各种应用统一用户验证数据。

以下是一个客户端在正常访问的时候插入验证代码,将用户提交的用户名和密码提交给ldap验证
HttpClient hc = new HttpClient();
            GetMethod method 
= new GetMethod("http://www.yoursite.com/auth/your_auth.html");
            String inputUserName 
= JOptionPane.showInputDialog("Input your User Name:");
            String inputPassWord 
= JOptionPane.showInputDialog("Input your password:");
            UsernamePasswordCredentials upc 
= new UsernamePasswordCredentials(inputUserName, inputPassWord);
            hc.getState().setCredentials(
nullnull, upc);
            
int status = hc.executeMethod(method);
            method.releaseConnection();
            
if(status == 200)
            {
                System.out.println(
"login successful!");
                //do your business things

            } 
else
            {
                System.out.println(
"Login failed!  Please check your userName and Password!");
            }


http://www.yoursite.com/auth/your_auth.html如果直接访问会弹出对话框让你输入用户名密码


posted @ 2006-06-11 12:31 Alex 阅读(1053) | 评论 (0)编辑 收藏

key words: Oracle自增长 sequence

SqlServer 和MySql都有自增长的功能,Oracle必须建一个对应的sequence,有时候感觉不是很方便 。

这次要实现在SqlServer中插入一条记录的时候自动在Oracle中增加一条对应的记录,sequence就有问题。

最后用触发器搞定:

create or replace trigger mytable_trig_autoinc
before insert on
mytable
for each row
begin
  if (:new.id is null) then
    select
mytable_seq.nextval into :new.id from dual;
  end if;
end;

posted @ 2006-06-08 18:07 Alex 阅读(2845) | 评论 (0)编辑 收藏

首先让我们看一下服务器/客户机的交互原理。服务器提供某特定功能的服务总是由特定的后台程序提供的。在TCP/IP网络中,常常把这个特定的服务绑定到 特定的TCP或UDP端口。之后,该后台程序就不断地监听(listen)该端口,一旦接收到符合条件的客户端请求,该服务进行TCP握手后就同客户端建 立一个连接,响应客户请求。与此同时,再产生一个该绑定的拷贝,继续监听客户端的请求。

举一个具体的例子:假设网络中有一台服务器A (IP地址为1.1.1.1)提供WWW服务,另有客户机B(2.2.2.2)、C(3.3.3.3)。首先,服务器A运行提供WWW服务的后台程序(比 如Apache)并且把该服务绑定到端口80,也就是说,在端口80进行监听。当B发起一个连接请求时,B将打开一个大于1024的连接端口(1024内 为已定义端口),假设为1037。A在接收到请求后,用80端口与B建立连接以响应B的请求,同时产生一个80端口绑定的拷贝,继续监听客户端的请求。假 如A又接收到C的连接请求(设连接请求端口为1071),则A在与C建立连接的同时又产生一个80端口绑定的拷贝继续监听客户端的请求。如下所示,因为系 统是以源地址、源端口、目的地址、目的端口来标识一个连接的,所以在这里每个连接都是唯一的。

服务器 客户端
连接1:a.b.c.1:80 <=> a.b.c.4:1037
连接2:a.b.c.1:80 <=> a.b.c.7:1071

每 一种特定的服务都有自己特定的端口,一般说来小于1024的端口多为保留端口,或者说是已定义端口,低端口分配给众所周知的服务(如WWW、FTP等 等),从512到1024的端口通常保留给特殊的UNIX TCP/IP应用程序,具体情况请参考/etc/services文件或RFC1700。

假设网络环境如下:某一单位,租用DDN专线上网,网络拓扑如下:

+--------------+
| 内部网段 | eth1+--------+eth0 DDN
| +------------|firewall|<===============>Internet
| 198.168.80.0 | +--------+
+--------------+
eth0: 198.199.37.254
eth1: 198.168.80.254

以上的IP地址都是Internet上真实的IP,故没有用到IP欺骗。并且,我们假设在内部网中存在以下服务器:
www服务器:www.yourdomain.com 198.168.80.11
ftp服务器:ftp.yourdomain.com 198.168.80.12
email服务器:mail.yourdomain.com 198.168.80.13

下面我们将用iptables一步一步地来建立我们的包过滤防火墙,需要说明的是,在这个例子中,我们主要是对内部的各种服务器提供保护。

1. 在/etc/rc.d/目录下用touch命令建立firewall文件,执行chmod u+x firewll以更改文件属性 ,编辑/etc/rc.d/rc.local文件,在末尾加上 /etc/rc.d/firewall 以确保开机时能自动执行该脚本。

2. 刷新所有的链的规则
#!/bin/sh

echo "Starting iptables rules..."

#Refresh all chains

/sbin/iptables -F

3. 我们将首先禁止转发任何包,然后再一步步设置允许通过的包。
所以首先设置防火墙FORWARD链的策略为DROP:

/sbin/iptables -P FORWARD DROP

4.设置关于服务器的包过虑规则:

在这里需要注意的是,服务器/客户机交互是有来有往的,也就是说是双向的,所以我们不仅仅要设置数据包出去的规则,还要设置数据包返回的规则,我们先建立针对来自Internet数据包的过虑规则。

WWW服务:服务端口为80,采用tcp或udp协议。规则为:eth0=>允许目的为内部网WWW服务器的包。

###########################Define HTTP packets####################################

#Allow www request packets from Internet clients to www servers
/sbin/iptables -A FORWARD -p tcp -d 198.168.80.11 --dport www -i eth0 -j ACCEPT

FTP 服务:FTP服务有点特别,因为需要两个端口,因为FTP有命令通道和数据通道。其中命令端口为21,数据端口为20,并且有主动和消极两种服务模式,其 消极模式连接过程为:FTP客户端首先向FTP服务器发起连接请求,三步握手后建立命令通道,然后由FTP服务器请求建立数据通道,成功后开始传输数据, 现在大多数FTP客户端均支持消极模式,因为这种模式可以提高安全性。FTP服务采用tcp协议。规则为:eth0=>仅允许目的为内部网ftp服 务器的包。

############################Define FTP packets#####################################

#Allow ftp request packets from Internet clients to Intranet ftp server
/sbin/iptables -A FORWARD -p tcp -d 198.168.80.12 --dport ftp -i eth0 -j ACCEPT


EMAIL服务:包含两个协议,一是smtp,一是pop3。出于安全性考虑,通常只提供对内的pop3服务,所以在这里我们只考虑针对smtp的安全性问题。smtp端口为21,采用tcp协议。eth0=>仅允许目的为email服务器的smtp请求。

###########################Define smtp packets####################################
/sbin/iptables -A FORWARD -p tcp -d 198.168.80.13 --dport smtp -i eth0 -j ACCEPT

5. 设置针对Intranet客户的过虑规则:

在 本例中我们的防火墙位于网关的位置,所以我们主要是防止来自Internet的攻击,不能防止来自Intranet的攻击。假如我们的服务器都是基于 linux的,也可以在每一部服务器上设置相关的过虑规则来防止来自Intranet的攻击。对于Internet对Intranet客户的返回包,我们 定义如下规则。

#############Define packets from Internet server to Intranet#######################
/sbin/iptables -A FORWARD -p tcp -s 0/0 --sport ftp-data -d 198.168.80.0/24 -i eth0 -j ACCEPT
/sbin/iptables -A FORWARD -p tcp -d 198.168.80.0/24 ! -syn -i eth0 -j ACCEPT
/sbin/iptables -A FORWARD -p udp -d 198.168.80.0/24 -i eth0 -j ACCEPT

说明:第一条允许Intranet客户采用消极模式访问Internet的FTP服务器;第二条接收来自Internet的非连接请求tcp包;最后一条接收所有udp包,主要是针对oicq等使用udp的服务。

6. 接受来自整个Intranet的数据包过虑,我们定义如下规则:

#############Define packets from Internet server to Intranet server###############
/sbin/iptables -A FORWARD -s 198.168.80.0/24 -i eth1 -j ACCEPT

7. 处理ip碎片

我们接受所有的ip碎片,但采用limit匹配扩展对其单位时间可以通过的ip碎片数量进行限制,以防止ip碎片攻击。

#################################Define fregment rule##################################
/sbin/iptables -A FORWARD -f -m limit --limit 100/s --limit-burst 100 -j ACCEPT

说明:对不管来自哪里的ip碎片都进行限制,允许每秒通过100个ip碎片,该限制触发的条件是100个ip碎片。

8. 设置icmp包过滤

icmp包通常用于网络测试等,故允许所有的icmp包通过。但是黑客常常采用icmp进行攻击,如ping of death等,所以我们采用limit匹配扩展加以限制:

#################################Define icmp rule##################################
/sbin/iptables -A FORWARD -p icmp -m limit --limit 1/s --limit-burst 10 -j ACCEPT

说明:对不管来自哪里的icmp包都进行限制,允许每秒通过一个包,该限制触发的条件是10个包。


通 过以上个步骤,我们建立了一个相对完整的防火墙。只对外开放了有限的几个端口,同时提供了客户对Internet的无缝访问,并且对ip碎片攻击和 icmp的ping of death提供了有效的防护手段。以下是完整的脚本文件内容,希望通过这个实例能是对iptables的用法有所了解:

#!/bin/sh

echo "Starting iptables rules..."

#Refresh all chains

/sbin/iptables -F

###########################Define HTTP packets####################################

#Allow www request packets from Internet clients to www servers
/sbin/iptables -A FORWARD -p tcp -d 198.168.80.11 --dport www -i eth0 -j ACCEPT

############################Define FTP packets#####################################

#Allow ftp request packets from Internet clients to Intranet ftp server
/sbin/iptables -A FORWARD -p tcp -d 198.168.80.12 --dport ftp -i eth0 -j ACCEPT

###########################Define smtp packets####################################
/sbin/iptables -A FORWARD -p tcp -d 198.168.80.13 --dport smtp -i eth0 -j ACCEPT

#############Define packets from Internet server to Intranet#######################
/sbin/iptables -A FORWARD -p tcp -s 0/0 --sport ftp-data -d 198.168.80.0/24 -i eth0 -j ACCEPT
/sbin/iptables -A FORWARD -p tcp -d 198.168.80.0/24 ! -syn -i eth0 -j ACCEPT
/sbin/iptables -A FORWARD -p udp -d 198.168.80.0/24 -i eth0 -j ACCEPT

#############Define packets from Intranet to Internet###############
/sbin/iptables -A FORWARD -s 198.168.80.0/24 -i eth1 -j ACCEPT

#################################Define fregment rule##################################
/sbin/iptables -A FORWARD -f -m limit --limit 100/s --limit-burst 100 -j ACCEPT

#################################Define icmp rule##################################
/sbin/iptables -A FORWARD -p icmp -m limit --limit 1/s --limit-burst 10 -j ACCEPT
posted @ 2006-06-06 17:05 Alex 阅读(259) | 评论 (0)编辑 收藏

key words: iptables linux防火墙 防火墙设置


[作者序]:本来是要翻译http://www.justlinux.com/nhf/Security/IPtables_Basics.html这篇文章的,可惜当年实在是没有学好语法,许多句子按照原文翻译,如何也理不通顺。只好按照自己的理解重新组织了,但愿不会有太大的偏差。好在,无论如何,现在读起来,基本通顺了。

Iptables用三种链来管理放出、进入或经过你计算机的(数据)包。INPUT链管理进入你计算机的包,OUTPUT链管理你计算机放出的包,FORWARD链管理经过你的计算机转送到另一台计算机的包。

所以,设置iptables的过程事实上就是定义一些规则来决定如何处理这三种包的过程。

例如,如果你访问http://www.yahoo.com,你的计算机将放出一个包向Yahoo!请求。这个包就要经过OUTPUT链的审核。内核会浏览OUTPUT链,看看是否有某条规则不允许放出这个包,如果有的话,就拒绝放出。

现在让我们来处理一些实际问题。比如你想阻塞所有来自200.200.200.1的包。首先你需要用-s选项来指明源IP地址或DNS:
CODE:
iptables -s 200.200.200.1

然后可以用-j选项来说明如何处理这个包。最常用的处理方式有三种:ACCEPT、DENY和DROP。ACCEPT顾名思义表示接受包,DENY不接受同时回送一条拒绝信息,而DROP则根本对包不予理睬。如果确信某个IP可疑,那么最好选择DROP而不是DENY:
CODE:
iptables -s 200.200.200.1 -j DROP

但是仅仅使用上面这条命令,我们的计算机会无所适从,因为它不知道该用哪条链来处理这项规则。这就要用到-A选项,它表示把某条规则追加到某个链的末尾。我们打算拒绝所有来自200.200.200.1的包,所以使用:
CODE:
iptables -A INPUT -s 200.200.200.1 -j DROP

选项的顺序不会影响最终的处理结果,-j DROP也可以放在-s 200.200.200.1的前面,只不过放在后面似乎更容易理解。
现在扩展一下,假设我们不想发送任何包给200.200.200.1该如何做呢?很简单,只要把INPUT换成OUTPUT,同时用-d替换-s就可以了:
CODE:
iptables -A OUTPUT -d 200.200.200.1 -j DROP

那 么,如果我们打算忽略来自这台机器的telnet请求该怎么办呢?你可能知道telnet使用的是23端口,但是如果你愿意,你也可以在iptables 中使用telnet关键字而不是端口号。Telnet,像大多数服务一样,运行于TCP协议之上。我们可以使用-p选项来指明所用的协议。但是只指明协议 不会有任何作用,还需要使用—destination-port来指出我们要为哪个目标端口指定规则。与之相对应,--source-prot用来指明源 端口,确信别把二者弄混了。所以我们可以这样拒绝某台机器的telnet请求:
CODE:
iptables -A INPUT -s 200.200.200.1 -p tcp --destination-port telnet -j DROP

扩展一下,如果你想拒绝一个网段的telnet请求,可以使用200.200.200.0/24来代替上面的200.200.200.1,它匹配任何200.200.200.*这样的IP地址。

再复杂一些。假设我们同时可以连接到本地局域网和internet,eth0网卡用来连接本地局域网,ppp0用来拨号到internet。我们可能只想 为本地局域网提供telnet服务而不想为不安全的internet提供此项服务。有两种选择:在OUTPUT链上用-o选项阻塞设备输出数据,但更好的 是在INPUT链上用-i选项阻塞设备输入数据。因此,这条规则可以这样设置:
CODE:
iptables -A INPUT -p tcp --destination-port telnet -i ppp0 -j DROP

这将关闭一切来自internet的telnet请求但是开放局域网同样的请求。

规则可以使用-A选项来追加在规则列表之后 ,也可以使用-I选项插入在某条规则之前。例如,如果我们想把一条规则放在INPUT链的最前面,我们可以使用“-I INPUT 1”。其中的1代表规则列表的第一行,你也可以把它换成其它的数字。除此之外,我们还可以使用-R选项来替换某条规则(它将删除原来的规则),-D选项来 删除某条规则,-L选项来列出所有已经设置的规则,-F选项来初始化所有规则。

现在,再深入一步。网络中的数据包通常使用某种协议,如果这种协议是TCP,它还会使用某个端口。你可能想干脆关闭所有端口拒绝进来的包,但是记着,如果 你的计算机同另一台计算机会话,另一台计算机肯定会发送反馈信息。如果你关闭了所有进来的端口,那本质上就表示你的连接就没有用了。而且对于大多数非服务 程序来说,你无法预知它们使用哪个端口进行会话。但是仍然有一种办法。当两台计算机在TCP连接上进行会话时,连接一定会首先被初始化。完成这项任务的包 叫作SYN。一个SYN包简单的表明另一台计算机已经做好了会话的准备。只有发出服务请求的计算机才发送SYN包。所以如果你仅拒绝进来的SYN包,它将 终止其它计算机打开你计算机上的服务,但是不会终止你使用其它计算机上的服务,如果它没有拒绝你发送的SYN包的话。这是一种折衷的办法,但是可以完成许 多我们想完成的任务。这个选项是--syn,用在你指明的TCP协议之后。所以制定一条规则阻塞所有来自internet的连接会是这样:
CODE:
iptables -A INPUT -i ppp0 -p tcp --syn -j DROP

这是一条非常有用的规则除非你的计算机运行有web服务。如果你仅打算开放一个端口,比如说80(HTTP),有种简单的办法。和许多编程语言一样,可以用一个惊叹号表示“非”。例如,你打算阻塞所有80端口以外的SYN包,我想会是这样:
CODE:
iptables -A INPUT -i ppp0 -p tcp --syn --destination-port ! 80 -j DROP

这稍微有点复杂但并不难理解。

最后,如何改变链的现有规则呢?INPUT链和OUTPUT链通常默认被设置为ACCEPT而FORWARD链默认则被设置为DENY。如果你打算把一台 计算机作为路由器,你可能要设置FORWARD规则为ACCEPT。如何做这个?事实上很简单。只要使用-P选项,在它后面跟上链的名字和你制定的新规则 就可以了。例如,把FORWARD链改为ACCEPT规则,我们这样做:
CODE:
iptables -P FORWARD ACCEPT
posted @ 2006-06-06 16:58 Alex 阅读(268) | 评论 (0)编辑 收藏

    key words: "  shared memory realm does not exist"  Oracle10g启动错误

上次安装的Oracle10g启动出现了问题,提示:
ORACLE not available
ORA-
27101: shared memory realm does not exist
Linux Error: 
2: No such file or directory



google了一下,有人有如下提议:
make sure that both ORACLE_HOME and ORACLE_SID are written correctly.
In past, I've got same error because ORACLE_HOME in init script was
/opt/oracle/9iR1/ but the real ORACLE_HOME was /opt/oracle/9iR1 without ending slash.
Yes, a simple slash implies two different installation.
If in your scritps/programs you use sometime /opt/oracle/9iR1 and sometime /opt/oracle/9iR1/
(with ending slash) you'll fall in troubble!.
When u got "shared memory realm does not exist " at first check du a "ps -fe | grep ora"
in order to make sure if the instance is running.
also, if you want see that "shared memory realm" you can type "ipcs". If oracle is alive you can see a
huge segment of memory (aslo know as SGA)



最后检查结果好像也不是这个,是配置文件出错,即服务名不一致:

其中SERVICE_NAME与SID_NAME一定要和.bash_profile中的ORACLE_SID相一致,否则无法启动

posted @ 2006-06-06 16:02 Alex 阅读(409) | 评论 (0)编辑 收藏

key words:  css


转自:http://www.blueidea.com/tech/site/2004/1928.asp

在了解XHTML代码规范后,我们就要进行CSS布局。首先先介绍一些CSS的入门知识。如果你已经很熟悉了,可以跳过这一节,直接进入下一节。

CSS是Cascading Style Sheets(层叠样式表)的缩写。是一种对web文档添加样式的简单机制,属于表现层的布局语言。

1.基本语法规范

分析一个典型CSS的语句:

{COLOR:#FF0000;BACKGROUND:#FFFFFF}

  • 其中"p"我们称为"选择器"(selectors),指明我们要给"p"定义样式;
  • 样式声明写在一对大括号"{}"中;
  • COLOR和BACKGROUND称为"属性"(property),不同属性之间用分号";"分隔;
  • "#FF0000"和"#FFFFFF"是属性的值(value)。

2.颜色值

颜色值可以用RGB值写,例如:color : rgb(255,0,0),也可以用十六进制写,就象上面例子color:#FF0000。如果十六进制值是成对重复的可以简写,效果一样。例如:#FF0000可以写成#F00。但如果不重复就不可以简写,例如#FC1A1B必须写满六位。

3.定义字体

web标准推荐如下字体定义方法:

body { font-family : "Lucida Grande", Verdana, Lucida, Arial, Helvetica, 宋体,sans-serif; }

  • 字体按照所列出的顺序选用。如果用户的计算机含有Lucida Grande字体,文档将被指定为Lucida Grande。没有的话,就被指定为Verdana字体,如果也没有Verdana,就指定为Lucida字体,依此类推,;
  • Lucida Grande字体适合Mac OS X;
  • Verdana字体适合所有的Windows系统;
  • Lucida适合UNIX用户
  • "宋体"适合中文简体用户;
  • 如果所列出的字体都不能用,则默认的sans-serif字体能保证调用;

4.群选择器

当几个元素样式属性一样时,可以共同调用一个声明,元素之间用逗号分隔,:

p, td, li { font-size : 12px ; }

5.派生选择器

可以使用派生选择器给一个元素里的子元素定义样式,例如这样:

li strong { font-style : italic; font-weight : normal;}

就是给li下面的子元素strong定义一个斜体不加粗的样式。

6.id选择器

用CSS布局主要用层"div"来实现,而div的样式通过"id选择器"来定义。例如我们首先定义一个层

<div id="menubar"></div>

然后在样式表里这样定义:

#menubar {MARGIN: 0px;BACKGROUND: #FEFEFE;COLOR: #666;}

其中"menubar"是你自己定义的id名称。注意在前面加"#"号。

id选择器也同样支持派生,例如:

#menubar p { text-align : right; margin-top : 10px; }

这个方法主要用来定义层和那些比较复杂,有多个派生的元素。

6.类别选择器

在CSS里用一个点开头表示类别选择器定义,例如:

.14px {color : #f60 ;font-size:14px ;}

在页面中,用class="类别名"的方法调用:

<span class="14px">14px大小的字体</span>

这个方法比较简单灵活,可以随时根据页面需要新建和删除。

7.定义链接的样式

CSS中用四个伪类来定义链接的样式,分别是:a:link、a:visited、a:hover和a : active,例如:

a:link{font-weight : bold ;text-decoration : none ;color : #c00 ;}
a:visited 
{font-weight : bold ;text-decoration : none ;color : #c30 ;}
a:hover 
{font-weight : bold ;text-decoration : underline ;color : #f60 ;}
a:active 
{font-weight : bold ;text-decoration : none ;color : #90 ;}

以上语句分别定义了"链接、已访问过的链接、鼠标停在上方时、点下鼠标时"的样式。注意,必须按以上顺序写,否则显示可能和你预想的不一样。记住它们的顺序是“LVHA”。

呵呵,看了这么多,有点头晕吧,实际上CSS的语法规范还有很多,这里列的只是一些常用的,毕竟我们是循序渐进,不可能一口吃成胖子:)

posted @ 2006-06-05 09:53 Alex 阅读(287) | 评论 (0)编辑 收藏

     摘要: key words: IE打印 web打印 页面打印 最近又碰到了页面打印,顺便记录一下,本来下午写完了,可惜最近blogjava最近总是出现问题,提交居然失败,只好再来一次.Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->function SaveD...  阅读全文
posted @ 2006-05-26 23:08 Alex 阅读(559) | 评论 (1)编辑 收藏

现在浏览器端以 JavaScript 为核心,基于各种 Web 标准(即:早已完成标准化的XHTML/CSS/DOM/XML/XSLT 和正在进行标准化的XMLHTTP)的技术正在加速整合,Ajax 就是这一系列技术的一个统称。

虽 然网络上已经有大量的相关资源,但是为了打好基础,认真读上几本书还是很有必要的。好在 Ajax 并不是什么全新的技术,它仅仅是传统技术的发展和增值,是对于这些基于 Web 标准的传统技术的重新包装,使其更加适合于企业应用,并且和服务器端结合地更加紧密。因此学习 Ajax,首先就要从深入学习这些传统的技术开始。我由浅入深地列出一些我读过的书籍,提供给大家做参考:

1、XHTML 教程(XHTML)

作者:Chelsea Valentine, Chris Minnick

New Riders 原版,人民邮电出版社中文版

是的,今天你最应该学习的是 XHTML,而不是 HTML。HTML 4.x 已经是一个被废弃了的标准,今天的标准是 XHTML 1.0。XHTML 1.0 也不是 XHTML 最新的版本,但是它是目前唯一得到浏览器广泛支持和唯一实用的 XHTML 版本。

2、JavaScript 权威指南第四版(JavaScript: The Definitive Guide)

作者:David Flanagan

O'Reilly 原版,中国电力出版社中文版

JavaScript 爱好者亲切地称之为“犀牛书”,因为 O'Reilly 以犀牛作为这本书的封面。这是目前 JavaScript 领域最深入和最权威的入门书。与其它 JavaScript 相关书籍的区别是这本书一半以上的篇幅着重于深入介绍 JavaScript 语言本身的基础知识,而不是象其它的书一样把基础知识和与 HTML 相结合做 Web 开发的内容(这些内容往往偏重于细节,使得其篇幅很容易就超出了 1000 页,例如《JavaScript Bible》)混杂在一起。对于刚刚开始学习 JavaScript 的初学者,这本书毫无疑问是最佳的入门书。

3、XML 高级编程(Professional XML)

Didier Martin等著

Wrox 原版,机械工业出版社中文版

这本书是关于 XML 开发技术非常详尽的著作。虽然因为作者众多(第一版 12 个人,第二版好像又多了几个),无法摆脱 Wrox 红皮书系列大杂烩的印记,但是这本书可以说是红皮书系列中少有的精品。

这本书可以作为 XML 技术参考书,虽然很厚,但是没有必要从头到尾全部读完。其中与 Ajax 相关的内容包括 XML DOM、XSLT 等等。

4、网站重构(Designing with Web Standards)

作者:Jeffrey Zeldman

New Riders 原版,电子工业出版社中文版

这 本书详细地介绍了如何摒弃远古时代(按照我的理解,3 年以前吧)不符合标准,专门针对某种浏览器(90%以上的情况下是 IE)做开发的恶习,真正采用符合标准的方式来做开发,最终走上向后兼容(注意:不是与浏览器以前不能完整支持 Web 标准的版本相兼容,而是与浏览器以后的版本相兼容)的平坦大路上来。这本书虽然不是 CSS 的专著,但是其中充分展示了使用 CSS 的一些高级技巧。尤其是最后一章展示了完全基于 CSS 做布局,摒弃使用 table 做布局的老方法的具体做法。

非常遗憾的是这本书的中文版翻译的非常烂,如果不对照原文,很容易误入歧途。读这本书有任何疑问的朋友都可以直接和我联系。

上面列出的是与 Ajax 涉及到的技术相关的书籍。我没有列出 CSS 的书,是因为我并没有专门读过一本 CSS 方面的专著。附件是网上流传很广的 CSS 2.0 中文手册,可以作为这方面的参考。

读了以上这些书,你已经在技术方面打下了极为坚实的基础,你还需要有一个经常的讨论场所,JavaEye 毫无疑问是你最值得来的地方。

下面我再列出几本与技术没有直接关系的书籍。

5、面向使用的软件设计(Software for Use)

作者:Larry Contantine, Lucy Lockwood

ACM Press 原版,机械工业出版社中文版

大 部分的软件都是给人使用的。我在 BEA User Group上的演讲中说到,Ajax 为什么会越来越流行,主要的原因就是它能比传统的基于 HTML FORM 的交互模式带给用户更好的交互体验,也就是 Ajax 可以实现更好的 Web 可用性(Web Usability,这是目前国外的一个专门的研究领域),这才是 Ajax 最大的价值。软件的可用性永远都是一个大的话题,《面向使用的软件设计》正是这方面最权威的专著。我们只要在做最终用户直接使用(有一个可视的界面)的软 件开发,提高可用性就是我们需要孜孜不倦追求的目标。

6、软件创新之路(Inmates Are Running the Asylum)

作者:Alan Cooper

Sams Publishing 原版,电子工业出版社中文版

7、About Face 2.0

作者:Alan Cooper

John Wiley & Sons 原版,中文版即将出版

上面两本书都是交互设计大师 Alan Cooper 的名著,相信很多朋友都知道 Alan Cooper 的大名,这两本书是交互设计爱好者必读的著作。


posted @ 2006-05-26 22:48 Alex 阅读(153) | 评论 (0)编辑 收藏

kew words: javamail

这几天项目里涉及到javamail,顺便看了下.

现在都习惯在blogjava上搜索一番了  XXX in site:blogjava.net是我常用的搜索方式了,呵呵,大多数时候发现blogjava没让我失望,也说明这里的高手很多啊 :)

感觉 Bromon的两篇文章很实用:
JavaMail使用指南(一)Javamail使用指南(二)

还有 morcble的 javamail发送邮件javamail接受邮件

在测试的时候有几个问题值得一提:
  • 第一就是一定要加上activation.jar 库文件,否则会报下面的异常:

NoClassDefFoundError: javax/activation/DataSource

  • 另外,发现用yahoo的smtp会报535的验证错误,把验证的方式换为morcble的下面的内部类的方式验证也不行:
Session session = Session.getDefaultInstance(props,
    
new Authenticator() {
     
public PasswordAuthentication getPasswordAuthentication() {
      
return new PasswordAuthentication(mymail.username,
        mymail.password);     
     }
    });

最后换了个smtp服务器没问题,不知道各位兄弟有没有碰到这样的问题,可以确认的是我的yahoo配置信息应该是正确的,因为我用foxmail收发信件都是可以的.

后来到yahoo中国里面看了一下帮助,里面说
我们目前正在对雅虎邮箱该项服务进行相关的调整,因此我们暂时停止了在页面上POP服务设置的相关介绍。目前雅虎邮箱暂时不提供POP服务,敬请关注雅虎邮箱的近期活动。


应该就是这个原因了   :)

  • 另外,还有一些基于javamail封装的工具类:
    可以参考这篇 :  简化JavaMail:小巧 Jakarta Commons-Email 简单教程


posted @ 2006-05-23 00:18 Alex 阅读(249) | 评论 (0)编辑 收藏

出处:codeChina

key words: cos 文件上传 jsp上传

index.html文件:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=gb2312">
<title>无标题文档</title>
</head>

<body>
<!-- enctype的值很重要,upload.jsp为处理上传的jsp-->
<form name="form1"  method="post" enctype="multipart/form-data" 
action
="upload.jsp">
<p>
  
<input name="file1" type="file">
</p>
<p>
  
<input name="file2" type="file">
</p>
<p>  <input name="file3" type="file">
</p>
<p>
  
<input type="submit" name="Submit" value="上传">
</p>
</form >

</body>
</html> 

upload.jsp文件 :
<%@page import="java.io.*"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@page import="com.oreilly.servlet.multipart.CoverFileRenamePolicy"%>
<%@page contentType="text/html; charset=gb2312" %>
<%
//文件上传后,保存在c:\\upload
String saveDirectory ="c:\\upload";
//每个文件最大5m,最多3个文件,所以
int maxPostSize =3 * 5 * 1024 * 1024 ;
//response的编码为"gb2312",同时采用缺省的文件名冲突解决策略,实现上传
//就这一句就完成上传了,真是很爽
MultipartRequest multi 
= new MultipartRequest(request, saveDirectory, maxPostSize,"gb2312");

//输出反馈信息
 Enumeration files 
= multi.getFileNames();
     
while (files.hasMoreElements()) {
        System.err.println(
"ccc");
       
String name = (String)files.nextElement();
       File f 
= multi.getFile(name);
       
if(f!=null){
         
String fileName = multi.getFilesystemName(name);
         
String lastFileName= saveDirectory+"\\" + fileName;
         out.println(
"上传的文件:"+lastFileName);
         out.println(
"<hr>");

       }
     }

%>


相关链接:几种上传方法介绍和比较
posted @ 2006-05-22 20:59 Alex 阅读(2776) | 评论 (3)编辑 收藏

key words: jsp文件上传 上传组件 Rrilly-Cos  jspsmartUpload  Jakarta Apache Struts upload


几种上传方法介绍、比较

目 录

1 引言... 1

2 O`Rrilly-Cos. 1

3 jspsmartUpload. 3

4 Jakarta Apache Struts upload. 5

5 几种方法的比较... 6

1 引言

一个网站总是不可避免的要和用户进行信息的交互,倘若是从窗体传送一般的简单输入类型(例如:text、password、radio、 checkbox、select等等)的信息到服务器端时,只要使用application/x-www-form-urlencoded的编码方式用 session传递就可以了。但是当涉及到和用户之间的文件交换(包括上传和下载)时,就不是那么简单了。在上传文件到服务器时,必须要使用 multipart/form-data的编码方式,并且不能直接使用request.getParameter()来取得。至于所使用的方法有很多种, 比如:jspsmart公司的jspsmartupload组件,O`Rrilly公司的cos组件,Jakarta Apache公司的commonsFileUpload组件,JavaZoom的uploadbean组件,还有Struts组件中自带的 org.apache.struts.upload类工具等等。下面就针对其中的三种解决方案(jspsmartupload、O`Reilly- cos、struts.upload)做一个简单的介绍和对比。

2 O`Rrilly-Cos

Cos组件是O`Rrilly公司开发的,该组件免费,不定期增加新功能,开源。

图1 O`Rrilly-Cos

在Cos组件中,MultipartRequest类主要负责文件上传的处理。MultipartRequest有8个构造函数:

1.Public MultipartRequest ( HttpServletRequest request, String saveDirectory,) throws IOException

2.Public MultipartRequest ( HttpServletRequest request, String saveDirectory, int maxPostSize) throws IOException

3.Public MultipartRequest ( HttpServletRequest request, String saveDirectory, int maxPostSize, FileRenamePolicy policy) throws IOException

4.Public MultipartRequest ( HttpServletRequest request, String saveDirectory, int maxPostSize, String encoding) throws IOException

5.Public MultipartRequest ( HttpServletRequest request, String saveDirectory, int maxPostSize, String encoding, FileRenamePolicy policy) throws IOException

6.Public MultipartRequest ( HttpServletRequest request, String saveDirectory, String encoding) throws IOException

7.Public MultipartRequest ( HttpServletRequest request, String saveDirectory) throws IOException

8.Public MultipartRequest ( HttpServletRequest request, String saveDirectory, int maxPostSize) throws IOException

前6种构造函数都是用来专门处理HTTP协议的,saveDirectory是上传文件要存储在服务器端的目录名称;maxPostSize是用来 限制用户上传文件大小的,若超过maxPostSzie,会产生IOException,默认上传文件大小是1MB;encoding可以设定用何种编码 方式来上传文件名称,可以解决中文问题。

MultipartRequest类工具有8种方法,利用这些方法,我们可以取得请求的相关信息:

Public Enumeration getParameterNames()

可以取得请求参数的名称

public String getParameter(String name)

此方法传回参数为name的值

public String[] getParameterValues(String name)

此方法主要用在取得当一指定参数具有多个值时,它会传回String的数组

public Enumeration getFileName()

传回所有文件输入类型的名称

public String getFilesystemNames(String name)

用此方法得到上传文件的真正的文件名,这里的name指文件输入类型的名称

public String getContentType(String name)

此方法得到上传文件的内容类型

public File getFile(String name)

此方法得到一个文件对象,代表储存在服务器上的name文件

public String getOriginalFileName(String name)

返回文件在修改政策有效之前的文件名

3 jspsmartUpload

Jspsmartupload组件是由jspsmart公司开发的,安装好它的组件以后,就可以处理文件上传及下载的问题。该组件简单好用,免费,但是源码不公开。

Jspsmartupload Overview:

Free 免费的

upload 1or more files to the server 可上传1个或多个文件

upload to a database 上传文件到数据库

control the upload file by file 可以一列一列的(一个个)控制上传

manage mixed forms files +form fields 可以管理表格文件和表格域

download a file 可以实现文件下载

download a database field 可以从数据库中下载

restrict file size , extension etc 可以限制上传文件的尺寸和类型

MacBinary support MckBinary的支持

Platform: Apache, NT, Unix, Linux, IIS 可以在多种平台上运行

Database : MySQL , Oracle…… 支持多种数据库(最支持MySQL)

整个jspsmartupload压缩包113K,包括有范例、API说明和编译好的class文件,调用这些class文件就可以实习文件的上传下载功能。

图2 jspsmartUpoad

Jspsmartupload能实现比O`Rrilly-Cos更多的方法,比如有:

1.public int getSize()方法得到上传文件大小的总和

2.public void setDeniedFilesList(String deniedFilesList)方法设定用户不可上传的类型

3.public void setAllowedFilesList(String allowedFilesList)方法设定用户可上传的文件类型

4.public void setTotalMaxFileSize(Long totalMaxFilesList)设定一次上传文件大小总和

5.public int getCount()得到Files中的文件个数

6.public Boolean isMissing()测试文件是否确实已经存在

7.public String getFieldName()得到此File在前一个HTML文件中的表格名称

8.public String getFilePathName()得到此File在上传端的文件位置

9.public String getFileExt()得到文件的扩展名

………….

Jspsmartupload的安装:只需把这些class文件拷贝到classes文件夹中即可。

4 Jakarta Apache Struts upload

由于本项目是用Struts结构开发的,所以利用Struts自带的类工具实现上传,这能和工程整体结合的很好,不需要导入其他的包,并且功能强大,使用简单,性能稳定且开源,所以无疑是最佳的选择。

下图是Struts中upload包的结构。基本上要实现上传功能,只要用到FormFiles和MultipartRequestHandler接口就可以解决了。

图3 Struts-upload包的结构

基本处理流程是,从页面中传递文件到Form中,然后从Action得到Form中的文件,形成InputStream,然后通过OutputStream写入磁盘。

同样,Struts的upload工具类也可以实现对上传文件大小和类型的控制,可以同时上传多个文件等等。

5 几种方法的比较

O`Rrilly-Cos

jspsmartUpload

Struts-upload

是否开源

是否免费

是否继续开发

不明

功能

一般

可靠性

一般

特点综述

免费,开源,不定期增加新功能,可靠性高,代码直接写在jsp文件中

简单好用,可上传、下载,功能强大,免费,但是源码不公开,代码直接写在jsp文件中。上传时,文件先预读入内存,当接到save指令时才保存到磁盘,所以上传的性能和文件及内存的大小关系密切。

在Struts中使用极为方便,免费,开源,可靠性高,表示层和业务层分离,有后台的Form和Action

表1 几种上传方法的比较

在研究比较这几种上传组件之后,我认为不管用其中的哪一种都能满足我们的要求,毕竟我们要实现的仅仅是文件上传的功能。最基本的,只要能将文件取得File格式的,就能实现各种各样的功能。

结论是,就本项目而言,使用Struts-upload组件是最贴切的选择;如果要做封装的话,最好选择jspsmartUpload和O`Rrilly-Cos。

posted @ 2006-05-16 23:50 Alex 阅读(1542) | 评论 (0)编辑 收藏

key words: 动态树 eval函数用法

近期项目中需要在ilearning中做开发,用到大量纯jsp模式的开发,当然javaScript也用了很多,看来近期要好好研究javascript了 :)

一.树
这次要做一个树,需要支持展开和放置checkbox,开始的时候打算找一个,后来发现没有适合的,最后自己写,其实也就是用到.style.display='none'或者.style.display='block'来支持展开
显示效果如下:
树
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"
>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Tree</title>
<script language="javascript">
function show(IMG,DV)
{
    
if(DV.style.display=="none")
    {
        DV.style.display
="block";
        IMG.src
="manager.gif"
    }
    
else
    {
        DV.style.display
="none";
        IMG.src
="manager.gif"        
    }
}
var display="none";
var i;
function showall()
{
    
var divTags=document.getElementsByTagName("div");
    
//alert(divTags[10].id.replace("DV",""));
    if( display=="none" )
    {
        
for(i=0;i<divTags.length;i++)
        {
            divTags[i].style.display
="block";
            eval(
"IMG"+divTags[i].id.replace("DV","")).src="images/btnDel.gif";
            display
="block"
        }
    }
    
else
    {
        
for(i=0;i<divTags.length;i++)
        {
            divTags[i].style.display
="none";
            eval(
"IMG"+divTags[i].id.replace("DV","")).src="images/btnAdd.gif";
            display
="none";
        }
    }
}
</script>

<SCRIPT LANGUAGE="JavaScript">
function checkAll(str)
{
  
var a = document.getElementsByName(str);
  
var n = a.length;
  
for (var i=0; i<n; i++)
  a[i].checked 
= window.event.srcElement.checked;
}
function checkItem(str)
{
  
var e = window.event.srcElement;
  
var all = eval("document.form0."+ str);
  
if (e.checked)
  {
    
var a = document.getElementsByName(e.name);
    all.checked 
= true;
    
for (var i=0; i<a.length; i++)
    {
      
if (!a[i].checked){ all.checked = falsebreak;}
    }
  }
  
else all.checked = false;
}
</SCRIPT>


</head>

<body>
      
<href="#" ONCLICK="show(IMG001,DV001)">
          
<img id="IMG001" src="manager.gif" border="0"></a>
          
<input type="Checkbox" name="All" onclick="checkAll('cb')">
 第一层

    
<!--Begin of 2-->
            
<DIV id='DV001' style='display:none'>
            
&nbsp;&nbsp;<img id="IMG0010" src="user.gif" border="0">
            
<input type="checkbox" name="cb" value="1" >
                101
                 
<br>      
            
&nbsp;&nbsp;<img id="IMG0010" src="user.gif" border="0">
            
<input type="checkbox" name="cb" value="1" >
                102
                
<!--End of 2-->
            
</div>    
 
<br>               
   
<href="#" ONCLICK="show(IMG002,DV002)">
       
<img id="IMG002" src="manager.gif" border="0">
       
</a>
       
<input type="Checkbox" name="fdasfdsafsd" onclick="checkAll('cbb')" >
 第二层

    
<!--Begin of 2-->
            
<DIV id='DV002' style='display:none'>
            
&nbsp;&nbsp;<img id="IMG0011" src="user.gif" border="0">
            
<input type="checkbox" name="cbd" value="1" id="cbb">
                201
                 
<br>      
            
&nbsp;&nbsp;<img id="IMG0011" src="user.gif" border="0">
            
<input type="checkbox" name="cbd" value="1" id="cbb">
                202
                
<!--End of 2-->
   
</div>    
</body>
</html>




2.eval函数用法
这次碰到一个问题,就是动态获取某个id的值,比如document.formX.idX.value,其中idX是动态的,所以直接写无法获得,会提示找不到某变量,这时eval就派上用场了
比如
var myObj = "document.formX."+idX;
myObj.value 
= XXValue;

详细信息参考这里
这里再提供几个例子:
function simpleSwap()
{
 
var the_image = prompt("change parrot or cheese","");
 
var the_image_name = "window.document." + the_image;
 
var the_image_object = eval(the_image_name);
 the_image_object.src 
= "ant.gif";
}

function tophide(id)    //id indicates menu
{
    
if (top.topframeset.rows == "31,*")
    {
        top.topframeset.rows 
= "86,*";
        eval(id 
+ "_icon.src="/imgs/collapse_up.gif'");
        eval(id + 
"_icon.alt='Collapse The Head'");
        head.style.display = 
"block"
        }
    else
    {
        top.topframeset.rows = 
"31,*";
        eval(id + 
"_icon.src="/imgs/collapse_down.gif'");
        eval(id 
+ "_icon.alt='Expand The Head'");
        head.style.display 
= "none"
    }
}


posted @ 2006-05-16 22:39 Alex 阅读(457) | 评论 (2)编辑 收藏

仅列出标题
共15页: First 上一页 7 8 9 10 11 12 13 14 15 下一页