Java小问题汇总

1. MySQL5.7下的JSON字段中文乱码问题

中文乱码问题在Java Web开发中经常碰到,大部分原因是后端与前端的编码不一致造成的(如tomcat的默认编码为ISO-8859-1,而前端为GBK),解决办法也简单,只需要加一个CharsetEncodingFilter就行。但本文要讲的不是这一类总是,而是纯粹的后端问题。

1.1 环境准备

假设MySQL的默认CharSet为UTF-8,应用及部署环境也为UTF-8

  • 创建包含JSON字段的数据库表
1
2
3
4
5
6
7
8
CREATE TABLE "ipms_device_feature" (
"ID" int(11) NOT NULL AUTO_INCREMENT,
"DEVICE_SERIAL_NUMBER" varchar(100) NOT NULL DEFAULT '' COMMENT '设备SN',
"DEVICE_IP" varchar(32) NOT NULL DEFAULT '' COMMENT '设备IP',
"FEATURES" json DEFAULT NULL COMMENT '设备巡检指标集',
"UPDATETIME" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY ("ID")
)
  • 运行如下脚本查看字段详细信息
1
show full fields from ipms_device_feature

结果如下:
mysql_json

上图中features这个字段的Collation列为Null

1
2
# 使用如下SQL时,JDBC在解析返回的数据(包含中文)时会出现乱码
select features from ipms_device_feature
  • 解决办法

第一步:使用MySQL提供的json_unquote方法

1
select json_unquote(features) as features from ipms_device_feature

第二步:在Java中调用上面的SQL时,将会返回一个byte数组,因此只需要通过String提供的方法进行转码就行。

1
2
3
4
5
List<Map> rows = em.createNamedQuery("XXX").list();
for(Map row : rows) {
byte[] bytes = (byte[]) row.get("features");
String features = new String(bytes, "UTF-8");
}

这样的话,Java变更features就是正常的中文,就可以直接回传给前端页面了。

2. 几个容易踩的坑

2.1. Integer对象之间比较的坑

对于Integer var=?-128127之间的赋值,Integer 对象是在IntegerCache.cache产生,会复用已有对象,这个区间内的Integer值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象。因此建议Integer对象在比较时应使用equals方法。

2.2. ArrayListsubList()方法返回值的坑

ArrayListsubList方法返回的结果不可强转成ArrayList,否则会抛出ClassCastException异常:

1
java.util.RandomAccessSubList cannot be cast to java.util.ArrayList;

因为subList方法返回的是ArrayList的内部类SubList,并不是ArrayList,而是ArrayList的一个视图,对于内部类SubList的所有操作最终会反映到原列表上。

2.3. Arrays.asList()方法返回值的坑

使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的 add/remove/clear方法会抛出UnsupportedOperationException异常。因为asList方法的返回对象是一个Arrays内部类,并没有实现集合的修改方法。Arrays.asList体现的是适配器模式,只是转换接口,后台的数据仍是数组。

1
2
3
4
String[] str = new String[] { "a", "b" };
List list = Arrays.asList(str);
list.add("c"); // 运行时异常。
str[0]= "gujin"; // 则list.get(0)也会随之修改。

3. 新版Eclipse Neon运行Junit报NPE

  • 问题描述:在Eclipse中创建单元测试用例(项目依赖的版本为junit-4.4)时,报如下错误
1
2
3
4
5
6
7
8
9
10
java.lang.NullPointerException
at org.eclipse.jdt.internal.junit4.runner.SubForestFilter.shouldRun(SubForestFilter.java:81)
at org.junit.internal.runners.JUnit4ClassRunner.filter(JUnit4ClassRunner.java:110)
at org.junit.runner.manipulation.Filter.apply(Filter.java:47)
at org.junit.internal.requests.FilterRequest.getRunner(FilterRequest.java:34)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createFilteredTest(JUnit4TestLoader.java:77)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:68)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:43)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:444)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
  • 原因分析:新版Eclipse在启动单元测试用例时调用的是JUnit新版本的方法,即Eclipse已不支持junit4.9以下的版本。

  • 解决办法:升级JUnit依赖版本即可

Windows下修改tomcat配置

1
2
3
4
5
6
7
8
9
10
# 将tomcat安装成window后台服务:
service.bat install tomcat8-cza

# 卸载服务
service.bat remove tomcat8-cza

# 配置JVM内存参数
cd <tomcat_home>/bin
tomcat8w.exe //MS/tomcat8-cza
# 在桌面右下角可以看到tomcat8w.exe的服务管理图标,点击“配置”,选择“java”标签,即可修改JVM参数。

获取echarts地图中各地区的经纬度信息

1
echarts.getMap('福州').geoJson.features.forEach(function(item){console.log('"' + item.properties.name + '"' + ": [" + item.properties.cp + "],")});

待续…

转载请注明出处:cloudnoter.com