??xml version="1.0" encoding="utf-8" standalone="yes"?> and the compilation unit: This example illustrates six points:
呵呵Q我是没有能够全部答?/p>
另外一关于String intern的文章: http://laiseeme.javaeye.com/blog/102442package testPackage;
class Test {
public static void main(String[] args) {
String hello = "Hello", lo = "lo";
System.out.print((hello == "Hello") + " ");
System.out.print((Other.hello == hello) + " ");
System.out.print((other.Other.hello == hello) + " ");
System.out.print((hello == ("Hel"+"lo")) + " ");
System.out.print((hello == ("Hel"+lo)) + " ");
System.out.println(hello == ("Hel"+lo).intern());
}
}
class Other { static String hello = "Hello"; }
package other;
public class Other { static String hello = "Hello"; } 正确{案Qtrue true true true false true
String
object (§4.3.1).
String
object.
String
object.
]]>
作者:来自ITPUB论坛 2008-01-24
向大家介l一U很不错Q也是Linux中的权限理法?
定义a^b为:a的bơ方
假如Q我们ؓ每一个操作设定一个唯一的整数|比如Q?/p>
删除A---0
修改A---1
dA---2
删除B---3
修改B---4
dB---5
。。?/p>
理论上可以有N个操作,q取决于你用于储存用h限值的数据cd了?/p>
q样Q如果用h权限Q添加A---2;删除B---3;修改B---4
那用L权限?purview =2^2+2^3+2^4=28Q也是2的权的和?/p>
化成二进制可以表CZؓ11100
如果要验证用h否有删除B的权限,可以通过位与q算来实现?/p>
在Java里,位与q算q算W号?amp;
xQint value = purview &((int)Math.pow(2,3));
你会发现Q当用户有操作权限时Q运出来的l果都会{于q个操作需要的权限?
原理Q?/p>
位与q算Q顾名思义是对位q行与运:
以上面的式子ZQpurview & 2^3 也就是 28&8
它们化成二q制?/p>
11100
& 01000
-------------------
01000 == 8(十进? == 2^3
同理Q如果要验证是否有删除A---0的权?/p>
可以用:purview &((int)Math.pow(2,0));
卻I
11100
& 00001
------------------------
00000 == 0(十进? != 2^0
q种法的一个优Ҏ速度快。可以同时处理N个权限,讄NU角?
如果想验证是否同时有删除A---0和删除B---3的权?/p>
可以用purview&(2^0+2^3)==(2^0+2^3)?true:false;
讄多角色用戗根据权限值判断用L角色。。?/p>
下面提供一个java的单操作权限判断的代码:
//userPurview是用户具有的L?br /> //optPurview是一个操作要求的权限Z个整?没有l过权的!)
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用唯一的整?Java的intcd最多可以储?1个权限和.如果过Q可以选择其它数据cdQ而且不同模块Q用多个权? 变量.
׃不同的机器对?strong>多字节数?int 是采用4个byte保存数据Q?/strong>的存储方式不?可能?低字节向高字节存?也可能是从高字节向低字节存储,q样,?分析|络协议或文件格?/strong>,Z解决不同机器上的字节存储序问题,用bytecd来表C数据是合适的?strong>而通常情况?׃其表C的数据范围很小,Ҏ造成溢出,应避免用?/strong>
/**
* Convert an int to a byte array
*
* @param value int
* @return byte[]
*/
public static byte[] intToByteArray(int value) {
byte[] b = new byte[4];
// 使用4个byte表示int
for (int i = 0; i < 4; i++) {
int offset = (b.length - 1 - i) * 8; // 偏移?br> b[i] = (byte) ((value >> offset) & 0xFF); //每次?bit
}
return b;
}
/**
* Convert the byte array to an int starting from the given offset.
*
* @param b The byte array
* @param offset The array offset,如果byte数组长度是4Q则该gؓ0
* @return The integer
*/
public static int byteArrayToInt(byte[] b, int offset) {
int value = 0;
for (int i = 0; i < b.length; i++) {
int shift = (b.length - 1 - i) * 8;
value += (b[i + offset] & 0xFF) << shift;
}
return value;
}
public static void main(String[] args) {
byte[] bb=intToByteArray(255);
for(int i=0;i<bb.length;i++){
System.out.println(bb[i]);
}
}
输出l果Q?/p>
0
0
0
-1
q是补码的Ş式(10000001Q,取反?可以得到源码Q?1111111Q?
byte
data type is an 8-bit signed two's complement integer. It has a minimum value of -128 and a maximum value of 127 (inclusive). The byte
data type can be useful for saving memory in large arrays, where the memory savings actually matters. They can also be used in place of int
where their limits help to clarify your code; the fact that a variable's range is limited can serve as a form of documentation. short
data type is a 16-bit signed two's complement integer. It has a minimum value of -32,768 and a maximum value of 32,767 (inclusive). As with byte
, the same guidelines apply: you can use a short
to save memory in large arrays, in situations where the memory savings actually matters. int
data type is a 32-bit signed two's complement integer. It has a minimum value of -2,147,483,648 and a maximum value of 2,147,483,647 (inclusive). For integral values, this data type is generally the default choice unless there is a reason (like the above) to choose something else. This data type will most likely be large enough for the numbers your program will use, but if you need a wider range of values, use long
instead. long
data type is a 64-bit signed two's complement integer. It has a minimum value of -9,223,372,036,854,775,808 and a maximum value of 9,223,372,036,854,775,807 (inclusive). Use this data type when you need a range of values wider than those provided by int
. float
data type is a single-precision 32-bit IEEE 754 floating point. Its range of values is beyond the scope of this discussion, but is specified in section 4.2.3 of the Java Language Specification. As with the recommendations for byte
and short
, use a float
(instead of double
) if you need to save memory in large arrays of floating point numbers. This data type should never be used for precise values, such as currency. For that, you will need to use the java.math.BigDecimal class instead. Numbers and Strings covers BigDecimal
and other useful classes provided by the Java platform. double
data type is a double-precision 64-bit IEEE 754 floating point. Its range of values is beyond the scope of this discussion, but is specified in section 4.2.3 of the Java Language Specification. For decimal values, this data type is generally the default choice. As mentioned above, this data type should never be used for precise values, such as currency. boolean
data type has only two possible values: true
and false
. Use this data type for simple flags that track true/false conditions. This data type represents one bit of information, but its "size" isn't something that's precisely defined. char
data type is a single 16-bit Unicode character. It has a minimum value of '\u0000'
(or 0) and a maximum value of '\uffff'
(or 65,535 inclusive).
cd名称 |
cd定义 | cd取?/strong> |
boolean | 布尔?/td> | true, false |
byte | 8?strong>有符h?/strong> | 最?128Q最大?27 |
short | 16?strong>有符h?/strong> |
最?32768Q?215Q,最大?2767Q?15-1Q?/p> |
int | 32?strong>有符h?/strong> | 最?2147483648Q?231Q,最大?147483647Q?31-1Q?/td> |
long | 64?strong>有符h?/strong> |
-263~(263-1) |
float | 32位QҎ |
1.4E-45~3.4028235E38 |
double | 64位QҎ | 4.9E-324~1.7976931348623157E308 |
char | 16位Unicode字符 | |
取反Q?/strong>~x 与操作:AND x & y 或操作:OR 异或操作QXOR 左移操作QShift left x左移y位,Udq程中,高位会丢? 有符h右移操作QShift Right - Signed 无符h右移QShift Right - Unsigned 下面的例子显C如何将一个int数组通过UM操作压羃C个int内保存,其原理是在java语言中,intcd使用4 bytes来保存,因此对于需要压~的int数组Q其中的每一个int值的大小不能过255Q??ơ方-1Q,因此q只是一个实例: int [] aRGB = {0x56, 0x78, 0x9A, 0xBC}; // 是用16q制保存?U颜色?br> int color_val = aRGB[3]; 操作完的l果?6 78 9A BC 如果要从colorVal q原为int数组Q或者得到数l中的某个|只需要对colorVal q行相应的右UL作即可: int alpha_val = (colorVal >>> 24) & 0xFF; 参考资料:
- flips each bit to the opposite value.
- AND operation between the corresponding bits in x and y.
x | y
- OR operation between the corresponding bits in x and y.
x ^ y
- XOR operation between the corresponding bits in x and y.
x << y
- shifts x to the left by y bits. The high order bits are lost while zeros fill the right bits.
x >> y
- shifts x to the right by y bits. The low order bits are lost while the sign bit value (0 for positive numbers, 1 for negative) fills in the left bits.
x >>> y
- shifts x to the right by y bits. The low order bits are lost while zeros fill in the left bits regardless of the sign. 例子Q?/strong>
color_val = color_val | (aRGB[2] << 8); // Z压羃Q需要放|到color_val值的W二个字节位|上Q将aRGB[2] 左移到第二个byteQ同时与color_valq行或操作,下面同理
color_val = color_val | (aRGB[1] << 16);
color_val = color_val | (aRBG[0] << 24);
int red_val = (colorVal >>> 16) & 0xFF;
int green_val = (colorVal >>> 8) & 0xFF;
int blue_val = colorVal & 0xFF;
]]>
http://tech.it168.com/j/n/2007-03-05/200703051354348.shtml
PA作ؓ一对象持久化的标准,不但可以获得Java EE应用服务器的支持Q还可以直接在Java SE中用?/p>
介绍得很清楚的文?/p>
JPA概述
JPA(Java Persistence API)作ؓJava EE 5.0q_标准的ORM规范Q将得到所有Java EE服务器的支持。Sunq次吸取了之前EJB规范惨痛p|的经历,在充分吸收现有ORM框架的基上,得到了一个易于用、~性强的ORM规范。从目前的开发社区的反应上看QJPA受到了极大的支持和赞扬,JPA作ؓORM领域标准化整合者的目标应该不难实现?nbsp;
JPA通过JDK 5.0注解或XML描述对象Q关p表的映关p,q将q行期的实体对象持久化到数据库中Q图 1很好地描qCJPA的结构:
Sun引入新的JPA ORM规范Z两个原因Q其一Q简化现有Java EE和Java SE应用的对象持久化的开发工作;其二QSun希望整合对ORM技术,实现天下归一?nbsp;
JPA由EJB 3.0软g专家l开发,作ؓJSR-220实现的一部分。但它不囿于EJB 3.0Q你可以在Web应用、甚x面应用中使用。JPA的宗旨是为POJO提供持久化标准规范,由此可见Q经q这几年的实跉|索,能够q容器独立q行Q方便开发和试的理念已l深入h心了。目前Hibernate 3.2、TopLink 10.1.3以及OpenJpa都提供了JPA的实现?
JPA的M思想和现有Hibernate、TopLinkQJDO{ORM框架大体一致。ȝ来说QJPA包括以下3斚w的技术:
Z备䆾blogQ简单写了一个适用于blogjava{metaWeblog的blog备䆾工具Q功能:
Q?Q备份post的正文到本地
Q?Q备份正文中的图片、css文g到本?/p>
Q?Q基于以上两的步骤,修改相关的链接,实现本地脱机览
惛_了但是未实现的功能:
Q?Q评论无法保?/p>
Q?Q合适的话可以考虑以Eclipes RCP形式包装
Q?Q获取post的方法:使用MetaWeblog提供的API接口
metaWeblog.getRecentPosts (blogid, username, password, numberOfPosts) returns array of structs,
Each struct represents a recent weblog post, containing the same information that a call to metaWeblog.getPost would return.
If numberOfPosts is 1, you get the most recent post. If it's 2 you also get the second most recent post, as the second array element. If numberOfPosts is greater than the number of posts in the weblog you get all the posts in the weblog.
(2) 使用正则表达式分析获取下来的postQ解析出post中包含的css和图片文件的地址Q执行两步操?/p>
(3) 使用xml-rpc来简化远E调用过E的~程
Java's java.util.regex 包包括:PatterncRMatchercRMatchResult接口和PatternSyntaxException异常Q?/p>
character sequence
by interpreting a Pattern
. 同时q需要了解是CharSequenceQJDK 1.4定义的新的接口,它提供了String和StringBufferq两个类的字W序列的抽象
interface CharSequence {
charAt(int i);
length();
subSequence(int start, int end);
toString();
}
Z实现q个新的CharSequence接口QStringQStringBuffer以及CharBuffer都作了修改,很多的正则表辑ּ的操作都要拿CharSequence作参数?
Group是指里用括号括v来的Q能被后面的表达式调用的正则表达式?/p>
Group 0 表示整个表达式,group 1表示W一个被括v来的groupQ以此类推。所以;
A(B(C))D
里面有三个groupQgroup 0是ABCDQ?group 1是BCQgroup 2是C?
你可以用下述MatcherҎ来用groupQ?
使用group可以做到逐步~小匚w的范_直至_匚w的目的?
start( )和end( )Q如果匹配成功,start( )会返回此ơ匹配的开始位|,end( )会返回此ơ匹配的l束位置Q即最后一个字W的下标加一。如果之前的匚w不成?或者没匚w)Q那么无论是调用start( )q是end( )Q都会引发一个IllegalStateException?/p>
String str="abc efg ABC";
String regEx="a|f"; //表示a或f
Pattern p=Pattern.compile(regEx);
Matcher m=p.matcher(str);
boolean rs=m.find();
如果str中有regExQ那么rs为trueQ否则ؓflase。如果想在查找时忽略大小写,则可以写成Pattern p=Pattern.compile(regEx,Pattern.CASE_INSENSITIVE);
String regEx=".+\\\\(.+)$";
String str="c:\\dir1\\dir2\\name.txt";
Pattern p=Pattern.compile(regEx);
Matcher m=p.matcher(str);
boolean rs=m.find();
for(int i=1;i<=m.groupCount();i++){
System.out.println(m.group(i));
}
以上的执行结果ؓname.txtQ提取的字符串储存在m.group(i)中,其中i最大gؓm.groupCount();
String regEx="::";
Pattern p=Pattern.compile(regEx);
String[] r=p.split("xd::abc::cde");
执行后,r是{"xd","abc","cde"}Q其实分割时q有跟简单的ҎQ?
String str="xd::abc::cde";
String[] r=str.split("::");
String regEx="a+"; //表示一个或多个a
Pattern p=Pattern.compile(regEx);
Matcher m=p.matcher("aaabbced a ccdeaa");
String s=m.replaceAll("A");
l果?Abbced A ccdeA"
如果写成IZQ既可达到删除的功能Q比如:
String s=m.replaceAll("");
l果?bbced ccde"
下面的函数是一个实际应用的例子Q需求是需要将抓取的网中?lt;img src=''http://aa.bb.cc.com/images/**.jpg"> 中的地址Q保存到一个地址列表中(以供抓取囄使用Q,q将l对地址替换成本地的相对地址Q即<img src="images/**.jpg">?/p>
public static Map<String, String> getImagesURL(String description) {
Map<String, String> map = new HashMap<String, String>();
// img 的正则表辑ּ:匚w<img>标签
String imgPattern = "<\\s*img\\s+([^>]+)\\s*>";
Pattern pattern1 = Pattern.compile(imgPattern, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern1.matcher(description);
// img src元素的正则表辑ּQ匹配img标签内的src属?br />
String srcPattern = "\\s*src\\s*=\\s*\"([^\"]+)\\s*\"";
Pattern pattern2 = Pattern.compile(srcPattern, Pattern.CASE_INSENSITIVE);
while (matcher.find()) {
//group()q回W合表达式的内容
Matcher matcher2 = pattern2 .matcher(matcher.group());
// 一定要find(),q是实际的匹配动?br />
if (matcher2.find()) {
String src = matcher2.group();
log.info(src);
int i2 = src.lastIndexOf('/');
int i1 = src.indexOf("http");
if (i1 != -1) {
map.put(src.substring(i2 + 1, src.length() - 1), src
.substring(i1, src.length() - 1));
}
}
}
log.debug("囄Q? + map);
return map;
}
整体思\是先匚w到img标签Q然后匹配src属性,q修改src的属?/p>
"<\\s*img\\s+([^>]+)\\s*>" 的解释:
\\s* :0 或多个空?nbsp; \\s+: 臛_一个空?/p>
([^>]+)Q指的是?gt;的所有的字符Q至一?/p>
字符集类
. 表示L一个字W?
[abc] 表示字符aQbQc中的L一?与a|b|c相同)
[^abc] 除aQbQc之外的Q意一个字W?否定)
[a-zA-Z] 从a到z或A到Z当中的Q意一个字W?范围)
[abc[hij]] a,b,c,h,i,j中的L一个字W?与a|b|c|h|i|j相同)(q)
[a-z&&[hij]] h,i,j中的一?交集)
\s I格字符(I格? tab, 换行, 换页, 回R)
\S 非空格字W?[^\s])
\d 一个数字,也就是[0-9]
\D 一个非数字的字W,也就是[^0-9]
\w 一个单词字W?word character)Q即[a-zA-Z_0-9]
\W 一个非单词的字W,[^\w]
字符c:
B 字符B
\xhh 16q制?xhh所表示的字W?
\uhhhh 16q制?xhhhh所表示的Unicode字符
\t Tab
\n 换行W?
\r 回RW?
\f 换页W?
\e Escape
逻辑q算W?/strong>
XY X 后面跟着 Y
X|Y X或Y
(X) 一?要匹配的l?capturing group)". 以后可以用\i来表C第i个被匚w的组?
边界匚wW?/strong>
^ 一行的开?
$ 一行的l尾
\b 一个单词的边界
\B 一个非单词的边?
\G 前一个匹配的l束
数量表示W?/strong>
"数量表示W?quantifier)"的作用是定义模式应该匚w多少个字W?
Greedy Reluctant Possessive 匚w
X? X?? X?+ 匚w一个或零个X
X* X*? X*+ 匚w零或多个X
X+ X+? X++ 匚w一个或多个X
X{n} X{n}? X{n}+ 匚w正好n个X
X{n,} X{n,}? X{n,}+ 匚w臛_n个X
X{n,m} X{n,m}? X{n,m}+ 匚w臛_n个,臛_m个X
要想q一步学习正则表辑ּQ徏议看Mastering Regular Expression, 2nd EditionQ作者Jeffrey E. F. Friedl (O’Reilly, 2002)?
"Regular Expressions and the Java Programming Language," Dana Nourie and Mike McCloskey (Sun Microsystems, August 2002) presents a brief overview of java.util.regex, including five illustrative regex-based applications:
http://developer.java.sun.com/developer/technicalArticles/releases/1.4regex/
http://www.aygfsteel.com/beike/archive/2006/04/28/43832.html
http://wcjok.bokee.com/4293762.html
http://www.xd-tech.com.cn/blog/article.asp?id=34
一般的情况下我们都是用IE或者Navigator览器来讉K一个WEB服务器,用来览面查看信息或者提交一些数据等{。所讉K的这些页面有的仅仅是一些普通的面Q有的需要用L录后方可使用Q或者需要认证以及是一些通过加密方式传输Q例如HTTPS。目前我们用的览器处理这些情况都不会构成问题。不q你可能在某些时候需要通过E序来访问这L一些页面,比如从别人的|页中“偷”一些数据;利用某些站点提供的页面来完成某种功能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服务器中的一个很常见的“顽固”!再有如通过HTTP来上传文件呢Q不需要头|q些问题有了“它”就很容易解决了Q?
我们不可能列举所有可能的固Q我们会针对几种最常见的问题进行处理。当然了Q正如前面说到的Q如果我们自׃?java.net.HttpURLConnection来搞定这些问题是很恐怖的事情Q因此在开始之前我们先要介l一下一个开放源码的目Q这个项目就?Apache开源组l中的httpclientQ它隶属于Jakarta的commons目Q目前的版本?.0RC2。commons下本来已l有一个net的子目Q但是又把httpclient单独提出来,可见http服务器的讉Kl非易事?
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(" //使用POSTҎ //HttpMethod method = new PostMethod(" client.executeMethod(method); //打印服务器返回的状? System.out.println(method.getStatusLine()); //打印q回的信? System.out.println(method.getResponseBodyAsString()); //释放q接 method.releaseConnection(); } 在这个例子中首先创徏一个HTTP客户?HttpClient)的实例,然后选择提交的方法是GET或?POSTQ最后在HttpClient实例上执行提交的ҎQ最后从所选择的提交方法中d服务器反馈回来的l果。这是使用HttpClient的基本流E。其实用一行代码也可以搞定整个请求的q程Q非常的单! 2Q?以GET或者POST方式向网|交参? 其实前面一个最单的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.*; /** * 提交参数演示 * 该程序连接到一个用于查询手机号码所属地的页? * 以便查询LD?330227所在的省䆾以及城市 * @author Liudong */ public class SimpleHttpClient { public static void main(String[] args) throws IOException { HttpClient client = new HttpClient(); client.getHostConfiguration().setHost(" HttpMethod method = getPostMethod();//使用POST方式提交数据 client.executeMethod(method); //打印服务器返回的状? System.out.println(method.getStatusLine()); //打印l果面 String response = new String(method.getResponseBodyAsString().getBytes("8859_1")); //打印q回的信? 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; } } 在上面的例子中页?a >http://www.imobile.com.cn/simcard.php 3Q?处理面重定? 在JSP/Servlet~程中response.sendRedirectҎ是使用HTTP协议中的重定向机制。它与JSP中的<jsp:forward ?gt;的区别在于后者是在服务器中实现页面的跌{Q也是说应用容器加载了所要蟩转的面的内容ƈq回l客LQ而前者是q回一个状态码Q这些状态码的可能D下表Q然后客Ld需要蟩转到的页面的URLq新加载新的页面。就是这样一个过E,所以我们编E的时候就要通过 HttpMethod.getStatusCode()Ҏ判断q回值是否ؓ下表中的某个值来判断是否需要蟩转。如果已l确认需要进行页面蟩转了Q那么可以通过dHTTP头中的location属性来获取新的地址? 状态码 下面的代码片D|C如何处理页面的重定? 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Ҏ重定向到另外一个页面用来测试上面的例子? 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个会话标识来获取对应的会话信息? 对于需要用L录的|站Q一般在用户d成功后会用戯料保存在服务器的会话中,q样当访问到其他的页面时候,应用服务器根据浏览器送上的Cookie中读取当前请求对应的会话标识以获得对应的会话信息Q然后就可以判断用户资料是否存在于会话信息中Q如果存在则允许讉K面Q否则蟩转到d面中要求用戯入帐号和口oq行d。这是一般用JSP开发网站在处理用户d的比较通用的方法? 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程? /* * 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表单的示? * @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服务? 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格式数据的例? */ 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中读? post.setRequestBody(new FileInputStream(input)); if (input.length() < Integer.MAX_VALUE) post.setRequestContentLength(input.length()); else post.setRequestContentLength(EntityEnclosingMethod.CONTENT_LENGTH_CHUNKED); // 指定h内容的类? 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? 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所在的路径? 7Q?讉K启用认证的页? 我们l常会碰到这L面Q当讉K它的时候会弹出一个浏览器的对话框要求输入用户名和密码后方可,q种用户认证的方式不同于我们在前面介l的Z表单的用戯n份验证。这是HTTP的认证策略,httpclient支持三种认证方式包括Q基本、摘要以及NTLM认证。其中基本认证最单、通用但也最不安全;摘要认证是在HTTP 1.1中加入的认证方式Q而NTLM则是微Y公司定义的而不是通用的规范,最新版本的NTLM是比摘要认证q要安全的一U方式? 下面例子是从httpclient的CVS服务器中下蝲的,它简单演C如何访问一个认证保护的面Q? 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( " "realm", new UsernamePasswordCredentials("username", "password") ); GetMethod get = new GetMethod(" 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?pre>MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
HttpClient client = new HttpClient(connectionManager);
以后管讉Kclient实例卛_?
参考资料:
httpclient首页Q?nbsp; http://jakarta.apache.org/commons/httpclient/
}
对应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
关于NTLM是如何工作: http://davenport.sourceforge.net/ntlm.html
]]>
1、底层的直接与文件系l或者硬件打交道的类(充当数据源的c?Q?
包括InputStream和OutPutStream两大c,分别用于输入和输出,数据源可以是bytes arrayQString对象Qfile文gQstream序列{:
{,具体参看下面的java iocd
2、充当装饰功能的ioc?通过装饰底层的类来实现更高的功能,l承自FilterOutputStream/FilterOutputStreamQ包括:
{,具体参看下面的java iocd
使用FilterOutputStream/FilterOutputStreamӞ首先创徏一个数据源IOQ然后根据需要的功能创徏装饰cioQ其构造函数的参数为已创徏的数据源io?
同时Qjava的IO体系又可以分成:inputStream/outputStream和reader/writer两类Q?
Q?Q?Reader/Writer是面向Unicode字符的(CharactersQ?
Q?Q?InputStream/OutputStream是直接面向字节的QbytesQ?
Reader/Writerl承体系之所以存在,最重要的原因是Z国际化,旧式I/O stream 的承体pM仅支?-bit byte streamQ而且无法处理16-bit unicode 字符。由于unicode被用于字W国际化Q所以加入Reader/Writer以便在所有的io动作上提供对unicode的支持?
几乎所有的java io stream classes都有相应的Reader和Writer来提供对unicode的支持,但是在某些场合,使用byte-oriented InputStream和OutPutStream才是正取的方法,最合理的方式是可能先试使用Read和WriterQ其ơ才使用byte-oriented库?
InputStreamReader和OutputStreamWriterQ可以把一个以字节为导向的stream转换成一个以字符为导向的stream?
Java 1.0 classQbyte orientedQ?nbsp; Java 1.1 class(unicode character oriented)
装饰前的行ؓ
InputStream Reader 转换器:InputStreamReader
OutputStreamReader Writer 转换器:OutputStreamWriter
FileInputSream FileOutputStream
FileReader FileWriter
StringBufferInputStream StringReader/StringWriter
ByteArrayInputStream ByteArrayOutputStream
CharArrayReader CharArrayWriter
装饰后的行ؓ
BufferedInputStream BufferedOutputStream
BufferedReader BufferedWriter
PrintStream PrintWriter
DataInputStream和DataOutputStream
Java中除了二q制文g和用文本文件外q有ZData的数据操作,q里的Data指的是Java的基本数据类型和String。基本数据类型包括byte、int、char、long、float、double、boolean和short?/b>
例子Q?/b>
protected void connect (Socket socket)
throws IOException, SocketException
{
this.socket = socket;
applyTimeout();
serverIn = new DataInputStream (
new BufferedInputStream (socket.getInputStream ())
);
serverOut = new DataOutputStream(
new BufferedOutputStream(socket.getOutputStream(), 2048)
);
usable = true;
cnt[CONNECT]++;
setChanged();
notifyObservers();
}
在DataInputStream和DataOutputStream两个cM的方法都很简单,基本l构为readXXXX()和writeXXXX()其中XXXX代表基本数据cd或者String?/p>
Document doc = new Document(new Element("rootElement"))
或?
Document doc = new Document();
// 根元?/p>
Element root = new Element("persons");
doc.addContent(root);
// add person
Element person = new Element("person").setText("test1");
root.addContent(person);
//add person 2
person = new Element("person").setText("test2");
root.addContent(person);
另外一U方式:
Document doc = new Document(new Element("family")
.addContent(new Element("mom"))
.addContent(new Element("dad").addContent("kidOfDad")));
一般而言Q用org.jdom.input.SAXBuilder更快Q推荐用,而org.jdom.input.DOMBuilder适用于已l存在DOM对象的场合?
SAXBuilder b = new SAXBuilder();
// Create the document
Document doc = b.build(new File(xmlfilename));
// Get a List of direct children as Elements
List allChildren = element.getChildren();// Get all direct children with a given name
List namedChildren = element.getChildren("name");// Get the first kid with a given name
Element kid = element.getChild("name");
List allChildren = element.getChildren();
// Remove the fourth child
allChildren.remove(3);
// Remove all children named "jack"
allChildren.removeAll(element.getChildren("jack"));或?br /> element.removeChildren("jack");
// Add a new child
allChildren.add(new Element("jane"));或?br /> element.addContent(new Element("jane"));
// Add a new child in the second position
allChildren.add(1, new Element("second"));
// d属性:
String value =table.getAttributeValue("width");// table 是element
// 也可以在d属性的同时q行cd转换
try {
value =table.getAttribute("border").getIntValue();
}
catch (DataConversionException e) { }
// 讄属?
// Add an attribute
table.addAttribute("vspace", "0");
// Add an attribute more formally 比较正式的写?br /> table.addAttribute(new Attribute("name", "value"))
// Remove an attribute
table.removeAttribute("border");
// Remove all attributes U除所有属?br /> table.getAttributes().clear();
比如<description>A cool demo</description>Q则可以直接获取内容
String content = element.getText();
// U除多余的空白,字符串前后的I白Q不会移除字W串内部的空?
element.getTextNormalize();
// This blows away all current content
element.setText("A new description");
//Special characters are interpreted correctly: Ҏ字符可以被正地转义
element.setText("<xml> content");
// 创徏cdata元素
element.addContent(new CDATA("<xml> content"));
XMLOutputter cȝ来实现XML文g的输出,在创建的时候需要一个Format对象来格式化XML文gQFormat对象是一个工厂类Q提供几个静态的工厂Ҏ来提供一些常规的XML格式Q比如getPrettyFormat()Q?
XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
try {
outputter.output(doc, new FileOutputStream(new File("xmlfile/persons.xml")));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Namespace xhtml = Namespace.getNamespace("xhtml", “http://www.w3.org/1999/xhtml”);
List kids = element.getChildren("p", xhtml);
Element kid = element.getChild("title", xhtml);
Attribute height = element.getAttribute("height", xhtml);
附录QJava下XML~程接口比较QDOM SAX JDOM JAXPQ网l装载)
一、DOM Q文档对象模型)
?XML 文档的已解析版本定义了一l接口。解析器d整个文档Q然后构Z个驻留内存的树结构,然后代码可以?DOM 接口来操作这个树l构?br /> 优点Q整个文档树在内存中Q便于操作;支持删除、修攏V重新排列等多种功能Q?br /> ~点Q将整个文档调入内存Q包括无用的节点Q,费旉和空_
使用场合Q一旦解析了文档q需多次讉Kq些数据Q?br /> g资源充Q内存、CPUQ?br /> 二、SAX
决DOM的问题,出现了SAX?br /> SAX Q事仉动。当解析器发现元素开始、元素结束、文本、文档的开始或l束{时Q发送事ӞE序员编写响应这些事件的代码Q保存数据?br /> 优点Q不用事先调入整个文档,占用资源;
SAX解析器代码比DOM解析器代码小Q适于AppletQ下?br /> ~点Q不是持久的Q事件过后,若没保存数据Q那么数据就丢了Q?br /> 无状态性;从事件中只能得到文本Q但不知该文本属于哪个元素;
使用场合QApplet;
只需XML文档的少量内容,很少回头讉KQ?br /> 机器内存;
三、JDOM
为减DOM、SAX的编码量Q出CJDOMQ?br /> 优点Q?0-80原则Q极大减了代码?br /> 使用场合Q要实现的功能简单,如解析、创建等Q但在底层,JDOMq是使用SAXQ最常用Q、DOM、Xanan
四、JAXP
为多个XML解析器提供了l一~程接口
更换解析器,不用更改代码
使用场合Q若不用JdomQ一般徏议用JAPXQ将代码与各U解析器的实现细节隔R?/p>
• JDOM should be straightforward for Java programmers
– Use the power of the language (Java 2)
– Take advantage of method overloading, the Collections APIs, reflection, weak references
– Provide conveniences like type conversions
• JDOM should hide the complexities of XML wherever possible
– An Element has content, not a child Text node with content
– Exceptions should contain useful error messages
– Give line numbers and specifics, use no SAX or DOM specifics
• JDOM should integrate with DOM and SAX
– Support reading and writing DOM documents and SAX events
– Support runtime plug-in of any DOM or SAX parser
– Easy conversion from DOM/SAX to JDOM
– Easy conversion from JDOM to DOM/SAX
• JDOM should stay current with the latest XML standards
– DOM Level 2, SAX 2.0, XML Schema
• JDOM does not need to solve every problem
– It should solve 80% of the problems with 20% of the effort
– We think we got the ratios to 90% / 10%
• Classes for reading XML from existing sources:
– DOMBuilder
– SAXBuilder
• Also, outside contributions in jdom-contrib:
– ResultSetBuilder
– SpitfireBuilder
• New support for JAXP-based input
– Allows consistency across applications
– Builders pick up JAXP information and user automatically
– Sets stage for JAXP version.next
Classes for writing XML to various forms of output:
– DOMOutputter
– SAXOutputter
– XMLOutputter
Also, outside contributions in jdom-contrib:
– JTreeOutputter
• TRaX is now supported in org.jdom.transform
– Supports XSLT transformations
– Defines Source and Result interfaces
– JDOMSource
– JDOMResult
• Normally XML Document -> SAXBuilder ->XMLOutputter
完整的pdf下蝲地址Q?span style="font-weight: bold;">JDOM: How It Works,and How It Opened the Java Processby Jason Hunter
http://www.aygfsteel.com/Files/cherishchen/JDOM%20How%20It%20Works.zip
首先q是重温?/span>java的异怽pȝ构,如图所C,所有异常的ҎThrowableQ异常又分ؓchecked exception?/span>unchecked exceptionQ?/span>RuntimeException是属于unchecked exceptionQ?/span>JVM 一旦捕捉到unchecked exception ׃l止当前q行的程序,q在console中打出错误信息?/span>
ption hierarchy
Client's reaction when exception happens |
Exception type |
Client code cannot do anything |
Make it an unchecked exception |
Client code will take some useful
recovery action based on information in exception |
Make it a checked exception |
另外Q?/span>unchecked exceptions的优点在于不客户端代码显式地处理他们Q异常可以一直往上传递(除非需要{化异常,否则异常不需要在中间被捕捉,节省了很多的try{}catch()Q代码更加简z)Q直Cx捉处理他们,Q有Z问,如何不强制客L处理他们Q比如像checked exceptionsq样Q不处理是语法错误Q如何保证异常能够得到处理呢Q在q点上,java提供的完善的文档机制Q通过API客户端程序员可以很方便地知道他调用的Ҏ可能会抛Z么异常,一个负责h的程序员应该对其进?/span>catch和处理)Q?/span>Java API提供了很多的unchecked exceptionsQ比?/span>NullPointerException
, IllegalArgumentException
, and IllegalStateException
Q?span lang="EN-US">java提供的标准的
unchecked exceptions是值得推荐的,q样的好处在于代码更加zƈ可以减少代码对内存的占用?/span>
Java异常应该可能地推迟处理Q除非要转化异常Q重新抛出,否则最好不要处理,而是留给最后能够处理异常的地方?/span>
通过为方法添?/span>throws声明Q可以将处理异常的责M递到更高的层ơ。在声明哪些需要抛出的时候,应该可能地详细。这样做的目的是可以?/span>API中详l地表述Ҏ可能会出现的异常Q从而让调用该方法的clinetE序员做好处理异常的准备Q比如对于代码通过throws语句详细地声明了可能会抛出的异常Q这栯用该Ҏ的程序员׃知道会有什么样的异怼发生?/span>
throws IllegalArgumentException,
FileNotFoundException, IOException
{
if (filename == null)
{
throw new IllegalArgumentException
("filename is null");
} //if
//
InputStream in = new FileInputStream(filename);
//
}
从语法上ԌIllegalArgumentException?/span>unckecked exception 是不需要声明的Q但是ؓ了从文档的角度考虑Q最好还是加上,q样可以让调用这个方法的E序员知道,q个Ҏ会可能抛异常Q需要加以捕捉和处理?/span>
不管如何Q最l程序肯定是要对异常q行处理的,否则会导致不定情况的发生,但是选择异常处理的位|却是有技巧的Q通常要么是程序在q些地方从异怸恢复、l执行且不会Dq一步异常的发生Q要么是在这些地方能为用户反馈特定的信息Q比如,如何避免异常的发生或者如何从异常中恢复。因此,对于有用L面层的程序,异常的捕捉和处理推q到UI层是有好处的Q在UI层可以用对话框或者其他方式提C用户出现异常?/span>
Best Practices for Exception Handling by Gunjan Doshi
Three Rules for Effective Exception Handling by Jim Cushing
举例来说Q如果图中的点表示城市Q而边上的权重表示著城市间开车行l的距离?Dijkstra法可以用来扑ֈ两个城市之间的最短\径?/p>
Dijkstra法的输入包含了一个有权重的有向图GQ以及G中的一个来源顶?em>S?我们?em>V表示G中所有顶点的集合。图中的每一个边Q都是两个顶Ҏ形成的有序元素对?u,v)表示从顶?em>u?em>v有\径相q?假设E?/em>所有边的集合,而边的权重则由权重函?em>w: E → [0, ∞]定义?因此Q?em>w(u,v)是从顶?em>u到顶?em>v的非负花费?cost)?边的p可以惛_成两个顶点之间的距离。Q两点间\径的p|是该\径上所有边的花费值d?已知?em>V中有点s?em>tQDijkstra法可以扑ֈs?em>t的最低花费\?i.e. 最短\??q个法也可以在一个图中,扑ֈ从一个顶?em>sCQ何其他顶点的最短\径?/p>
q个法是通过为每个顶?em>v保留目前为止所扑ֈ的从s到v的最短\径来工作的。初始时Q源点s的\径长度D赋ؓ0Q?em>d[s]=0Q, 同时把所有其他顶点的路径长度设ؓ无穷大,卌C我们不知道M通向q些点的\径(对于V中所有顶?em>v?em>s?em>d[v]= ∞Q。当法l束Ӟd[v]中储存的便是?em>s?em>v的最短\径,或者是无穷大(如果路径不存在的话)?
Dijstra法的基操作是边的拓展:如果存在一条从u?em>v的边Q那么从s到v的最短\径可以通过边(u,v)d到s到u的尾部来拓展。这条\径的长度是d[u]+w(u,v)。如果这个值比目前已知?em>d[v]的D,我们可以用新值来替代当前d[v]中的倹{拓展边的操作一直执行到所有的d[v]都代表从s到v最短\径的p。这个算法经q适当的组l因而当d[u]辑ֈ它最l的值的时候,每条?u,v)都只被拓展一ơ?/p>
法l护两个点集S和Q。集合S保留了我们已知的所有d[v]的值已l是最短\径的值顶点,而集合Q则保留其他所有顶炏V集合S初始状态ؓI,?
后每一步都有一个顶点从QUd到S。这个被选择的顶ҎQ中拥有最的d[u]值的点。当一个顶点u从Q中{Ud了S中,法Ҏ条外接边(u,v)q?
行拓展?/p>
Spring推荐事务的控制在service层实玎ͼ而不是像单独使用hibernate那样Q在dao层实玎ͼq样的好处在于更好地支持declear方式的事务(service层通常提供接口Q这样可以针Ҏ口来定义事务{略Q而不是针对具体的service实现Q因此可以很方便地替换service的实玎ͼ而不需要修改事务的配置Q,更加灉|。同Ӟ可以更加斚w自然地实现全局事务的控制?/span>
举例如下Q?/p>
service接口
spring.xmlQ注意在声明事务的时候,是针对service接口的,而不是针对service实现?br>
对于横跨多个Hibernate SessionFacotry的分布式事务Q只需单地?/span> JtaTransactionManager 同多?/span> LocalSessionFactoryBean 的定义结合v来作Z务策略。你的每一?/span>DAO通过bean属性得到各自的 SessionFactory 引用。在需要进行跨多个数据库的事务操作Ӟ只需要定义一?/span>service层,使用 JtaTransactionManager 作ؓ事务{略Q横跨多?/span>DAO和多?/span>session
factories来划分事务,而不需要特D的处理?/span>
jPDL是一U直观的程语言Q用以展现商业逻辑的处理过E。jPDL包含的概忉|及Q务、异步通讯状态、定时器、自动执行的动作{,为此Qؓ了整合上q行为,jPDL提供了强大、可扩展的控制流机制?/p>
implementation technique for graph based execution languagesQ?/p>
The strategy on how graph execution can be implemented on top of an OO programming language. For those who are familiar with design patterns, it's a combination of the command pattern and the chain of responsibility pattern.
1、Transitions 可以理解入和d节点的箭_应该存在多个Transitions q入一个节点和一个节Ҏ多个d?strong>Transitions 的情?/p>
the structure of the graph is represented with the classes Node and TransitionQ?tt>Transition是具有方向性的
transitions are able to pass the execution from a source node to a destination node with the method take.
2、execution Q类似petri中的标记Q是变迁qA的前?/strong>
An execution (also known as a token) is represented with a class called Execution. An execution has a reference to the current node.
3、Node
A node is a command and has an execute method. Subclasses of Node are supposed to override the execute method to implement some specific behaviour for that node type.
When an execution arrives in a node, that node is executed. The Node's execute method is also responsible for propagating the execution. Propagating the execution means that a node can pass the execution that arrived in the node over one of its leaving transitions to the next node.
When a node's execute method does not propagate the execution, it behaves as a wait state.
Also when a new execution is created, it is initialized in some start node and then waits for an event.
An event is given to an execution and it can trigger the execution to start moving. If the event given to an execution relates to a leaving transition of the current node, the execution takes that transition. The execution then will continue to propagate until it enters another node that behaves as a wait state.
So now we can already see that the two main features are supported : wait states and a graphical representation. During wait states, an Execution just points to a node in the graph
4、Actions
An Action is a command with an execute method. Actions can be associated with events.
The default propagation of execution is synchronous.
JGAP (pronounced "jay-gap") is a Genetic Algorithms and Genetic Programming component provided as a Java framework. It provides basic genetic mechanisms that can be easily used to apply evolutionary principles to problem solutions. See the examples for a demonstration or watch out the graphical tree that can be created with JGAP for found solutions of genetically evolved programs.
JGAP was designed to be very easy to use "out of the box", while also designed to be highly modular so that more adventurous users can easily plug-in custom genetic operators and other sub-components.
Documentation, quality and stability of code are the top concerns when developing JGAP. You find really many unit tests packaged with JGAP, extensive Javadocs, and quite a lot of examples. Compare JGAP with other projects! Feedback is always welcome.
最q一个桌面的E序需要用嵌入式数据库,选择了很多不同的嵌入式数?最l选择了H2Q性能是一个很重要的原因,下图是h2提供的Performance的比较图
http://www.h2database.com/html/images/performance.png
h2是Thomas Mueller提供的一个开源的、纯java实现的关pL据库Q在google上面有讨论组h2-database@googlegroups.comQThomas Mueller也非常热情,回答问题非常及时?/p>
下面说下我最l选择h2的原因:
Q?Q性能、小?/p>
Q?Q同时支持网l版和嵌入式版本Q另外还提供了内存版
Q?Q有比较好的兼容性,支持相当标准的sql标准Q实际上也不存在一个数据库能够100%W合标准Q?/p>
Q?Q提供了非常友好的基于web的数据库理界面
Q?Q支持hibernate
This database supports the following transaction isolation levels:
When using the isolation level 'serializable', dirty reads, non-repeatable reads, and phantom reads are prohibited.
Q?Q合理用checked exception和unchecked exceptionQ说明用这两种异常的原则的文章很多Q不多罗嗦了
Q?Q异常的转换Q如果需要,可以底层的异常包装为包含更多含义的自定义异帔R新抛出(包括checked?/span>unchecked的自定义异常体系Q,自定义异怸仅仅需要包含原始的异常信息Q还要包含一些特定的含义和处理方法;
(3) 异常的抛出,量不要在中间层处理异常Q要么在异常发生的地方处理,要么抛出Q推q到由最l调用层来处理,比如?span style="font-size: 10pt;">与用L接打交道?span lang="EN-US">UI?/span>Q捕捉异常,q以错误信息框、对话框{信息蝲体反馈良好的信息l用?/span>
范例Q?span lang="EN-US">
Q?span lang="EN-US">1Q定义自定义的异常:包括了两个构造函敎ͼ一个用于提供默认的异常信息Q一个供E序员添加更加详l的异常信息Q这个异常,可以用来装所有的底层异常Q但是一般在逻辑上更加清楚,可以增加不同的自定义异常Q比如数据库处理异常、文件处理异常、网l处理异常等
Q?/span>2Q用自定义的异常封装底层异常:
Q?span lang="EN-US">3Q在用户界面部分的处理,通过MessageDialog反馈l用h的信息Q?/span>
select calldate,
sum(case class when '1' then callcount else 0 end)
as Ac?span lang="EN-US">,
sum(case class when '2' then callcount else 0 end)
as Bc?span lang="EN-US">,
sum(case class when '3' then callcount else 0 end)
as Cc?