java
文章平均质量分 54
蚁方阵
千里之行,始于足下,用代码编织技术人生
展开
-
HttpClient提交表单出现中文乱码的解决办法
有个项目需要为图片添加水印,本来运行得很好,但后来增加了自定义水印内容的需求,且需要支持中文,于是很简单地添加了表单描述字段“remark”,但后端解析到的字符为一连串“?”(难道水印也是满脸的懵逼?),代码如下:HttpEntity reqEntity = MultipartEntityBuilder.create();HttpEntity reqEntity = MultipartE...原创 2018-09-06 18:01:42 · 4169 阅读 · 0 评论 -
Spring Boot(四):利用注解自定义日期格式化
在日期的格式化过程中,我们有时候需要将日期格式化到秒或者微妙,有时候又仅仅需要将日期格式化到日期,所以定义全局的日期格式化肯定难以满足需求,这时就需要一种更灵活的方法。在Spring Boot对JSON的处理类中,定义了annotationIntrospector属性,专用于处理注解,因此自定义日期格式化的步骤分为四步,如下: 1. 定义日期格式化注解,用于盛放格式化样式; 2. 定义日期JSO原创 2017-09-13 22:41:44 · 20814 阅读 · 1 评论 -
JAVA NIO(二):小端字节顺序
在JAVA中,ByteBuffer采用小端字节顺序进行存储,即最低字节保存在低位地址中,最高字节保存在高位地址中,证明的过程如下: 1. 首先存入汉字“你好”,UTF-8编码为“\u4F60\u597D”; 2. 依次读出每个字节,并输出16进制形式; 3. 比较16进制与UTF-8编码;相关的测试代码如下:// 字符缓冲区CharBuffer charBuf = CharBuffer.a原创 2017-07-27 23:34:03 · 1128 阅读 · 3 评论 -
Spring Boot(二):从Session中获取域对象的三种方法
1. 利用@SessionAttribute进行获取这是最简单直接的方法,可以直接在方法的参数中直接进行注入,如下:// 可以直接从Session中抓取域对象public Account login(@SessionAttribute Account account) { return account;}上面的方法虽然简单,但是唯一的缺点是Spring Framework 4.3之前的原创 2017-08-24 21:17:12 · 49239 阅读 · 0 评论 -
并发(十):用一个类实现遍历线程的所有状态
在Thread中,有一个关于线程状态的枚举类Thread.State,其共有六个状态,分别为: 1. NEW, 线程未启动; 2. RUNNABLE,线程正在运行中; 3. BLOCKED, 线程因为等待锁被阻塞; 4. WAITING,线程处于等待(信号)状态中; 5. TIMED_WAITING,主动调用了限时等待方法而处于等待状态中; 6. TERMINATED,线程已结束;下面我原创 2017-07-28 15:59:32 · 711 阅读 · 0 评论 -
JAVA NIO(一):Buffer.mark()的用法
在默认情况下,Buffer.mark()并没有什么用处,既不会影响Buffer的遍历,也不会影响Buffer的位置统计函数,如remaining()函数,能影响这些操作的行为只有position()。位置统计示例代码如下:CharBuffer buffer = CharBuffer.allocate(10);buffer.put('你');buffer.put('好');// 直接跳转位置原创 2017-07-27 23:32:16 · 2796 阅读 · 0 评论 -
并发(七):闭锁应用与其实现原理
闭锁是一种线程同步工具,用于同步相关线程达到相关状态(并不一定要结束),然后再执行下一步操作,所以在所有的状态满足之前,调用await的线程将一直阻塞,相对于CyclicBarrier,闭锁更强调信号的同步。当然了,闭锁也能达到CyclicBarrier的效果。假定有个任务,需要四个线程的任务都完成后才能继续执行,为了更便于理解,这里改为任务完成一半,任务类的逻辑如下:static class Ta原创 2017-07-20 21:51:57 · 1222 阅读 · 0 评论 -
JAVA总结(五):多行匹配正则表达式的两种解析方法
在利用正则表达式的解析过程中,我们经常会遇到多行字符输出的情形,例如执行执行dir命令,如输出如下结果:1 个文件 59,629,625 字节7 个目录 41,259,528,192 可用字节针对这样的输出结果,我们有解析方法: 1. 将整个输出结果作为一个正则表达式解析; 2. 在输出结果中按每行依次进行解析;方法一:跨行解析对于跨行解析,首先需要解决的问题是如何匹配换行符,在大部分原创 2017-08-17 22:02:17 · 12190 阅读 · 0 评论 -
JAVA总结(四):正则表达式匹配中文的三种方法
在对安全日志信息的分析过程中,我们经常需要利用正则表达式提取重要的字段信息,而中文就成为正则表达式绕不过去的一道坎。以“8个文件”作为测试字符串,依次做出匹配与字段提取操作。方法一:区段匹配众所周知,JAVA支持对Unicode字符的解析,请看清楚,是Unicode字符,不是UTF-8编码(只有在字节码中,才会转为UTF-8形式),于是我们可以使用Unicode指定字符的区间范围4E00到9FA5,原创 2017-08-17 22:01:29 · 1673 阅读 · 0 评论 -
UTF-8编码与Unicode编码的区别与联系
中文字节的区别: 1. UTF-8编码采用三个字节表示; 2. Unicode编码采用二个字节表示;联系,Unicode与UTF-8编码可以相互转换,转换规则为: 1110xxxx 10xxxxxx 10xxxxxx以“国”字为例,它的Unicode编码为“56FD”,详细的转换过程如下: 1. 将56FD转换为二进制0101 0110 1111 1101; 2. 然后按照上述规则原创 2017-08-10 19:37:19 · 847 阅读 · 0 评论 -
并发(十五):怎么证明Hashmap不是线程安全的?
在并发编程中,证明一个类是线程安全的很难,所以我们经常试着去证明类是线程不安全,证明的方法一般有如下几种: 1. 对象不能安全发布,构造过程逃逸; 2. 内存的可见性,内容不能及时发布; 3. 操作不是原子的; 4. 读写不能同步; 5. 存在死锁的可能性;我们经常说HashMap不是线程安全的,但如何证明呢?大部分网上的例子都是从源码进行分析,没有从运行结果中分析,基于这个原因,我试着构原创 2017-08-10 19:35:56 · 3486 阅读 · 1 评论 -
Spring Boot(一):添加任务管理的解决办法
在默认的Spring Boot中,载入的Spring架包其实较少,如果此时直接启用任务管理,如下:<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronTrigg原创 2017-08-03 18:30:18 · 653 阅读 · 0 评论 -
并发(十四):异步Servlet与AJAX的区别与联系
在wEB应用程序的开发中,前端可以通过AJAX提供异步操作解决用户请求阻塞的问题,从而解决界面响应速度较慢的问题,既然如此,为何我们还需要后端的异步Servlet呢,这两个功能是否存在重复设计?其实对于前端来说,根本不区分后端处理请求是异步的行为还是同步的行为,但对于后端来说,对于用户的每一个请求(是的,你没有看错,不是每一个用户,而是每一个请求),都会启动一个独立的线程来处理任务,这样在短时间内会原创 2017-08-03 18:25:09 · 1796 阅读 · 0 评论 -
JAVA总结(四):正则表达式匹配中文的三种方法
在对安全日志信息的分析过程中,我们经常需要利用正则表达式提取重要的字段信息,而中文就成为正则表达式绕不过去的一道坎。以“8个文件”作为测试字符串,依次做出匹配与字段提取操作。方法一:区段匹配众所周知,JAVA支持对Unicode字符的解析,请看清楚,是Unicode字符,不是UTF-8编码(只有在字节码中,才会转为UTF-8形式),于是我们可以使用Unicode指定字符的区间范围4E00到9FA5,原创 2017-08-17 14:07:34 · 51712 阅读 · 2 评论 -
JAVA总结(三):sun.jnu.encoding与file.encoding的区别
先说结论,sun.jnu.encoding是指操作系统的默认编码,file.encoding是指JAVA文件的编码(请记住,不是class文件,所有class文件的编码都是UTF-8),所以,在同一个操作系统上运行的JAVA应用程序,其sun.jnu.encoding完全相同,而file.encoding即使在同一个JAVA应用程序中,JAVA文件的编码也可以不一样。在大部分的情况下,sun.jnu原创 2017-08-10 19:39:24 · 8586 阅读 · 7 评论 -
JAVA总结(二):字符的编码与解码
中文字符出现乱码的原因是因为采用了错误的解码方式,换句话说,也就是没有采用与字符编码一致的方式进行解码。那如何将乱码字符还原呢?需要分为以下几步: 1. 将当前的乱码字符以当前解码的方式编码为二进制数组,这也是还原过程; 2. 然后以正确的方式(即原编码方式)进行解码;下面以接收到的乱码字符“鍥介檯绫冲叞”为例,再次讲解还原过程。 1. 首先获取当前乱码字符的解码方式;# 获取默认的字符编原创 2017-08-09 22:20:49 · 1331 阅读 · 0 评论 -
JAVA总结(一):怎样获取JVM的全局属性
在JAVA代码的跨平台实践中,我们需要知道操作系统的类型及版本,而JVM在启动时,就已经将这些信息内置在System的属性中(可通过System.getProperties()获取)。所以,如果要获取JVM运行的操作系统信息,只需要通过响应的键值获取即可:// 获取操作系统的名称System.getProperty("os.name")// 获取操作系统的版本System.getPrope原创 2017-08-09 22:18:53 · 2338 阅读 · 0 评论 -
并发(十三):线程都可以中断吗?
在长任务的运行过程中,有时我们需要提前中断任务的执行,以保持对用户操作的响应性,而在新版JAVA中,已没有能终止线程执行的方法(Thread.stop()已废除),在Thread提供的内置方法中,能影响Thread执行节奏的方法也就只有interrupt()了,那么所有的线程都能对中断进行响应吗?看如下的例子:static class PrimeThread extends Thread {原创 2017-08-01 20:05:14 · 945 阅读 · 0 评论 -
JAVA NIO(四):rewind与flip的用法差异
在ByteBuffer的使用中,为了尽可能地复用Buffer,我们不可避免地要重新设置ByteBuffer的position与limit,它们之间的差值就是remaining()方法的结果,也是Channel真正写入或读取的数据(超过limit的数据会自动丢弃),如下:ByteBuffer buff = ByteBuffer.allocate(10);// 存入7个字节的数据buff.put(原创 2017-08-28 19:50:17 · 3844 阅读 · 2 评论 -
JAVA 8函数式编程(四):JAVA支持闭包吗?
如果闭包的定义如此简单,请参看百度百科对闭包的定义: 闭包包含自由(未绑定到特定对象)变量;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。简单来说,就是可以绑定变量作用域,那么很显然,JAVA是完全支持闭包的,如下:static IntFunction<Integer> sumEx(int a) { // 定义局部变量 fin原创 2017-08-29 12:07:25 · 2352 阅读 · 0 评论 -
HttpClient Not in GZIP format的解决办法
在用HttpClient抓取图片的过程中,提示如下错误:Exception in thread "main" java.util.zip.ZipException: Not in GZIP format at java.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:165) at java.util.zip...原创 2018-07-05 16:00:51 · 11331 阅读 · 0 评论 -
一起SQL引发OOM的解决思路与过程
在TOMCAT WEB程序的运行过程中,突然触发了内存溢出错误,检查Tomcat的localhost日志,找到如下信息:java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:2245) at java.util.Arrays.copyOf(Arrays.ja原创 2017-11-27 19:50:45 · 3028 阅读 · 0 评论 -
JAVA反射(一):获取Class对象
1. 获取父类这是最简单也是最容易理解的方法——getSuperclass(),唯一需要说明的是,返回的一定是类,不是接口。2. 获取内部类获取内部类有两种,分别为class.getClasses()与class.getDeclaredClasses(),但它们两个差别极大,见下表: 方法名称 返回结果 包含接口 包含继承结果 仅包含公开 class.getClasses()原创 2017-12-20 23:17:29 · 1502 阅读 · 1 评论 -
Quartz中任意值*与不指定值?的区别
在Quartz定时任务的启动中,提示如下错误:java.text.ParseException: Support for specifying both a day-of-week AND a day-of-month parameter is not implemented. at org.quartz.CronExpression.buildExpression(CronExpressi原创 2017-11-23 15:18:33 · 831 阅读 · 0 评论 -
JDBC事务与ORM事务管理的差异与联系
1. JDBC需要事务吗?习惯里Spring JdbcTemplate的便捷性,一直以为JDBC不需要事务,但是仔细一想,如果有多条SQL语句同时执行,如何保证事务的完整性?仔细阅读JdbcTemplate的源码,发现底层实现都依赖于DataSourceUtils,而它在获取数据连接时,是依赖于事务管理器的,如下:public static boolean isConnectionTransacti原创 2017-12-12 21:37:01 · 1148 阅读 · 1 评论 -
Spring Boot(七):Spring Security如何启用与禁用CSRF
从Spring Security 4开始,默认启用CSRF机制,本来这也不算什么大事,但与Spring Boot结合在一起,那么实现起来就比较麻烦了,尤其是采用前后端分离式的开发架构后,配置CSRF机制就更困难了,几乎所有网上的解决办法都无法解决如何获取CSRF编码的难题,首先以表单登陆的错误镇楼:There was an unexpected error (type=Forbidden, stat原创 2017-11-06 17:14:11 · 26974 阅读 · 3 评论 -
JavaMail发送邮件无法显示图片的解决办法
在Java Mail的邮件发送中,所有的邮件客户端都显示正常,但Mac OS邮件客户端无法正常显示图片,仅仅显示一个蓝色的问号图片。首先按照BS模式与HTML的思维判定问题可能是没有指定图片的类型,于是添加了相应的图片类型说明,如“Content-Type”与“Disposition”,结果问题解决,完全的代码如下:// 显示图片必须为related,如果还需要添加附件必须为multi// 邮原创 2017-10-30 16:18:23 · 10650 阅读 · 3 评论 -
Spring Boot(六):如何配置静态资源的地址与访问路径
静态资源,例如HTML文件、JS文件,设计到的Spring Boot配置有两项,一是“spring.mvc.static-path-pattern”,一是“spring.resources.static-locations”,很多人都难以分辨它们之间的差异,所以经常出现的结果就是404错误,无法找到静态资源。1. “spring.mvc.static-path-pattern”spring.mvc.原创 2017-10-20 20:21:18 · 89018 阅读 · 20 评论 -
Spring Boot(五):如何在单元测试中自动回滚数据
在Spring Framework 3的单元测试中,针对数据库单元测试,我们一般会采用“@Rollback(true)”进行回滚,如下:@RunWith(SpringJUnit4ClassRunner.class)// 引入Spring配置文件@ContextConfiguration(locations = { "classpath:/META-INF/springContext/servi原创 2017-10-19 22:51:32 · 21651 阅读 · 5 评论 -
JavaMail如何别名发送邮件
在钓鱼邮件的欺骗中,最常用的手法就是为邮件发送人添加别名,如果邮件发送人的名称跟邮件接收人熟悉的别名相近的话,那钓鱼成功率要提升一倍。JAVA使用JavaMail工具包进行邮件发送,其MAVAN依赖如下:<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</art原创 2017-10-17 19:17:07 · 6293 阅读 · 0 评论 -
JAVA NIO(六):读取10G的文件其实很容易
读取10G的文本文件,我们可能会直接认为,这太难了,这涉及到内存的容量,硬盘的读取速度以及虚拟内存、页失败载入等概念,其实对JAVA,读取10G的文件轻而易举,无论bio(java.io)还是nio,都能轻松完成任务。本次测试的10G文件,来源于上篇文章《JAVA NIO(五):如何在5秒内写入10G的文本数据》的实验结果。1. FileInputStream VS BufferedInputStr原创 2017-09-30 12:25:31 · 25642 阅读 · 7 评论 -
并发(十六):不要使用Thread.join()——并行变串行
在多线程程序的编写中,为了同步线程的执行状态,我们为了方便,经常会使用Thread.join()方法,须不知此方法有重大的性能缺陷,能将多线程程序变成单线程程序,执行时间瞬间翻倍,示例如下:/** * 用于长时间的任务计算,一般求fabic(40)就会花费1秒的时间 * 花费时间呈指数增长速度 */static long fabic(int n) { if(n < 0) {原创 2017-09-20 22:23:15 · 13692 阅读 · 12 评论 -
JAVA 8函数式编程(六):怎样复用Stream对象
在JAVA 8的Stream方法中,分为两大类,一类是惰性求值,另一类是立刻求值,只要Stream调用了立刻求值,Stream就会自动关闭,如果再次调用,将会提示如下错误:java.lang.IllegalStateException: stream has already been operated upon or closed at java.util.stream.AbstractPi原创 2017-09-27 22:49:54 · 4580 阅读 · 0 评论 -
JAVA NIO(五):如何在5秒内写入10G的文本数据
首先说本机的性能,采用AS SSD Benchmark进行评测,写入能力大约在422M每秒,计划连续写入文本数据,直到达到要求为止(5G数据与10G数据),测试环境如下: 环境 版本 JDK 1.8.0_131 操作系统 Windows 10 专业版 x64 CPU Inter i7-3740QM 内存 16G 硬盘 三星512G SSD1. File原创 2017-09-28 21:29:27 · 15748 阅读 · 4 评论 -
JAVA NIO(三):缓冲区的相互转换及中文乱码的解决方案
在Java IO中,Channel(通道)只能直接与ByteBuffer进行通信,这样我们可能会用ByteBuffer的视图来解决数据的转换问题,如将字符串转换为二进制缓冲区,整数缓冲区转换为二进制缓冲区,示例如下:ByteBuffer buffer = ByteBuffer.allocate(100);// 获取缓冲区的视图,但与ByteBuffer的mark、position、limit互相原创 2017-08-23 18:40:48 · 5411 阅读 · 1 评论 -
Spring Boot(三):RestTemplate提交表单数据的三种方法
在REST接口的设计中,利用RestTemplate进行接口测试是种常见的方法,但在使用过程中,由于其方法参数众多,很多同学又混淆了表单提交与Payload提交方式的差别,而且接口设计与传统的浏览器使用的提交方式又有差异,经常出现各种各样的错误,如405错误,或者根本就得不到提交的数据,错误样例如下:Exception in thread "main" org.springframework.web原创 2017-09-11 23:13:13 · 96185 阅读 · 11 评论 -
JAVA 8函数式编程(五):收集器详解与自定义实现
在Stream的接口中,最强大的接口就是collect了,当然这也是最难的接口,它对Stream的应用过程可分为四步: 1. 利用Supplier接口,创建存储中间运算结果的容器(不是返回结果),扮演的角色为supplier; 2. 利用BiConsumer// 声明单词集合对象List<String> words = Lists.newArrayList("hi", "Hello", "H原创 2017-09-07 22:13:26 · 1225 阅读 · 0 评论 -
并发(九):检查死锁与Locked ownable synchronizers
通过jstack可快速检查线程的死锁信息,用法如下:# 获取JVM ID(JAVA 进程ID),通过参数lv可以获取更详细的JAVA方法调用信息jps -lv# 得到JVM ID后,执行jstack命令,这里假定为123# 将结果重定向到文件,更便于查看jstack -l 123 >> d:/123.txt翻到页底,可发现明显的死锁信息:Java stack information for原创 2017-07-24 11:27:44 · 38402 阅读 · 1 评论 -
正则表达式非贪婪模式的应用
贪婪模式又叫匹配优先模式,在整个表达式匹配成功的前提下,尽可能多的匹配,而非贪婪模式恰恰相反,在整个表达式匹配成功的前提下,尽可能少的匹配,针对的量词包括:{m, n}{m, }?*+从书写正则表达式的差异来看,它们的唯一区别在于非贪婪模式在贪婪模式的量词后面添加“?”,如下:{m, n}?{m, }???*?+?下面看一个具体的例子,从“[]”提取需要的字符,首先是贪婪模式://原创 2017-07-31 22:08:14 · 2100 阅读 · 0 评论 -
并发(一):理解可重入锁
在JAVA中,内置锁都是可重入的,也就是说,如果某个线程试图获取一个已经由它自己持有的锁时,那么这个请求会立刻成功,并且会将这个锁的计数值加1,而当线程退出同步代码块时,计数器将会递减,当计数值等于0时,锁释放。看例子,一目了然:new Thread() { /* (non-Javadoc) * @see java.lang.Thread#run() */ @Ove原创 2017-07-03 15:18:34 · 4851 阅读 · 0 评论