Factory, Abstract Factory, Factory Method, 和Builder

Factory, Abstract Factory, Factory Method, 和Builder 选这4个模式在一起讨论首先是因为它们的功能比较类似,都是用来制造对象实例的,从归类来说,他们都属于制造类模式(creational patterns),其次她们们在工作中比较常用,由于功能太过相似,往往导致在某个实际问题上让人举棋不定,似乎选哪个都可以解决问题,可是真的选择某个模式后,又会发现不是完全合适。今天我们就来讨论讨论在什么情况下选择什么模式来解决问题比较合适。 考虑到不是所有的朋友都对以上提到的4种模式都了如指掌,在开始讨论之前先简单的介绍一下这4个模式,对这4种模式熟悉的朋友也可以顺便回顾一下。请注意,这里我只会做简短的介绍,如果要比较深入地了解她们的话,还请去看模式相关的书籍,比较浅显易懂的我推荐 “Head First Design Patterns”。如果要在工作中反复参考的我推荐 “Applied Java Patterns”。那本经典的GOF Design Patterns由于写的时间比较早,举的例子不太适合现在的软件开发,我个人认为初学者或者是没有太多时间的朋友没有必要去读那本书,尽管她的确是经典。 Factory Pattern 中文叫工厂模式, 这个是我们在面向对象编程中最常用的模式之一了,她的主要功能就是制造对象,也正是这个原因才叫她为工厂模式,工厂干什么?生产产品。通常情况而言某个工厂所生产的产品总是一个系列的不同种类,大体上相同,细节上有差异。 图1 展示了一个非常简单的例子,通常CarFactory类会提供下列方法来生产车辆, 如代码片断1所示: public class CarFactory { public Car createBusinessCar() {….} public Car createSportCar() {…} } 代码片断 1 http://www.wiloon.com/wp-content/uploads/2012/10/x1pBG_wmiiVq4fKhMkEoTbjopPcKCE3u0uJjfqcYoYvgBeu5PDT5UndtcNdt48rY80PV_fd8Ce5pLpHavAj520cgRoVa4EmOhjE5VNS7GnBHl126UUuSSCrcM8YMFLVb3mp_UsivKRLJ1HKESriM5FDQA-1.gif 图1 Factory Pattern Abstract Factory Pattern 中文叫抽象工厂模式,顾名思义,就是把工厂模式在进一步抽象化,进一步细化。我们继续沿用上面的例子,不过这次增加产品的种类,如图2所示。由于我们增加了一层分类,当我们要生产某种车的时候就需要询问要哪种车, 商用还是跑车?不然的话就要增加create方法,如果分类多了,create方法就会成几何数量增长。 public class CarFactory { public Car createBusinessBMWCar() {….} public Car createBusinessBenzCar() {…} public Car createSportBMWCar() {….} public Car createSportBenzCar() {…} } 代码片断 2 图2 bad Factory Pattern ...

2012-10-11 · 2 min · 236 words · -

JAVA 浅复制与深复制/深克隆/深拷贝

JAVA 浅复制与深复制/深克隆/深拷贝 1.浅复制与深复制概念 ⑴浅复制 (浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。 ⑵深复制 (深克隆) 被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。 2.Java的clone()方法 ⑴clone方法将对象复制了一份并返回给调用者。一般而言,clone () 方法满足: ①对任何的对象x,都有x.clone() !=x//克隆对象与原对象不是同一个对象 ②对任何的对象x,都有x.clone().getClass()= =x.getClass()//克隆对象与原对象的类型一样 ③如果对象x的equals()方法定义恰当,那么x.clone().equals(x)应该成立。 ⑵Java中对象的克隆 ①为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。 ②在派生类中覆盖基类的clone()方法,并声明为public。 ③在派生类的clone()方法中,调用super.clone()。 ④在派生类中实现Cloneable接口。 请看如下代码: class Student implements Cloneable { String name; int age; Student(String name,int age) { this.name=name; this.age=age; } public Object clone() { Object o=null; try { o=(Student)super.clone();//Object中的clone()识别出你要复制的是哪一个对象。 } catch(CloneNotSupportedException e) { System.out.println(e.toString()); } return o; } public static void main(String[] args) { Student s1=new Student("zhangsan",18); Student s2=(Student)s1.clone(); s2.name="lisi"; s2.age=20; System.out.println("name="+s1.name+","+"age="+s1.age);//修改学生2后,不影响学生1的值。 } } 说明: ...

2012-10-09 · 2 min · 369 words · -

java Delegate

java Delegate 委派,也可以叫做委托,从字面上来理解的话,应该是委托其他类做事情而自己不做或者只做一部分工作;而回调,就是调用自己的方法。 在 java 中,这两种机制很类似,你姑且可以认为它们就是一码事。 java 中,实现委派和回调都是通过接口来实现的。下面举个小例子吧! 该例子是这样的 (只是一个例子) : ProfessionalWorker 、SparetimeWorker 负责发射 Rocket,Rocket 类通过接口 IRocketDelegate 委派 (或者说是回调) ProfessionalWorker 、SparetimeWorker自己发射。 总之,Rocket不做具体的事情。看实例代码: IRocketDelegate.java源码 public interface IRocketDelegate { public abstract long startAtTime(); public abstract long endAtTime(); public abstract void sendDidFail(); } 共有三个方法,分别是用于计算 Rocket 发射时间、计算 Rocket 发射完毕的时间以及发送是否失败的。 Rocket.java源码 public class Rocket { IRocketDelegate delegate = null; public Rocket(IRocketDelegate delegate) { this.delegate = delegate; } private long getRocketStartTime() { long startTime = delegate.startAtTime(); return startTime; } private long getRocketEndTime() { long endTime = delegate.endAtTime(); return endTime; } public boolean isOk() { // 超时0.1秒为失败 if (getRocketEndTime() - getRocketStartTime() >= 100) { delegate.sendDidFail(); return false; } return true; } } 在这个类中,声明一个 IRocketDelegate 接口对象,使用该对象调用接口的方法。我们知道,接口不可以直接实例化,换句话说,实例化接口必须实现接口的所有方法。 ...

2012-10-08 · 2 min · 302 words · -

里氏代换原则

里氏代换原则 里氏代换原则 (Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对"开-闭"原则的补充。实现"开-闭"原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。LSP讲的是基类和子类的关系。只有当这种关系存在时,里氏代换关系才存在。如果两个具体的类A,B之间的关系违反了LSP的设计,(假设是从B到A的继承关系)那么根据具体的情况可以在下面的两种重构方案中选择一种。 –创建一个新的抽象类C,作为两个具体类的超类,将A,B的共同行为移动到C中来解决问题。 –从B到A的继承关系改为委派关系。 为了说明,我们先用第一种方法来看一个例子,第二种办法在另外一个原则中说明。我们就看那个著名的长方形和正方形的例子。对于长方形的类,如果它的长宽相等,那么它就是一个正方形,因此,长方形类的对象中有一些正方形的对象。对于一个正方形的类,它的方法有个setSide和getSide,它不是长方形的子类,和长方形也不会符合LSP。 eg: 长方形类: public class Rectangle{ … setWidth(int width){ this.width=width; } setHeight(int height){ this.height=height } } 正方形类: public class Square{ … setWidth(int width){ this.width=width; this. height=width; } setHeight(int height){ this.setWidth(height); } } 例子中改变边长的函数: public void resize(Rectangle r){ while(r.getHeight()<=r.getWidth){ r.setHeight(r.getWidth+1); } } 那么,如果让正方形当做是长方形的子类,会出现什么情况呢?我们让正方形从长方形继承,然后在它的内部设置width等于height,这样,只要width或者height被赋值,那么width和height会被同时赋值,这样就保证了正方形类中,width和height总是相等的.现在我们假设有个客户类,其中有个方法,规则是这样的,测试传入的长方形的宽度是否大于高度,如果满足就停止下来,否则就增加宽度的值。现在我们来看,如果传入的是基类长方形,这个运行的很好。根据LSP,我们把基类替换成它的子类,结果应该也是一样的,但是因为正方形类的width和height会同时赋值,这个方法没有结束的时候,条件总是不满足,也就是说,替换成子类后,程序的行为发生了变化,它不满足LSP。 那么我们用第一种方案进行重构,我们构造一个抽象的四边形类,把长方形和正方形共同的行为放到这个四边形类里面,让长方形和正方形都是它的子类,问题就OK了。对于长方形和正方形,取width和height是它们共同的行为,但是给width和height赋值,两者行为不同,因此,这个抽象的四边形的类只有取值方法,没有赋值方法。上面的例子中那个方法只会适用于不同的子类,LSP也就不会被破坏。在进行设计的时候,我们尽量从抽象类继承,而不是从具体类继承。如果从继承等级树来看,所有叶子节点应当是具体类,而所有的树枝节点应当是抽象类或者接口。当然这个只是一个一般性的指导原则,使用的时候还要具体情况具体分析。

2012-10-08 · 1 min · 53 words · -

java ocr tesseract

java ocr tesseract http://ykf.iteye.com/blog/212431

2012-09-30 · 1 min · 4 words · -

OCR之 Tesseract

OCR之 Tesseract http://www.cnblogs.com/brooks-dotnet/archive/2010/10/05/1844203.html 光学字符识别(OCR,Optical Character Recognition)是指对文本资料进行扫描,然后对图像文件进行分析处理,获取文字及版面信息的过程。OCR技术非常专业,一般多是印刷、打印行业的从业人员使用,可以快速的将纸质资料转换为电子资料。关于中文OCR,目前国内水平较高的有清华文通、汉王、尚书,其产品各有千秋,价格不菲。国外OCR发展较早,像一些大公司,如IBM、微软、HP等,即使没有推出单独的OCR产品,但是他们的研发团队早已掌握核心技术,将OCR功能植入了自身的软件系统。对于我们程序员来说,一般用不到那么高级的,主要在开发中能够集成基本的OCR功能就可以了。这两天我查找了很多免费OCR软件、类库,特地整理一下,今天首先来谈谈Tesseract,下一次将讨论下Onenote 2010中的OCR API实现。可以在这里查看OCR技术的发展简史。 测试代码下载 转载请注明出处: http://www.cnblogs.com/brooks-dotnet/archive/2010/10/05/1844203.html 1、Tesseract概述 Tesseract的OCR引擎最先由HP实验室于1985年开始研发,至1995年时已经成为OCR业内最准确的三款识别引擎之一。然而,HP不久便决定放弃OCR业务,Tesseract也从此尘封。 数年以后,HP意识到,与其将Tesseract束之高阁,不如贡献给开源软件业,让其重焕新生--2005年,Tesseract由美国内华达州信息技术研究所获得,并求诸于Google对Tesseract进行改进、消除Bug、优化工作。 Tesseract目前已作为开源项目发布在Google Project,其项目主页在这里查看,其最新版本3.0已经支持中文OCR,并提供了一个命令行工具。本次我们来测试一下Tesseract 3.0,由于命令行对最终用户不太友好,我用WPF简单封装了一下,就可以方便的进行中文OCR了。

2012-09-30 · 1 min · 17 words · -

java取整和四舍五入

java取整和四舍五入 Math.round Math.round(-1.1): -1 Math.round(-1.5): -1 Math.round(-1.6): -2 Math.round(0.1): 0 Math.round(0.5): 1 Math.round(0.6): 1 Math.round(1.1): 1 Math.round(1.5): 2 Math.round(1.6): 2 round 方法,我们通常会说这个方法表示"四舍五入",但是当参数为负数时,就不太好理解。 所以也有以下形式 即将原来的数字加上0.5后再向下取整。 Math.round(x) = Math.floor(x + 0.5) import java.math.BigDecimal; import java.text.DecimalFormat; public class TestGetInt{ public static void main(String[] args){ double i=2, j=2.1, k=2.5, m=2.9; System.out.println(“舍掉小数取整:Math.floor(2)=” + (int)Math.floor(i)); System.out.println(“舍掉小数取整:Math.floor(2.1)=” + (int)Math.floor(j)); System.out.println(“舍掉小数取整:Math.floor(2.5)=” + (int)Math.floor(k)); ...

2012-09-30 · 2 min · 287 words · -

Java Image与BufferedImage

Java Image 与 BufferedImage Image是一个抽象类,BufferedImage是Image的实现。Image和BufferedImage的主要作用就是将一副图片加载到内存中。 Java将一副图片加载到内存中的方法是: String imgPath = “C://demo.jpg”; BufferedImage image = ImageIO.read(new FileInputStream(imgPath)); 该方法可以获得图片的详细信息,例如: 获得图片的宽度: image.getWidth(null);图片只有加载内存中才能对图片进行进一步的处理。 还有一个方法 String imgPath = "C://demo.jpg"; Image imageToolkit.getDefaultToolkit().getImage(imgPath); 但该方法不能把图片加载到内存中,仅仅是得到图片,所以也就不能获得图片的信息,图片的长宽信息都无法拿到。 文章地址: http://javapub.iteye.com/blog/683944

2012-09-30 · 1 min · 28 words · -

Map, Dictionary

Map, Dictionary Dictionary Dictionary 是 Hashtable 的抽象父类,在 java.util包下,他的子类有 Hashtable, Properties. 它的主要作用是用于记录 键到值的一一对应关系。没错,从数学的概念上讲,这种映射关系就是一对一的。也就是说,一个key最多只能找到一个value. 如果给出一个 Dictionary 的子类对象和一个 key, 就可以查找有没有包含相关的元素。需要注意的是:任何非空(non-null)的对象才能用作 key 和 value. 通常,类的实现应使用 equals 方法来确定两个键是否相同。 注意:此类已过时。 新的实现应实现 Map 接口,而不是扩展此类。 Map 接口 Map 是一个接口,还是看图: Map 是一个将 keys 映射到 values 的对象。一个 map 对象不能包含重复的 keys. 每一个 key 最多只能映射到一个对象。 Map 这个接口是为了取代 Dictionary 这个抽象类的,更直白的说,就是拿一个接口去取代之前抽象类。 three collection views Map 接口提供了三套查看方法来查看map所包含的内容。 查看它所包含的所有 keys (view as a set of keys) 查看它所包含的所有 values(view as collection of values) 查看它所包含的键-值映射。(view as a set of key-value mappings) ...

2012-09-27 · 1 min · 78 words · -

java读写文件

java读写文件 Java获取当前路径 利用System.getProperty()函数获取当前路径: System.out.println(System.getProperty(“user.dir”));//user.dir指定了当前的路径 使用File提供的函数获取当前路径: File directory = new File("");//设定为当前文件夹 try{ System.out.println(directory.getCanonicalPath());//获取标准的路径 System.out.println(directory.getAbsolutePath());//获取绝对路径 }catch(Exceptin e){} File.getCanonicalPath()和File.getAbsolutePath()大约只是对于new File(".")和new File("..")两种路径有所区别。 对于getCanonicalPath()函数,".“就表示当前的文件夹,而”..“则表示当前文件夹的上一级文件夹 对于getAbsolutePath()函数,则不管”."、"..",返回当前的路径加上你在new File()时设定的路径 至于getPath()函数,得到的只是你在new File()时设定的路径 http://sharewind.iteye.com/blog/227538 ```java //=============================写文件 package fier; import java.io.*; public class write { public static void main(String[] args) { write("E:\123.txt", "hello"); } public static void write(String path, String content) { String s = new String(); String s1 = new String(); try { File f = new File(path); if (f.exists()) { System.out.println("文件存在"); } else { System.out.println("文件不存在,正在创建..."); if (f.createNewFile()) { System.out.println("文件创建成功!"); } else { System.out.println("文件创建失败!"); } } BufferedReader input = new BufferedReader(new FileReader(f)); while ((s = input.readLine()) != null) { s1 += s + "n"; } System.out.println("文件内容: " + s1); input.close(); s1 += content; BufferedWriter output = new BufferedWriter(new FileWriter(f)); output.write(s1); output.close(); } catch (Exception e) { e.printStackTrace(); } } } //=============================读文件 package fier; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStreamReader; public class sdsd { /** * @param args */ public static void main(String[] args) { read("E:\123.txt"); } public static void read(String file) { String s = null; StringBuffer sb = new StringBuffer(); File f = new File(file); if (f.exists()) { System.out.println("文件存在"); try { BufferedReader br = new BufferedReader(new InputStreamReader( new FileInputStream(f))); while ((s = br.readLine()) != null) { sb.append(s); } System.out.println(sb); } catch (Exception e) { e.printStackTrace(); } }else{ System.out.println("文件不存在!"); } } } ```

2012-09-27 · 2 min · 217 words · -

Java Http连接中 (HttpURLConnection) 中使用代理 (Proxy) 及其验证 (Authentication)

Java Http连接中 (HttpURLConnection) 中使用代理 (Proxy) 及其验证 (Authentication) System.setProperty("http.proxyHost", "www.proxy.com"); System.setProperty("http.proxyPort", "8080"); 使用Java的HttpURLConnection类可以实现HttpClient的功能,而不需要依赖任何其他类库。所有有时候大家就直接使用它来完成一些简单 (或复杂) 的功能。但是你活在伟大的{print G.F.W}后面,如果你需要访问的网站被墙了,那HttpURLConnection类就会出现连接超时的错误。这时候就需要给他设置代理 (Proxy) 了。 设置代理 (Proxy) 可以有两种方式: 1、通过设置系统属性(System.setPropery(String key, String value)的方式 首先你可以在这里看到Java支持的属性。我们可以使用其中的http.proxyHost,http.proxyPort这两个属性。顾名思义,就是分别设置代理服务器地址和代理端口。 [c language="-sharp"][/c] 替换上面的www.proxy.com为你的代理服务器地址或IP地址,以及相应的端口为真实端口,Http连接及可以工作了。需要注意的是如果你设置了这些属性,那么所有的Http请求都会通过代理服务器。这些属性是JVM级别的,设置了以后对所有的同类请求都有效。比如上面的是关于http的,还有关于ftp的等等。 如果你的代理服务器不需要验证,那到此就结束了。但一般都是需要验证的。但是你要是看了上面Java支持的属性列表,你就会发现那里面并没有期望中的 [c language="-sharp"][/c] http://blog.csdn.net/redhat456/article/details/6149774# http.proxyUserName=username http.proxyPassword=password 这两个属性。 这时就需要java.net.Authenticator类来完成一般的Http验证。但是java.net.Authenticator这个类却是个抽象类,我们要使用还需要实例化一下子自己的类。个人觉得这里很不方便。如下: ```java``` http://blog.csdn.net/redhat456/article/details/6149774# http://blog.csdn.net/redhat456/article/details/6149774# Authenticator.setDefault(new BasicAuthenticator(userName, password)); 这样就提供了基于Http Basic的验证,接着就可以顺畅的使用需要验证的代理了。 2、通过java.net.Proxy类。 这种方式是实例化一个Proxy类提供代理服务器的信息,如端口和地址。 ```java``` http://blog.csdn.net/redhat456/article/details/6149774# Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, port)); URLConnection conn = url.openConnection(proxy); 使用代理的方式是在打开Http连接的时候同时传递一个Proxy参数。如果需要验证信息的话我们可以添加一个Http头参数来实现。 ```java``` http://blog.csdn.net/redhat456/article/details/6149774# ...

2012-09-27 · 1 min · 83 words · -

Java HTTP Helper

Java HTTP Helper import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.AuthCache; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.protocol.ClientContext; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.params.ConnRoutePNames; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.entity.BasicHttpEntity; import org.apache.http.entity.StringEntity; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.client.BasicAuthCache; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.util.EntityUtils; public class HttpHelper { /*\* The Constant MAX_NUMBER_OF_CONNECTIONS. */ private static final int MAX_NUMBER_OF_CONNECTIONS = 200; /*\* The http client. */ private DefaultHttpClient httpClient; /*\* The http context. */ private BasicHttpContext httpContext; /*\* The target host. */ private HttpHost targetHost; /*\* The proxy host. */ private HttpHost proxyHost; /*\* The X509TrustManager. */ protected static X509TrustManager tm = new X509TrustManager() { public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { } public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return null; } }; protected String execute(HttpRequest request) throws Exception { // logger.debug("executing request: " + request.getRequestLine()); // logger.debug("via proxy: " + getProxyHost()); // logger.debug("to target: " + getTargetHost()); StringBuffer resXML = new StringBuffer(); // Send request DefaultHttpClient httpClient = getHttpClient(); HttpResponse response = httpClient.execute(getTargetHost(), request, getHttpContext()); // Get response HttpEntity entity = response.getEntity(); StatusLine statusLine = response.getStatusLine(); // logger.debug("Response code: " + statusLine); int httpStatus = statusLine.getStatusCode(); if (httpStatus >= 200 && httpStatus <= 207) { // Get response XML InputStream is = entity.getContent(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String line = null; while ((line = br.readLine()) != null) { resXML.append(line); } EntityUtils.consume(entity); } else { // Http access error throw new Exception(statusLine.toString()); } return resXML.toString(); } /** * Gets the target host. * * @return the target host */ protected HttpHost getTargetHost() { if (targetHost == null) { targetHost = new HttpHost(getTargetHost(), getTargetPort(), getProtocol()); } return targetHost; } /** * Gets the proxy host. * * @return the proxy host */ protected HttpHost getProxyHost() { if (proxyHost == null) { proxyHost = new HttpHost(getProxyHost(), getProxyPort()); } return proxyHost; } /** * Gets the http context. * * @return the http context */ @SuppressWarnings("static-access") protected BasicHttpContext getHttpContext() { if (httpContext == null) { // Create AuthCache instance AuthCache authCache = new BasicAuthCache(); // Generate BASIC scheme object and add it to the local BasicScheme basicAuth = new BasicScheme(); basicAuth.authenticate( new UsernamePasswordCredentials(getUserName(), getPassword()), "UTF-8", true); authCache.put(getTargetHost(), basicAuth); // Add AuthCache to the execution context httpContext = new BasicHttpContext(); httpContext.setAttribute(ClientContext.AUTH_CACHE, authCache); } return httpContext; } /** * Gets the http client. * * @return the http client * @throws NoSuchAlgorithmException the no such algorithm exception * @throws KeyManagementException the key management exception */ @SuppressWarnings("deprecation") protected DefaultHttpClient getHttpClient() throws NoSuchAlgorithmException, KeyManagementException { if (httpClient == null) { ThreadSafeClientConnManager cm =new ThreadSafeClientConnManager(); cm.setMaxTotal(MAX_NUMBER_OF_CONNECTIONS); httpClient = new DefaultHttpClient(cm); if (isProxyEnabled()) { httpClient.getParams().setParameter( ConnRoutePNames.DEFAULT_PROXY, getProxyHost()); } String protocol = getProtocol(); if ("HTTPS".equalsIgnoreCase(protocol)) { SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(null, new TrustManager[] { tm }, null); SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); ClientConnectionManager ccm = httpClient.getConnectionManager(); SchemeRegistry sr = ccm.getSchemeRegistry(); sr.register(new Scheme(protocol, ssf, getTargetPort())); httpClient = new DefaultHttpClient(ccm, httpClient.getParams()); } httpClient.getCredentialsProvider().setCredentials( AuthScope.ANY, new UsernamePasswordCredentials(getUserName(), getPassword())); } return httpClient; } /** * Shuts down this httpClient connection manager and releases allocated resources. * This includes closing all connections, whether they are currently * used or not. */ public void shutdown(){ if (httpClient == null) { httpClient.getConnectionManager().shutdown(); } } }

2012-09-26 · 3 min · 543 words · lcf

Java JAXB Unmarshaller

Java JAXB Unmarshaller import java.io.IOException; import java.io.InputStream; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.Unmarshaller; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.springframework.context.support.GenericApplicationContext; import org.w3c.dom.Document; public class ConfigReader { public final <T>T read(Class<T> t, String filePath) throws ISException { InputStream input; try { input = new GenericApplicationContext() .getResource(filePath).getInputStream(); } catch (IOException e) { throw new ISException(e); } return read(input, t); } public final <T>T read(InputStream inputStream, Class<T> t) throws ISException { T root = null; synchronized (this) { try { if (inputStream != null) { final DocumentBuilderFactory dbf = DocumentBuilderFactory .newInstance(); dbf.setNamespaceAware(true); final JAXBContext context = JAXBContext.newInstance(t); final Unmarshaller unmarshaller = context .createUnmarshaller(); final DocumentBuilder documentBuilder = dbf .newDocumentBuilder(); final Document doc = documentBuilder.parse(inputStream); final JAXBElement<T> rootElement = unmarshaller.unmarshal( doc, t); root = rootElement.getValue(); } } catch (Exception e) { throw new ISException(e); } } return root; } }

2012-09-26 · 1 min · 135 words · lcf

Java ClassLoader

Java ClassLoader 不同的JVM的实现不同,本文所描述的内容均只限于Hotspot Jvm. 本文将会从JDK默认的提供的ClassLoader,双亲委托模型,如何自定义ClassLoader以及Java中打破双亲委托机制的场景四个方面入手去讨论和总结一下。 JDK默认ClassLoader JDK 默认提供了如下几种ClassLoader Bootstrp loader Bootstrp加载器是用C++语言写的,用来加载核心类库,如 java.lang.* 等.它是在Java虚拟机启动后初始化的,它主要负责加载%JAVA_HOME%/jre/lib,-Xbootclasspath参数指定的路径以及%JAVA_HOME%/jre/classes中的类。 ExtClassLoader Bootstrp loader加载ExtClassLoader,并且将ExtClassLoader的父加载器设置为Bootstrp loader.ExtClassLoader是用Java写的,具体来说就是 sun.misc.Launcher$ExtClassLoader,ExtClassLoader主要加载%JAVA_HOME%/jre/lib/ext,此路径下的所有classes目录以及java.ext.dirs系统变量指定的路径中类库。 AppClassLoader Bootstrp loader加载完ExtClassLoader后,就会加载AppClassLoader,并且将AppClassLoader的父加载器指定为 ExtClassLoader。AppClassLoader也是用Java写成的,它的实现类是 sun.misc.Launcher$AppClassLoader,另外我们知道ClassLoader中有个getSystemClassLoader方法,此方法返回的正是AppclassLoader.AppClassLoader主要负责加载classpath所指定的位置的类或者是jar文档,它也是Java程序默认的类加载器。 综上所述,它们之间的关系可以通过下图形象的描述: 双亲委托模型 Java中ClassLoader的加载采用了双亲委托机制,采用双亲委托机制加载类的时候采用如下的几个步骤: 当前ClassLoader首先从自己已经加载的类中查询是否此类已经加载,如果已经加载则直接返回原来已经加载的类。 每个类加载器都有自己的加载缓存,当一个类被加载了以后就会放入缓存,等下次加载的时候就可以直接返回了。 当前classLoader的缓存中没有找到被加载的类的时候,委托父类加载器去加载,父类加载器采用同样的策略,首先查看自己的缓存,然后委托父类的父类去加载,一直到bootstrp ClassLoader. 当所有的父类加载器都没有加载的时候,再由当前的类加载器加载,并将其放入它自己的缓存中,以便下次有加载请求的时候直接返回。 说到这里大家可能会想,Java为什么要采用这样的委托机制?理解这个问题,我们引入另外一个关于Classloader的概念"命名空间", 它是指要确定某一个类,需要类的全限定名以及加载此类的ClassLoader来共同确定。也就是说即使两个类的全限定名是相同的,但是因为不同的 ClassLoader加载了此类,那么在JVM中它是不同的类。明白了命名空间以后,我们再来看看委托模型。采用了委托模型以后加大了不同的 ClassLoader的交互能力,比如上面说的,我们JDK本生提供的类库,比如hashmap,linkedlist等等,这些类由bootstrp 类加载器加载了以后,无论你程序中有多少个类加载器,那么这些类其实都是可以共享的,这样就避免了不同的类加载器加载了同样名字的不同类以后造成混乱。 如何自定义ClassLoader Java除了上面所说的默认提供的classloader以外,它还容许应用程序可以自定义classloader,那么要想自定义classloader我们需要通过继承java.lang.ClassLoader来实现,接下来我们就来看看再自定义Classloader的时候,我们需要注意的几个重要的方法: 1.loadClass 方法 loadClass method declare public Class loadClass(String name) throws ClassNotFoundException 上面是loadClass方法的原型声明,上面所说的双亲委托机制的实现其实就实在此方法中实现的。下面我们就来看看此方法的代码来看看它到底如何实现双亲委托的。 loadClass method implement public Class loadClass(String name) throws ClassNotFoundException { return loadClass(name, false); ...

2012-09-26 · 8 min · 1507 words · lcf

Java Spring LDAP

Java Spring LDAP import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; import javax.naming.Context; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import org.springframework.ldap.core.DirContextOperations; import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.LdapTemplate; import org.springframework.ldap.core.support.AbstractContextMapper; import org.springframework.ldap.core.support.DirContextSource; import org.springframework.ldap.support.LdapUtils; /** * This Service does user authentication with LDAP. It uses Spring to do the authentication * * A good chunk of the LDAP code is copy-paste from: * http://static.springsource.organization/spring-ldap/docs/1.3.x/reference/pdf/spring-ldap-reference.pdf * */ public class LDAPService { private Map<String, String> ldapPropertiesMap=new HashMap<String, String>(); // LDAP Settings public static final String LDAP_PROVIDER_URL = "ldap.provider.url"; public static final String LDAP_SECURITY_AUTHENTICATION = "ldap.security.authentication"; public static final String LDAP_SECURITY_PRINCIPAL = "ldap.security.principal"; public static final String LDAP_SECURITY_CREDENTIALS = "ldap.security.credentials"; public static final String LDAP_ADMIN_OU = "ldap.admin.ou"; public static final String LDAP_USER_OU = "ldap.user.ou"; public static final String LDAP_USER_FILTER = "ldap.user.filter"; private DirContextSource dirCtxSrc; private String userAuthority; private static final String ldapFactory = "com.sun.jndi.ldap.LdapCtxFactory"; private static final String DEFAULT_USER_FILTER = "uid"; public LDAPService() throws Exception { ldapPropertiesMap.put(LDAP_PROVIDER_URL, "ldap://10.0.1.1:10389/ou=system"); ldapPropertiesMap.put(LDAP_SECURITY_AUTHENTICATION, "simple"); ldapPropertiesMap.put(LDAP_SECURITY_PRINCIPAL, "uid=admin,ou=system"); ldapPropertiesMap.put(LDAP_SECURITY_CREDENTIALS, "secret"); ldapPropertiesMap.put(LDAP_ADMIN_OU, "ou=admins,ou=system"); ldapPropertiesMap.put(LDAP_USER_OU, "ou=users,ou=system"); ldapPropertiesMap.put(LDAP_USER_FILTER, "uid=?"); this.init(); } private void init() throws Exception { Hashtable<String, String> env = new Hashtable<String, String>(); env.put(Context.INITIAL_CONTEXT_FACTORY, ldapFactory); env.put(Context.PROVIDER_URL, ldapPropertiesMap.get(LDAP_PROVIDER_URL)); env.put(Context.SECURITY_AUTHENTICATION, ldapPropertiesMap.get(LDAP_SECURITY_AUTHENTICATION)); env.put(Context.SECURITY_PRINCIPAL, ldapPropertiesMap.get(LDAP_SECURITY_PRINCIPAL)); env.put(Context.SECURITY_CREDENTIALS, ldapPropertiesMap.get(LDAP_SECURITY_CREDENTIALS)); dirCtxSrc = new DirContextSource(); dirCtxSrc.setBaseEnvironmentProperties(env); dirCtxSrc.setUserDn(ldapPropertiesMap.get(LDAP_SECURITY_PRINCIPAL)); dirCtxSrc.setPassword(ldapPropertiesMap.get(LDAP_SECURITY_CREDENTIALS)); dirCtxSrc.setUrl(ldapPropertiesMap.get(LDAP_PROVIDER_URL)); dirCtxSrc.afterPropertiesSet(); } /** * Return user authority after authentication * * @return */ public String getUserAuthority() { return userAuthority; } public boolean validateLoginCredentials(String username, String password) throws Exception { boolean result = false; try { String userDn = getDnForUser(username); result = authenticate(userDn, password); if (result) { String adminGroup = ldapPropertiesMap.get(LDAP_ADMIN_OU); String userGroup = ldapPropertiesMap.get(LDAP_USER_OU); if (adminGroup != null && userDn.toLowerCase().endsWith( adminGroup.toLowerCase())) { this.userAuthority = adminGroup; } else if (userGroup != null && userDn.toLowerCase().endsWith( userGroup.toLowerCase())) { this.userAuthority = userGroup; } else { logger.info(username + " is a valid user, but is not in the either the UserOU or AdminOU"); throw new RuntimeException( "Could not locate Authority for User: '" + username + "' in LDAP"); } } return result; } catch (Exception ex) { logger.error("Exception during ldap authentication for User: '" + username + "'", ex); throw ex; } } /** * This will find the distinguished name given a uid * * @param uid * @return */ protected String getDnForUser(String uid) { LdapTemplate ldapTemplate = new LdapTemplate(dirCtxSrc); // Filter String userFilter = ldapPropertiesMap.get(LDAP_USER_FILTER); if (userFilter != null && !userFilter.isEmpty()) { userFilter = userFilter.replaceAll("\?", uid); } else { userFilter = "(" + DEFAULT_USER_FILTER + "=" + uid + ")"; } Logger.debug("LDAP USER Filter:" + userFilter); // Filter f = new EqualsFilter("uid", uid); List result = ldapTemplate.search(DistinguishedName.EMPTY_PATH, userFilter, new AbstractContextMapper() { protected Object doMapFromContext(DirContextOperations ctx) { return ctx.getNameInNamespace(); } }); if (result.size() != 1) { throw new RuntimeException("User-'" + uid + "' not found in LDAP or not unique"); } return (String) result.get(0); } /** * This try to create a Context using the supplied username and password * * @param userDn * @param password * @return */ protected boolean authenticate(String userDn, String password) throws Exception { DirContext ctx = null; Hashtable<String, String> env = new Hashtable<String, String>(); String providerUrl = (ldapPropertiesMap.get(LDAP_PROVIDER_URL)); String securityAuth = (ldapPropertiesMap .get(LDAP_SECURITY_AUTHENTICATION)); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, providerUrl); env.put(Context.SECURITY_AUTHENTICATION, securityAuth); env.put(Context.SECURITY_PRINCIPAL, userDn); env.put(Context.SECURITY_CREDENTIALS, password); try { ctx = new InitialDirContext(env); return true; } catch (Exception e) { // Context creation failed - authentication did not succeed logger.error("Login failed for userDn-'" + userDn + "'", e); throw e; } finally { // It is imperative that the created DirContext instance is always // closed LdapUtils.closeContext(ctx); } } public Map<String, String> getLdapPropertiesMap() { return ldapPropertiesMap; } public void setLdapPropertiesMap(Map<String, String> ldapPropertiesMap) { this.ldapPropertiesMap = ldapPropertiesMap; } }

2012-09-26 · 3 min · 581 words · lcf

Java Base64

Java Base64 // encode byte[] in; byte[] out=java.util.Base64.getEncoder().encode(in); System.out.println(new String(out)); // decode byte[] byteArray = Base64.getDecoder().decode(value.getBytes()); String base64Decode = new String(byteArray, StandardCharsets.UTF_8); System.out.println("base64 decode: " + base64Decode);

2012-09-26 · 1 min · 27 words · lcf

Java Singleton

Java Singleton public class ConnEnv { /** The instance. */ private static ConnEnv instance; private ConnEnv(){ } public static ConnEnv getInstance(){ if (instance == null) { createInstance(); } return instance; } /** Creates the instance. */ private static synchronized void createInstance() { if (instance==null) { try { instance = new ConnEnv(); } catch (Exception e) { // throw e; } } } }

2012-09-26 · 1 min · 63 words · lcf

hash, hashCode, 哈希, 散列

hash, hashCode, 哈希, 散列 Hash,一般直接音译成“哈希”,按真正含义译作“散列”比较合适。通过散列算法,把任意长度的输入,转换成固定长度的输出,输出就叫做散列值 (hashCode)。这种转换是一种压缩映射,也就是说,散列值所占用的空间通常远小于输入值所占用的空间,不同的输入可能会有相同的散列值。散列的目的,在于尽量分散数据的存储位置,使数据散列在不同的哈希桶(bucket)中。 hashCode:是一串固定长度的整型的数字,hashCode可以由hash函数生成。hash函数常用的算法有:直接取余法、乘法取整法、平方取中法等。由hashCode可以得到对象在hash表中的位置 hashMap、hashTable:都是基于hash表实现的,都通过单链表解决数据通途的问题。二者很类似,但是也有很明显的区别。 hashcode() 方法返回该对象的哈希码值。 在 Java 应用程序执行期间,在同一对象上多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是对象上 equals 比较中所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。 如果根据 equals(Object) 方法,两个对象是相等的,那么在两个对象中的每个对象上调用 hashCode 方法都必须生成相同的整数结果。 以下情况不 是必需的: 如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么在两个对象中的任一对象上调用 hashCode 方法必定会生成不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同整数结果可以提高哈希表的性能。 实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。 (这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。) 当equals方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。 hashCode()和equals()定义在Object类中,这个类是所有java类的基类,所以所有的java类都继承这两个方法。 使用hashCode()和equals() hashCode()方法被用来获取给定对象的唯一整数。这个整数被用来确定对象被存储在HashTable类似的结构中的位置。默认的,Object类的hashCode()方法返回这个对象存储的内存地址的编号。 重写默认的实现 如果你不重写这两个方法,将几乎不遇到任何问题,但是有的时候程序要求我们必须改变一些对象的默认实现。 来看看这个例子,让我们创建一个简单的类Employee public class Employee { private Integer id; private String firstname; private String lastName; private String department; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } } ...

2012-09-26 · 3 min · 569 words · -

类方法 静态方法

‘类方法 静态方法’ http://www.blogjava.net/magicblw/archive/2007/08/22/138610.html 对于实例方法,实例变量和类方法,类变量的区分的不是很清楚,谈一下个人现在理解程度: 1,类方法类变量是静态方法,静态方法和静态变量可以看作是全局的。 2,实例方法和是实例变量可以看作是由类new出来的对象,是局部的。 规则: 1,全局的可以调用全局的 2,局部的可以调用局部的 3,局部可以调用全局的 4,全局不可以直接调用局部的 5,实例方法和实例变量只可以由对象引用,而类方法和类变量可以由类名或对象引用。 以上是自己的一些看法,不对的地方请指教。

2012-09-26 · 1 min · 13 words · -

Java Hex To Byte & CRCChecker

‘Java Hex To Byte & CRCChecker’ public final String byte2Hex(final byte[] btSrc) throws Exception { final StringBuffer sbuffer = new StringBuffer(); if (btSrc != null) { for (int n = 0; n < btSrc.length; n++) { String stmp = "00" + Integer.toHexString(btSrc[n] & 0XFF); stmp = stmp.substring(stmp.length() - 2); sbuffer.append(stmp.toUpperCase()); } } return sbuffer.toString(); } /** * Hex2 byte. * * @param src * the src * @return the byte[] */ public final byte[] hex2Byte(final String src) throws Exception { byte[] btRtn = new byte[0]; String srcTmp = src; if (isHex(srcTmp)) { int len = srcTmp.length(); if (len % 2 != 0) { len++; srcTmp = "0" + srcTmp; } len = len / 2; btRtn = new byte[len]; for (int n = 0; n < len; n++) { final int index = 2 * n; final String strTemp = String.valueOf(srcTmp.charAt(index)) + String.valueOf(srcTmp.charAt(index + 1)); final byte btTemp = (byte) Integer.parseInt(strTemp, 16); btRtn[n] = btTemp; } } return btRtn; } /** * Checks if is hex. * * @param src * the src * @return true, if is hex */ public final boolean isHex(final String src) { boolean blRtn = false; if (src != null) { final String pattern = "([0-9a-fA-F])*"; blRtn = src.matches(pattern); } return blRtn; } CRCChecker.java ...

2012-09-26 · 2 min · 336 words · lcf