java ocr tesseract
java ocr tesseract http://ykf.iteye.com/blog/212431
java ocr tesseract http://ykf.iteye.com/blog/212431
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了。
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)); ...
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
短信验证码 短信验证码有效期2分钟 验证码 6 位纯数字 每个手机号60秒内只能发一次短信验证码, 前后端都要做验证 同一个手机号在同一时间可以有多个有效的验证码 验证码不记录到日志 验证码使用后作废 (使用后作废,不太友好,如果有其它信息填写错误得等1分钟再重新取验证码) 验证码至多可以使用3次,无论是否匹配都作废,防止暴力攻击 (一个手机号验证三次之后, 作废关联的验证码) java 识别验证码 http://blog.csdn.net/problc/article/details/5800093 https://www.cnblogs.com/guokun/p/11042903.html https://insights.thoughtworks.cn/sms-authentication-login-api/
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) ...
回车, 换行符, CRLF, LF 换行 line feed, LF, newline, \n, ascii 码: 0x0A 回车, carriage return, CR, return, \r, ascii 码: 0x0D CRLF, Carriage return & line feed unix: 换行, \n windows: 换行(回车+换行), \r\n, Unix/Mac 下打开会显示成 ^M macos: Line Feed, LF https://blog.csdn.net/wjcquking/article/details/6634504 回车符号和换行符号产生背景 关于"回车" (carriage return) 和"换行" (line feed) 这两个概念的来历和区别。 在计算机还没有出现之前,有一种叫做电传打字机 (Teletype Model 33) 的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。 于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做"回车",告诉打字机把打印头定位在左边界;另一个叫做"换行",告诉打字机把纸向下移一行。 这就是"换行"和"回车"的来历,从它们的英语名字上也可以看出一二。 后来,计算机发明了,这两个概念也就被般到了计算机上。那时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就可以。于是,就出现了分歧。 Unix系统里,每行结尾只有"<换行>",即"\n";Windows系统里面,每行结尾是" <回车><换行>",即"\r\n";Mac系统里,每行结尾是"<回车>"。一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行;而Windows里的文件在 Unix/Mac 下打开的话,在每行的结尾可能会多出一个^M符号 windows创建的文件是 \n\r 结束的, 而linux,mac这种unix类系统是\n结束的。 所以unix的文本到windows会出现换行丢失 (ultraedit这种软件可以正确识别) ; 而反过来就会出现^M的符号了 ...
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("文件不存在!"); } } } ```
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# ...
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(); } } }
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; } }
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); ...
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; } }
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);
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; } } } }
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; } } ...
‘类方法 静态方法’ http://www.blogjava.net/magicblw/archive/2007/08/22/138610.html 对于实例方法,实例变量和类方法,类变量的区分的不是很清楚,谈一下个人现在理解程度: 1,类方法类变量是静态方法,静态方法和静态变量可以看作是全局的。 2,实例方法和是实例变量可以看作是由类new出来的对象,是局部的。 规则: 1,全局的可以调用全局的 2,局部的可以调用局部的 3,局部可以调用全局的 4,全局不可以直接调用局部的 5,实例方法和实例变量只可以由对象引用,而类方法和类变量可以由类名或对象引用。 以上是自己的一些看法,不对的地方请指教。
‘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 ...
Java Console Input import java.io.Console; public class ConsoleInput { public static void main(String[] args) { Console console = System.console(); String titleUser = "Please enter value"; String label = "[Encrypted value]:"; String titlePWD = "password:"; String description = "Please enter a Digit:: 0: Start encrypt words 1: Exit"; String flag ="0"; if(console!=null){ while("0".equals(flag.trim())) { String srcWord = console.readLine("[%s]:", titleUser); console.printf("%s", label + srcWord); console.flush(); System.out.println(); System.out.println(description); flag =console.readLine(); System.out.println(); char[] password = console.readPassword("[%s]", titlePWD); String strPassword = String.valueOf(password); java.util.Arrays.fill(password, '*'); console.printf("%s", titlePWD + String.valueOf(password)); console.flush(); System.out.println(); } } } }
refactor, 重构 重构是克服演进式设计中大杂烩问题的主力,通过在单独的类及方法级别上做一系列小步重构来完成。 在解决现实问题时,我们会将问题映射到脑海中的概念模型,在模型中解决问题,再将解决方案转换为实际的代码。上述问题在于我们解决了设计到代码之间的重构,但提炼出来的设计模型,并不具有实际的业务含义,这就导致在开发新需求时,其他同学并不能很自然地将业务问题映射到该设计模型。设计似乎变成了重构者的自娱自乐,代码继续腐败,重新重构……无休止的循环。