Hexo Blog

fsh的博客


  • 首页

  • 归档

Spring-Boot 快速使用

发表于 2018-10-23 更新于 2019-02-20

Spring-Boot 介绍

架构
spring boot
MyBatis-Plus
MySql
start

实体映射表

1
2
3
4
5
6
7
8
9
10
11
12
13
@Data
@EqualsAndHashCode(callSuper = false)
#表名称 配置映射表
@TableName("t_cc_*")
public class Dao implements Serializable {
/**实现序列化,实现serializable接口的作用是就是可以把对象存到字节流,然后可以恢复。网络传输需要用到,分布式系统尤其重要*/
private static final long serialVersionUID = 1L;

//设置主键自增
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String tableName;
private String tableColumn;

Mapper层

1
2
3
4
5
6
@Mapper
public interface Mapper extends BaseMapper<Dao> {
//自定义sql
@Select("SELECT t.id,t.Key,t.name,t.version,t.createTime,t.mark FROM t_apk t where Key=#{Key}")
Dao selectByKey(@Param("Key") String Key);
}

service实现层

TO 继承了MyBatis-Plus的Pagination类有了分页属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Service
public class ServiceImpl implements Service {

private static AndroidPackageMapper mapper;

@Autowired
@SuppressWarnings("SpringJavaAutowiringInspection")
public AndroidPackageServiceImpl(AndroidPackageMapper mapper){
this.mapper=mapper;
}

@Override
public ActionResult<Page> List(TO){
EntityWrapper<DO> ew = new EntityWrapper<>();
ew.where("key={0}",key)
List<DO> DOList=mapper.selectPage(TO,ew);
Page<AndroidPackageVO> page=new Page(TO.getCurrent(),TO.getSize());
page.setRecords(DOList);
page.setTotal(TO.getTotal());
ActionResult<Page> ar=new ActionResult<>();
ar.setResult(page);
return ar;
}

}

service层

使用在启动类上使用@EnableTransactionManagement注解开启事务,在单元测试中的test函数上添加 @Transactional 注解配合
@Rollback 注解让每个单元测试都能在结束时回滚

1
2
3
4
5
//开启事务
@Transactional
public interface AndroidPackageService {
ActionResult<Page> List(TO)
}

controller层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@RestController
@RequestMapping("/api/Controller")
public class Controller {
//参数层次较多时用@RequestBody注解映射
@RequestMapping("/find")
public ResponseEntity<ActionResult> findAPKList(@RequestBody PageTO pageTO){
ActionResult<Page> result=Service.List(pageTO);
return ResponseEntity.ok(result);
}

//参数层次单一时
@RequestMapping("/delete")
public ResponseEntity<ActionResult> delete(String key){
ActionResult<String> result=Service.delete(key);
return ResponseEntity.ok(result);
}
}

阿里的JSONObject对象转换

发表于 2018-10-19

FASTJSON

GitHub
Fastjson是一个Java库,可用于将Java对象转换为其JSON表示。它还可用于将JSON字符串转换为等效的Java对象。Fastjson可以处理任意Java对象,包括您没有源代码的预先存在的对象。

Fastjson目标

1.在服务器端和Android客户端提供最佳性能
2.提供简单的toJSONString()和parseObject()方法,将Java对象转换为JSON,反之亦然
3.允许将预先存在的不可修改对象转换为JSON和从JSON转换
4.广泛支持Java Generics
5.允许对象的自定义表示
6.支持任意复杂的对象(具有深层继承层次结构和泛型类型的广泛使用)

Maven

1
2
3
4
5
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.49</version>
</dependency>

JSONObject对象转换

1
2
3
4
5
6
7
8

JSONObject.toJSONString(Javabean对象)

JSONObject.toJavaObject(JSON字符串,Javabean.class)

JSONObject.parseObject(JSON字符串)

JSONObject.parseObject(JSON字符串,Javabean.class)

Spring-Booot 下的线程和进程

发表于 2018-10-18 更新于 2019-01-07

@Component 注解

@component 把普通pojo实例化到spring容器中,相当于配置文件中的
@component有3个为扩展:
1、@controller 控制器(注入服务)
2、@service 服务(注入dao)
3、@repository dao(实现dao访问)

异步注解

在启动类*Application的上面添加@EnableAsync注解

在异步类的上面添加@Async

通常将异步执行的方法单独抽取成一个类方便阅读和避免调用方法的是对象本身,从而导致异步变成同步。具体一点就是spring容器在初始化时会将有AOP注解的类对象“替换”为代理对象,因此异步方法在同一类中会变成调用对象本身而非代理对象。

如果需要在一个类使用则需要通过上下文SpringUtil.getBean(获取本身)来获得代理对象。然后通过代理对象使用。

或者AopContext.currentProxy()获取当前代理对象,改对象和上面对象是同一个。

##超时处理
修改下异步方法的返回类型,原本返回空修改成返回Future

WebSocket

发表于 2018-10-16

WebSocket

WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。
WebSocket通信协议于2011年被IETF定为标准RFC 6455,并被RFC7936所补充规范。

Hexo 主题-NexT

发表于 2018-10-15 更新于 2019-08-01

NexT

Next官网

安装Next

1
$ git clone https://github.com/iissnan/hexo-theme-next themes/next

配置主题(bolg下的_config.yml)

1
2
theme: next
language: zh-Hans

配置主题风格

1
2
3
#scheme: Muse
#scheme: Mist
scheme: Pisces

Hexo指令

1
2
3
$ hexo clean
$ hexo g
$ hexo s

Hexo控制台警告修复

原文
假如你正在Windows上写程序,又或者你正在和其他人合作,他们在Windows上编程,而你却在其他系统上,在这些情况下,你可能会遇到行尾 结束符问题。 这是因为Windows使用回车和换行两个字符来结束一行,而Mac和Linux只使用换行一个字符。 虽然这是小问题,但它会极大地扰乱跨平台协作。

Git可以在你提交时自动地把行结束符CRLF转换成LF,而在签出代码时把LF转换成CRLF。用core.autocrlf来打开此项功能, 如果是在Windows系统上,把它设置成true,这样当签出代码时,LF会被转换成CRLF:

$ git config –global core.autocrlf true

Linux或Mac系统使用LF作为行结束符,因此你不想Git在签出文件时进行自动的转换;当一个以CRLF为行结束符的文件不小心被引入时你肯定想进行修正, 把core.autocrlf设置成input来告诉Git在提交时把CRLF转换成LF,签出时不转换:

$ git config –global core.autocrlf input

这样会在Windows系统上的签出文件中保留CRLF,会在Mac和Linux系统上,包括仓库中保留LF。

如果你是Windows程序员,且正在开发仅运行在Windows上的项目,可以设置false取消此功能,把回车符记录在库中:

$ git config –global core.autocrlf false

NexT主题配置

themes/next/_config.yml

menu:
home: /
archives: /archives

#about: /about

#categories: /categories
tags: /tags

#commonweal: /404.html

https://hexo.io/zh-cn/docs/tag-plugins.html

Spring Boot 下的单元测试

发表于 2018-10-12 更新于 2019-01-29

Idea下快速生成指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
ctrl+shift+t --> create new test
```

## 常使用注解
```java
类注解
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureTestDatabase(replace = NONE) 对真实数据库运行测试
public class MultipartFileServiceImplTest {
服务注解
@Resource
private *Service service;
```

## 校验结果
[参考](https://blog.csdn.net/sz85850597/article/details/80427408)
Assert.assertThat();

想判断某个字符串 s 是否含有子字符串 "developer" 或 "Works" 中间的一个
assertThat(s, anyOf(containsString("developer"), containsString("Works")));

字符相关匹配符
/**equalTo匹配符断言被测的testedValue等于expectedValue,
* equalTo可以断言数值之间,字符串之间和对象之间是否相等,相当于Object的equals方法
*/
assertThat(testedValue, equalTo(expectedValue));
/**equalToIgnoringCase匹配符断言被测的字符串testedString
*在忽略大小写的情况下等于expectedString
*/
assertThat(testedString, equalToIgnoringCase(expectedString));
/**equalToIgnoringWhiteSpace匹配符断言被测的字符串testedString
*在忽略头尾的任意个空格的情况下等于expectedString,
*注意:字符串中的空格不能被忽略
*/
assertThat(testedString, equalToIgnoringWhiteSpace(expectedString);
/**containsString匹配符断言被测的字符串testedString包含子字符串subString**/
assertThat(testedString, containsString(subString) );
/**endsWith匹配符断言被测的字符串testedString以子字符串suffix结尾*/
assertThat(testedString, endsWith(suffix));
/**startsWith匹配符断言被测的字符串testedString以子字符串prefix开始*/
assertThat(testedString, startsWith(prefix));

一般匹配符
/**nullValue()匹配符断言被测object的值为null*/
assertThat(object,nullValue());
/**notNullValue()匹配符断言被测object的值不为null*/
assertThat(object,notNullValue());
/**is匹配符断言被测的object等于后面给出匹配表达式*/
assertThat(testedString, is(equalTo(expectedValue)));
/**is匹配符简写应用之一,is(equalTo(x))的简写,断言testedValue等于expectedValue*/
assertThat(testedValue, is(expectedValue));
/**is匹配符简写应用之二,is(instanceOf(SomeClass.class))的简写,
*断言testedObject为Cheddar的实例
*/
assertThat(testedObject, is(Cheddar.class));
/**not匹配符和is匹配符正好相反,断言被测的object不等于后面给出的object*/
assertThat(testedString, not(expectedString));
/**allOf匹配符断言符合所有条件,相当于“与”(&&)*/
assertThat(testedNumber, allOf( greaterThan(8), lessThan(16) ) );
/**anyOf匹配符断言符合条件之一,相当于“或”(||)*/
assertThat(testedNumber, anyOf( greaterThan(16), lessThan(8) ) );
数值相关匹配符
/**closeTo匹配符断言被测的浮点型数testedDouble在20.0¡À0.5范围之内*/
assertThat(testedDouble, closeTo( 20.0, 0.5 ));
/**greaterThan匹配符断言被测的数值testedNumber大于16.0*/
assertThat(testedNumber, greaterThan(16.0));
/** lessThan匹配符断言被测的数值testedNumber小于16.0*/
assertThat(testedNumber, lessThan (16.0));
/** greaterThanOrEqualTo匹配符断言被测的数值testedNumber大于等于16.0*/
assertThat(testedNumber, greaterThanOrEqualTo (16.0));
/** lessThanOrEqualTo匹配符断言被测的testedNumber小于等于16.0*/
assertThat(testedNumber, lessThanOrEqualTo (16.0));
集合相关匹配符
/**hasEntry匹配符断言被测的Map对象mapObject含有一个键值为"key"对应元素值为"value"的Entry项*/
assertThat(mapObject, hasEntry("key", "value" ) );
/**hasItem匹配符表明被测的迭代对象iterableObject含有元素element项则测试通过*/
assertThat(iterableObject, hasItem (element));
/** hasKey匹配符断言被测的Map对象mapObject含有键值“key”*/
assertThat(mapObject, hasKey ("key"));
/** hasValue匹配符断言被测的Map对象mapObject含有元素值value*/
assertThat(mapObject, hasValue(value));

## 使用Mockito来录制结果
```java
//Let's import Mockito statically so that the code looks clearer
import static org.mockito.Mockito.*;

//mock creation
List mockedList = mock(List.class);

//using mock object
mockedList.add("one");
mockedList.clear();

//verification
verify(mockedList).add("one");
verify(mockedList).clear();

when(mockedList.get(0)).thenReturn("first");
when(mockedList.get(1)).thenThrow(new RuntimeException());

Mockito注释

@mock
标记一个模仿区域
1.快速创建模拟
2.减少重复代码
3.使得的代码更有可读性
4.使验证错误更易于阅读,因为字段名称用于标识模拟

@injection
1.允许快速模拟和注入。
2.最大限度地减少重复模拟和注入。

注:无法注入接口,如果要测试,直接用实现类测试

@spy
1.快速创建间谍类

LomLombok使用

发表于 2018-09-25 更新于 2018-12-27

实体映射表

1
2
#根据属性生成get和set方法
@Data

在线预览文档

发表于 2018-09-22 更新于 2019-08-01

java实现在线预览功能,无非是将各类文档转换成前端可以解析的统一格式的文件,前端可解析文件一般是目前有pdf或者html。

选用格式分析

pdf处理原理

1.通过第三方工具openoffice,将word、excel、ppt、txt等文件转换为pdf文件;
2.通过swfTools将pdf文件转换成swf格式的文件;
3.通过FlexPaper文档组件在页面上进行展示。

html处理原理

或者通过poi实现word、excel、ppt转html,这样就可以放在页面上了
ppt转成图片时,如果字体不是宋体会发时乱码
poi还有一些兼容问题,不太支持wps的文档

通过个种在线工具对比,发现转成html,文档格式变动比较大,但是代码量相对较少,实现比较简单
而转成pdf对性能消耗比较大,文档格式基本无损,代码量较多,实现逻辑相对复杂

还有一种 第三方成熟的服务 如OfficeWeb365
优点很多,但是缺点致命,首先必须联网,然后文档安全无法保证,不稳定。

选用技术分析

jacob插件

jacob允许在java中调用com接口自动组件,它使用JNI(本地调用程序)来进行本地调用COM库。它可运行在x86和支持32位和64位Java虚拟机 X64的环境。

需下载jacob-1.19-x86.dll 、jacob-1.19-x64.dll 并将文件放到jdk bin目录下,用户调用时启动插件功能
最后需要通过ComThread.Release()语句释放winword.exe进程
但是当被部署项目的服务器是centOS等linux server时,就不能用使用相关插件

OpenOffice

OpenOffice跨平台可以在Windows和Linux下运行,并且开源免费(原则上GPL开源协议不推荐,相当于别人开源了你也需要开源不适用于商业软件)

开源协议

开发思路
参考block
1.一个文件只转换一次
2.多线程,OpenOffice为单进程不支持多线程,故需要多开进程(一个程序至少有一个进程,一个进程至少有一个线程)
3.存在用户同时请求未转换完文档,导致重复转换导致异常的情况,故需要加锁处理

OpenOffice转excel为pdf时出现折行

参考block
问题:Java 操作 OpenOffice 将excel 转换为 pdf ,因多列出现折行;
原因:OpenOffice 默认输出为A4 大小,源excel 存在队列,总宽度超出 A4 宽度,所以出现折行;
解决方法:自定义一个类,继承OpenOfficeDocumentConverter 类 重写方法,与 refreshDocument 方法,设置 OpenOffice 输出 pdf 的宽度参数

Java 中foreach

发表于 2018-09-20 更新于 2019-02-13

不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator
方式,如果并发操作,需要对 Iterator 对象加锁。
正例:

1
2
3
4
5
6
7
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if (删除元素的条件) {
iterator.remove();
}
}

反例:

1
2
3
4
5
6
7
8
List<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
for (String item : list) {
if ("1".equals(item)) {
list.remove(item);
}
}

说明:以上代码的执行结果肯定会出乎大家的意料,那么试一下把“1”换成“2”,会是同样的
结果吗?

执行后“1”是正常 换成2后抛出ConcurrentModificationException异常

ArrayList 的内部类 Itr 实现了 Iterator 接口 其中checkForComodification回判断集合的实际结构变化次数 和 Itr 记录的变化次数,不相等时,则抛出 ConcurrentModificationException 异常

(参考)[https://www.jianshu.com/p/724f763fd242]

JavaScript
数组遍历
foreach 无返回
map 返回相同长度的数组
filter 返回符合条件的数组
reduce 折叠数组

Lambda

发表于 2018-09-19 更新于 2018-10-26

参考百科

Lambda 表达式

“Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。

Java表达式

Java 8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁。当开发者在编写Lambda表达式时,也会随之被编译成一个函数式接口。下面这个例子就是使用Lambda语法来代替匿名的内部类,代码不仅简洁,而且还可读。

没有使用Lambda的老方法:

1
2
3
4
5
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent actionEvent){
System.out.println("Action detected");
}
});

匿名内部类

1
2
3
4
5
6
7
8
9
10
public class Test {
public static void main(String[] args) {
//第一种方式:
Outter outter = new Outter();
Outter.Inner inner = outter.new Inner(); //必须通过Outter对象来创建

//第二种方式:
Outter.Inner inner1 = outter.getInnerInstance();
}
}

使用Lambda:

1
2
3
button.addActionListener(() -> { 
System.out.println("Action detected");
});

让我们来看一个更明显的例子。

不采用Lambda的老方法

1
2
3
4
5
6
Runnable runnable1=new Runnable(){
@Override
public void run(){
System.out.println("Running without Lambda");
}
};

使用Lambda:

1
2
3
Runnable runnable2=()->{
System.out.println("Running from Lambda");
};

1
2
3
4
5
6
7
8
9
scenes.forEach((ProgramScene scene) ->{
List children = scene.getChildren();
if(children != null && children.size() > 0){
children.forEach(o->{
if(o instanceof JSONObject)
result.addAll(this.getMaterials((JSONObject)o));
});
}
});

正如你所看到的,使用Lambda表达式不仅让代码变的简单、而且可读、最重要的是代码量也随之减少很多。然而,在某种程度上,
这些功能在Scala等这些JVM语言里已经被广泛使用。

并不奇怪,Scala社区是难以置信的,因为许多Java 8里的内容看起来就像是从Scala里搬过来的。在某种程度上,Java 8的语法
要比Scala的更详细但不是很清晰,但这并不能说明什么,如果可以,它可能会像Scala那样构建Lambda表达式。

一方面,如果Java继续围绕Lambda来发展和实现Scala都已经实现的功能,那么可能就不需要Scala了。另一方面,如果它只提供一
些核心的功能,例如帮助匿名内部类,那么Scala和其他语言将会继续茁壮成长,并且有可能会凌驾于Java之上。其实这才是最好的结果,有竞争才有进步,其它语言继续发展和成长,并且无需担心是否会过时。

函数语言

Lambda演算和函数式语言的计算模型天生较为接近,Lambda表达式一般是这些语言必备的基本特性。如:
Scheme:

1
(lambda(x)(+x1))

Haskell:

1
\x->x+1

Java8新特性Stream

Java 8 中的 Stream 是对集合(Collection)对象功能的增强

1…456

fsh

54 日志
4 分类
20 标签
© 2019 fsh
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Pisces v7.3.0