使用jackson来实现json和object之间转换。
使用的时候在resultMap中,对应的列配置,例如:
1 | <result column="specs" property="specs" |
1 | update table_xxx |
JsonTypeHandler.java
1 | package cn.devmgr.tutorial.typehandler; |
使用jackson来实现json和object之间转换。
使用的时候在resultMap中,对应的列配置,例如:
1 | <result column="specs" property="specs" |
1 | update table_xxx |
1 | package cn.devmgr.tutorial.typehandler; |
在调用https的外部接口时,遇到一个异常:
Caused by: java.lang.RuntimeException: Could not generate DH keypair
at sun.security.ssl.ECDHCrypt.<init>(ECDHCrypt.java:82)
at sun.security.ssl.ClientHandshaker.serverKeyExchange(ClientHandshaker.java:724)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:281)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:961)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
... 103 common frames omitted
Caused by: java.security.InvalidAlgorithmParameterException: parameter object not a ECParameterSpec
at org.bouncycastle.jce.provider.JDKKeyPairGenerator$EC.initialize(Unknown Source)
at sun.security.ssl.ECDHCrypt.<init>(ECDHCrypt.java:77)
... 110 common frames omitted
发现maven打包依赖时加入org.bouncycastle:bcprov-jdk14导致,老版本的bcp只支持1024位加密,遇到2048位加密就出这个异常了。
有两个办法解决,推荐第一个,彻底解决:
* 找到依赖org.bouncycastle:bcprov-jdk14的配置,用exclusion排除它,并加入最新的bcprov。
* 在java命令行加参数: -Dcom.sun.net.ssl.enableECC=false
我的项目出错是由于itextpdf-5.0依赖了bcprov-jdk14,升级到itextpdf-5.5.13并增加了对bcprov-jdk15的依赖。 由于itextpdf-5.5.13中对bcprov-jdk15的依赖是optional,需要另外增加bcprov-jdk15
1 | <dependency> |
@Autowired在查找构件时,会从构件库中查找所有构件,查找所有是被注解变量的类型或该类型的子类。
在使用@Autowired注解装载构件时,可以增加一个@Qualifier指定一个待装载构件的名字
1 | @Autowired @Qualifier("thisone") MyObject myObject; |
上面这种写法可以解决多个MyObject的子类被设置成component的状况
相应的,在构件上有两种写法:
1 | @Service("thisone") |
也可以
1 | @Qualifier("thisone") |
注意给构件起名不要重复,重名会抛异常的。
定制RestController中Date类型转换为JSON时的格式有两种方法:
两个方法都有,注解优先级高。
1 | spring: |
long型的timestamp表示日期:
1 | @JsonFormat(shape = JsonFormat.Shape.NUMBER) |
字符串表示日期:
1 | @JsonFormat(timezone="GMT+8", pattern="yyyy-MM-dd") |
Mybatis写mapper时,每个表都需要INSERT UPDATE写很长的语句比较麻烦,80%的表和java bean是简单的一一对应关系,因此考虑使用mybatis的SQLProvider注解减少这部分重复劳动。
SELECT和DELETE语句由于涉及字段较少,写起来还在可接收范围内,所以没做通用的。
也可以把javabean增加写注解,类似JPA那样指定表名、字段名、主键等,但做得太多就失去了mybatis依赖SQL的灵活性了
1 | import java.lang.reflect.Field; |
1 | import org.apache.ibatis.annotations.InsertProvider; |
POM文件中加入spring-boot-devtoools的依赖,可以在修改后自动重启,方便开发过程中测试。
1 | <dependency> |
需要IDE工具打开自动编译,因为devtools是监视class文件的修改后自动重启,不是监视src目录下的java文件。
IntelliJ IDEA可以通过Build菜单下的Build Project来编译项目。
如果需要配置devtools,可以通过在application.yml里加入
1 | spring: |
如果使用了maven的多模块功能,devtools的依赖需要加到子模块中,加入到父模块不起作用,因为optional=true,是可选依赖,子模块不会继承它。
CURL常用用法汇总。
调用GET方法最简单
1 | curl http://127.0.0.1:8080/tvseries/ |
1 | curl -H "user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0“ http://localhost:8080 |
1 | curl -H "Authorization: Bearer 7e161a1a-4590-4696-9d90-516c54113906" http://localhost:8080/api/exam |
增加 -v 参数可以显示连接过程的详细信息,发送和接收到的HTTP头信息等等,如果不增加 -v,只显示 http response body部分内容
1 | curl -v http://localhost:8080 |
1 | curl -H "Content-Type:application/json" -X POST --data '{"name": "West World", “originRelease":"2016-10-02"}’ http://127.0.0.1:8080/tvseries/ |
上面的data参数是用的单引号包含起来的,内容json部分有双引号。这种写法在windows下可能会出错,需要用双引号,改成如下方式:
1 | curl -H "Content-Type:application/json" -X POST --data "{\"name\": \"West World\", \“originRelease\":\"2016-10-02\"}\" http://127.0.0.1:8080/tvseries/ |
1 | curl -X DELETE https://127.0.0.1:8080/tvseries/23/ |
1 | curl -H “Content-Type:application/json” -X PUT —data ‘{“name”: “Person of Interest”} http://127.0.0.1:8080/tvseries/33/ |
PUT 方法同 POST 方法,一般需要指定传输的数据。
需要服务端支持才可,并不是标准的HTTP服务。
使用临时文件,需要2个命令,先创建一个压缩文件,后发送:
1 | echo '{ "mydummy" : "json" }' | gzip > body.gz |
或者使用管道符合并到一行上
1 | echo '{"type": "json", "length": 2222}' | gzip | curl -H "Content-Type: application/json" -H "Content-Type: gzip" -X POST -d @- http://127.0.0.1:8080/ss |
在使用spring的时候,如果Controller中抛出异常,会被spring显示在客户端界面,而日志中一般没有记录。
客户端对异常的显示也是经spring处理后的信息,没有堆栈,这不方便找错和改错。
可以通过RestControllerAdvice注解定义一个异常处理类来解决这个问题。代码如下
注:也可以不继承ResponseEntityExceptionHandler类,此处继承只是省了一些通用异常的处理。
1 | import java.util.HashMap; |
查看java内存使用状况可以通过jmap命令,例如: jmap -histo:live PID
如果执行命令是出现下述错误:
jmap -histo:live 19114
19114: Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding
这是因为19114号进程的属主和当前执行jmap的用户不一致,换成一致的用户即可,例如:
1 | sudo -u tomcatuser jmap -histo:live 19114 |
可以把方法设置成返回 ResponseEntity<T>
类型,其中的泛型T取代以前想返回的类型,然后通过 ResponseEntity.status(HttpStatus.OK).body(result)
方法创建返回结果,其中第一个status就是设置返回的ResponseCode
1 | @PostMapping |