Fork me on GitHub
行锋

低头走路,抬头思考


  • 首页

  • 分类

  • 归档

  • 标签

  • 关于

  • 搜索

Linux防火墙管理

发表于 2018-11-26 | 分类于 Linux
  • 查看防火墙状态: firewall-cmd --state
  • service firewall start|stop|restart
  • 端口管理:
1
2
firewall-cmd --permanent --add-port=8080-8085/tcp
firewall-cmd --permanent --remove-port=8080-8085/tcp
  • 启用防火墙设置:firewall-cmd reload
  • firewall-cmd --permanent --list-ports
  • firewall-cmd --permanent --list-services

https://www.cnblogs.com/moxiaoan/p/5683743.html

Linux文件目录

发表于 2018-11-26 | 分类于 Linux

![image](/pub-images/Linux 文件目录.png)

Java8 特性

发表于 2018-11-26 | 分类于 Java

[toc]

SAM接口

Java8中增加了一个新的包:java.util.function,它里面包含了常用的函数式接口

1
2
3
4
5
6
Predicate<T>——接收T对象并返回boolean
Consumer<T>——接收T对象,不返回值
Function<T, R>——接收T对象,返回R对象
Supplier<T>——提供T对象(例如工厂),不接收值
UnaryOperator<T>——接收T对象,返回T对象
BinaryOperator<T>——接收两个T对象,返回T对象

lambda表达式

参考:http://note.youdao.com/noteshare?id=3bc7675e64b86f5e9b75534c0e436694

方法引用和构造器引用

方法引用

1
2
3
4
5
objectName::instanceMethod

ClassName::staticMethod

ClassName::instanceMethod
  1. 前两种方式类似,等同于把lambda表达式的参数直接当成instanceMethod|staticMethod的参数来调用
  2. 最后一种方式,等同于把lambda表达式的第一个参数当成instanceMethod的目标对象,其他剩余参数当成该方法的参数

构造器引用

构造器引用语法如下:ClassName::new,把lambda表达式的参数当成ClassName构造器的参数 。例如BigDecimal::new等同于x->new BigDecimal(x)

Stream语法

stream就是JAVA8提供给我们的对于元素集合统一、快速、并行操作的一种方式。
它能充分运用多核的优势,以及配合lambda表达式、链式结构对集合等进行许多有用的操作

  1. Stream是元素的集合,这点让Stream看起来用些类似Iterator,可以把Stream当成一个装饰后的Iterator;
  2. 可以支持顺序和并行的对原Stream进行汇聚的操作;
1
2
List<Integer> nums = Lists.newArrayList(1,null,3,4,null,6);
nums.stream().filter(num -> num != null).count();

Kotlin

发表于 2018-11-26 | 分类于 Kotlin

http://kotlinlang.org/
https://try.kotlinlang.org/#/Examples/Hello, world!/Simplest version/Simplest version.kt

Kotlin作者Andrey
Kotlin是一种在 Java 虚拟机上运行的静态类型编程语言,被称之为 Android 世界的Swift,由 JetBrains 设计开发并开源
Kotlin是一种运行在Java虚拟机、Android、浏览器上的静态语言
Kotlin可以编译成Java字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。
Android官方语言;100%兼容Java;Kotlin-js前端开发;Kotlin-jvm服务端开发;Kotlin-native本地执行程序;Kotlin是一门全栈语言

千里之行,始于Hello World

Kotlin不存在拆箱装箱问题;Kotlin不可隐式转换类型
var tmp:[类型]=[变量值]

Boolean类型
Number数据类型:Byte,Short,Int,Long,Float,Double
Char数据类型:Char
String数据类型:String 字符串a==b 比较内容;a===b比较应用 字符串模版$args1 args1+args2,引号中{args1+args2},引号中args1+args2,引号中引用变量 ,多行
var a:String …
a1
a2
…

Kotlin中 Any 等于 Java中 Object,是顶级类

空类型:任意类型都有可空和不可空两种状态,?表示可为空,!!表示强制认定nullable不可为空
fun main(args:Array){
var name:String = getName() ?: return
println(name)

var tmp:String? = "Hello Kotlin"
println(tmp)
println(tmp!!.length)

}

fun getName():String?{
return null
}

智能类型转换
Java方式的:var sub:Subclass = parent as Subclass //类似于Java方式,转换异常则会抛异常
安全类型转换:var sub:Subclass? = parent as? Subclass //如果转换失败,则返回null,不抛异常

if(parent is Subclass)

import com.test as test

区间Range:一个数学上的概念,表示范围;是ClosedRange的子类,IntRange最常用;i in 0…1024 判断i是否在区间内
var range:IntRange = 0…1024 //[0,1024]
var range:IntRange = 0 until 1024 //[0,1024) == [0,1023]

className::java.class.name
className::java.class.simpleName

数组: val array:Array<> = arrayOf(…)
为了避免不必要的拆箱和装箱,基本类型的数组是定制的
val arrayOfInt:IntArray = intArrayOf(1,2,4)
val arrayOfChar:CharArray = charArrayOf(‘H’,‘e’,‘y’)
val arrayOfString: Array = arrayOf(“Hello”,“Kotlin”)
val arrayOfOther:Array = arrayOf(Other(1),Other(2))

常量:val,常量因为赋值了,编译器可以推导出来类型,所以类型可以不用写,变量:var

External Tools
Tools->Kotlin->Show Kotlin Bytecode

函数:Kotlin中没有申明返回值的默认返回值是Unit
kotlinc安装,使用和javac一样
变量函数
var int2Long = fun(x:Int):Long{
return x.toLong()
}
int2Long(123)
fun sum(arg1:Int,arg2:Int) = arg1+arg2
Lambda表达式调用使用()或者invoke(),如:sum(1,2) 或 sum.invoke(1,2)
Lambda表达式–匿名函数

var = {arg1:Int,arg2:Int -> arg1+arg2}

arrayOfString.forEach { println(it) } //如果字面函数只有一个参数,可以省略该参数声明,并用“it”代替
arrayOfString.forEach(::println)

Lambda表达式中的return
https://www.jianshu.com/p/92cd94cba709?utm_source=oschina-app

public inline fun Array.forEach(action: (T) -> Unit): Unit {
for (element in this) action(element)
}

indexes.forEach {
if (it > 5) {
return@forEach
}
println(it)
}

indexes.forEach label@ {
if (it > 5) {
return @label
}
println(it)
}

函数参数调用时最后一个Lambda可以移出去
函数参数只有一个Lambda,调用时小括号可以省略
Lambda有一个参数,可默认为it
入参、返回值与形参一致的函数可以用函数引用的方式作为实参传入

类成员方法和成员变量
class B
class A{
var b=0;
lateinit var c:String
val d:B by lazy{
B()
}
}
属性初始化

  1. 尽量在构造方法中完成
  2. 无法在构造方法中完成的,尝试降级为局部变量
  3. var用lateinit延迟初始化,val用lazy
  4. 可空类型慎用null直接初始化

中缀表达式:只有一个参数,且用infix修饰的函数
class Book {infix fun on(placeString:String){…}}
Book() on “My Desk” //使用方式
分支表达式:
val mode=if(args.isNotEmpty() && args[0] ==1){
0
}else{
1
}

异常捕捉
try …catch …finally中的执行完之后,再返回结果,可通过var获取返回值

具名参数:sum(arg1=2,arg0=3) //参数就可以不按照顺序传递了
变长参数:如main方法中的args
fun test(vararg args:String){}
默认参数:给出参数默认值

导出可执行程序

kotlin应用场景:

kotlin-android

JSP知识点小记

发表于 2018-11-26 | 分类于 Java
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
1.	JSP文件中的元素可分为5类:
A 注释 <!-- --> 隐藏注视:不发给客户 <%-- --%> java中的注释
B 模板元素 HTMl元素
C 脚本元素
1. 声明:<%! %>
2.表达式 <%= %>
3.Scriptlets <% %> 是JSP中页面处理请求是执行的Java代码
D 指令元素
1. page指令
2.include指令(静态,编译时包含检查错误了,区别于动作包含)
3.taglib指令 允许使用自定义标签
E动作元素 <jsp: >
2. 表达式语言用${}表示
3. JSP内建对象
所有的内建对象都是由容器管理和实现,在所有的JSP页面中都可以使用该内部对象
1. request javax.servelt.ServletRequset的子类
2. response javax.servelt.ServletResponse的子类
3. pageContext javax.servelt.jsp.PageContext的子类
4. session javax.servlet.http.HtttpSession
5. application javx.servlet.ServletContext
6. out javax.servlet.jsp.JspWriter
7. config javax.servlet.ServletConfig
8. page javax.lang.Object
9. exception java.lang.Throwable
4. JSP内建对象详解
一. Out对象
表示为客户打开的输出流PrintWriter通过他向客户端发送输出六,简单的说,它主要用来向客户端输出数据,代表输出流的对象
区分:out.clear();方法清除缓冲区的数据,并把数据输出到客户端
Out.clearBuffer();方法清除缓冲区的数据,但不把数据输出到客户端
其中的方法有print和println,但是println并没有换行的的作用,因为被浏览器忽略了,用println(“<br>”);
二、 request对象
表示请求对象,通过gerParameter方法可以得到request对象的参数,通过Cookies、Referer等可以得到请求的HTTP头。
来自客户端的请求经Servlet容器处理后,由request对象进行封装。
isUserRole方法判断认证后的用户是否属于逻辑的Role的会员
三、 response对象
response封装了JSP产生的响应,然后被发送到客户端以响应客户的请求,输出流是有缓冲的
四、 session对象
session对西安用来保存每个用户的信息,以便跟踪每个客户的操作状态。其中,session信息保存在容器中,session的ID保存在客户机的Cookie中。
如果客户端禁掉了Cookies,则会自动的转化为URL-rewriting(重写URL,这个URL中包含客户端的信息),session自动为每个流程提供方便的存储信息的方法。
Invalidate方法销毁这个session对象,使得和他绑定的对象都失效
五、 pageContext对象
他为JSP页面包装了页面的上下文,管理对属于JSP中特殊可见部分中已命名对象的访问。创建和初始化是由容器完成的。JSP页面中可以直接使用pageContext对象的句柄
pageContext对象的getXXX()/setXXX()/findXXX()方法可以用来根据不同的对象范围实现对不同范围内的对象的管理
forward()方法重定向
注意: pageContext属性默认在当前的页面是共享的
Session中的属性在当前是session中是共享的
ServletContext对象中的属性对所有页面是共享的
六、 application对象
他为多个应用程序保存信息。对于一个容器而已,每个用户都共同是由一个application对象,他和服务器同生同死
getAttributeNames返回的是一个枚举的实例
可以用来做网站计数器(刷新的时候变了?当服务器关闭时就从0开始计数,解决方法是每当服务器宕机后设置技术的初始值)
七、 config对象
他表示servlet的配置,当一个容器初始化的时候,容器把某些信息通过此对象传递给这个Servlet
getServletContext()返回执行者的Servlet上下文
getInitParameter 和getInitParameterNames返回初始值
八、 page对象
他指的是JSP实现类的实例,即他就是JSP本身,通过这个可以对他进行访问
九、 exception对象
他值得是运行时的异常,也就是被调用的错误页面(isErrorPage==true)的结果,只有在错误页面中才可以使用
5. JSP中使用JavaBean
JavaBean往往封装了程序的页面逻辑,它是可重用的组建
区别:JavaBean和Enterprise JavaBean概念是完全不同的。
EJB为开发服务器端应用程序组件提供了一个模型,利用这个模型来创建可移植与分布式企业应用程序服务器或组件。
JavaBean的属性是Bean组件内部状态的抽象表示,可分为四类:
A.Simple B。Indexed (可以操作数组) C。Bound D。Constrained
6、 动态页面和用户会话
JSP是一种动态页面技术
动态网页的动态主要是以下几个方面获得:
1. 根据时间的动态
2. 根据用户类型的动态
3. 根据用户自定义信息的动态
4. 根据用户来自地区的动态
5. 根据数据库内容的动态
用户会会话跟踪
不同页面间的信息交换:
1. HTTP信息
将信息保存在HTTP头部,以淘汰了
2. 隐藏字段
<input type=”hiddern” name=”” value=””>
3. URL重写
<a href=” ?name=3&……”></a>
缺点:不安全,连接长度 (URL长度一般是2KB)
4.Cookie
5.session
7 Sevlet技术
Servlet先于JEE平台而出现
Servlet是由服务器端调用和执行的、按照Servlet自身规范编写的Java类,可以实现Java编写的所有功能除图形界面以外
作用:可以处理客户端传过来的HTTP请求,并返回一个响应。
Servlet的生命周期:
1. 装载Servlet
2. 创建Servlet对象
3. 调用Servlet的init方法
4. 服务 调用service方法
5. 销毁 调用Servlet的destroy方法
平常编写Servlet一般都直接继承HttpServlet
重点:编写配置文件
8. Servlet常用接口的使用
一、 Servlet实现相关
Public interface Servlet 是所有Servlet必须直接或间接实现的接口,有init,destroy,service等方法
Public abstract class GenericServlet implements Servlet,ServletConfig,java.io.Serializable
其方法service是抽象方法
Public abstract class HttpServlet extends GenericServlet implements java.io.Serializable
他是针对使用HTTP协议的Web服务器的Servlet类,通过执行Servlet接口,能够提供HTTP协议的功能
二、Servlet配置相关
Javax.servlet.ServletConfig接口代表Servlet的配置,包括Servlet的名字,促使参数和上下文。
Public interface ServletConfig 有getInitParameter方法,getServletContext等方法
三、Servlet异常相关
1、public class ServletException extends Exception 方法getRootCase返回异常产生原因
2、public class UnavailableException extends ServletException
当Servelet或Filter不能使用时抛出此异常
四、 请求和相应相关
ServletRequest 、ervletI/O、ServletRequestWrapper(ServletRequest的实现类)、HttpServletReqest等
五、会话跟踪
Public interface HttpSession
此接口被Servlet引擎用来实现HTTP客户端和HTTP会话两者之间的关联。Session用来再无状态的HTTP协议下越过多个请求页面来维持状态和识别用户
一个Session可以通过Coookie或URL来维持
六、Servlet上下文
public interface ServletContext
在服务器上使用Session对象维持与单个客户相关的状态,而当多个用户的Web应用维持一个状态时,则应使用Servlet环境(Context),ServletContext对象代表一组Servlet共享的资源。
七、Servlet协作
public interface RequestDispatcher,包含两个方法:forward和include
八、过滤
通过过滤可以对请求进行统一的编码、对请求进行认证等。每个filter可能只担任很少的任务,多个Filter可以相互协作,通过这种协作,可以完成一个复杂的功能。
public interface Filter 他是Filter必须实现的接口,包含init,doFilter,destroy等方法
public interface FilterChain 是代码的过滤链,通过它可以把过滤的任务在不同的Filter之间转移,包含doFilter方法
public interface FilterConfig 代表Filter的配置
十、 使用HttpServlet处理客户端的请求
Servlet被设计成轻轻驱动的。
当Web容器接受到某个对Servlet的请求时,把他封装成一个HttpServletRequest对象,然后把此对象传给Servlet的对应处理方法,如doGet和doPost等
doGet:可以获取服务器信息,并将其作为响应返回给客户端
doGet:用户把数据传送到服务器端,可以隐藏放松的数据,适合发送大量的数据
9、获得Servlet的初始化参数
通过ServletConfig接口获得Servlet的初始参数
10、Servlet的配置
第八章
15、JSP和Servlet结合的方法
模式一:JSP+JavaBean
所有数据通过Bean处理,JSP实现页面的表现
小型应用中可以考虑
模式二:JSP+Servlet+JavaBean
遵循MVC模式,Servlet作为控制器修改Bean的属性,JSP读取Bean的属性,然后进行显示,即JavaBean作为JSP和Servlet通信的中间工具
大中型项目中使用
实际中,所有JSP都必须编译成Servlet,并且在Servlet的容器中执行。
16、JSP开发中的常用技巧
一、在不同页面之间共享数据(同一用户)
A.ssession B. Cookie C.隐含表单 D.ServletContext E.application F.文件系统或者数据库
二、在不同用户之间共享数据
A.使用ServletContext B、application对象
三、创建错误处理页面
在编译时出现错误,其代码为500.
在JSP中声明出错页面<%@ page errorPage=”error.jsp”%>;在error.jsp中首先要制定该isErrorPage=“true”,只有这样,这个页面才能进行错误处理 ,才能使用exception对象。
一句话:JSP 错误处理的本质是在不同的页面或者类中传递异常,并且在目标页面处理异常
17、自定义标签库的开发

SpringBoot入门

发表于 2018-11-26 | 分类于 Spring

https://www.imooc.com/video/16358
https://www.imooc.com/learn/1058
https://www.imooc.com/video/16783

简介

  • 官网:http://spring.io/,https://spring.io/projects/spring-boot
  • 英文文档:https://docs.spring.io/spring-boot/docs/current/reference/
  • Spring Framework是一种JavaEE的框架;Spring Boot是一种快速构建的Spring应用;Spring Cloud是构建SpringBoot的分布式应用
  • Spring MVC 相当于一辆手动挡汽车,Spring Boot 相当于把汽车变成自动挡,然后还加装了无钥匙进入、自动启停等功能,让你开车更省心。但是车的主体功能不变,你还是要用到 Spring MVC

SpringBoot2.0: 编程语言Java 8+,Kotlin,底层框架:SpringFramework 5.0.X,支持Web Flux

Web Flux

  1. 支持函数编程,Java 8 Lambda
  2. 响应式编程,Reactive Streams
  3. 异步编程,Servlet3.1和Asyc NIO

SpringBoot优势:

  • 组件自动装配:规约大于配置,专注核心业务
  • 外部化部署:一次构建、按需调配,到处运行
  • 嵌入式容器:内置容器、无需部署、独立运行
  • SpringBoot Starter:简化依赖、按需装配、自我包含
  • Production-Ready:一站式运维、生态无缝整合

SpringBoot和Maven

1
2
3
4
5
6
7
8
9
10
 <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/>
</parent>
~~~
* spring-boot-starter-parent 模块中包含了自动配置、日志和YAML,使构建spring项目变得简单
* spring-boot-starter-parent它用来提供相关的Maven默认依赖,使用它之后,常用的包依赖可以省去version标签
* Spring Boot提供的jar包的依赖可参考.m2/repository/org/springframework/boot/spring-boot-dependencies/下pom文件
org.springframework.boot spring-boot-starter-web
1
spring-boot-starter-web 模块,包括了Tomcat和Spring MVC的依赖
org.springframework.boot spring-boot-starter-test test
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
spring-boot-starter-test 测试模块,包括JUnit、Hamcrest、Mockito

* 在spring-boot中,模块的依赖都是以starter的方式进行,以 spring-boot-starter-方式命名,指明了具体的模块
* 使用starter的依赖方式,可以把相应需要依赖的包一起依赖到项目中,而不像传统的Spring 需要各自依赖包
* 更多starter作用,请参考:Spring Boot的启动器Starter详解(https://my.oschina.net/u/3235888/blog/887854)
* SpringBoot启动原理(推荐必读):https://www.cnblogs.com/zheting/p/6707035.html

# 项目构建
方式一:在线构建 http://start.spring.io
方式二:IDEA中IndexController构建spring-boot项目

# SpringBoot的属性配置
## 默认配置
* 如果需要修改starter模块中的默认配置,只需要在application.properties 中添加修改相应的配置
* spring boot启动的时候会读取application.properties默认配置
* 在spring boot中配置除了支持 application.properties,还支持application.yml的配置方式
* 详细SpringBoot配置可参考: https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

## 自定义属性配置

com.student.id=6228
com.student.name=lily
com.student.desc=${name} id is ${random.int}

1
2
3
4
* 定义属性对应类需要添加@Component注解,让spring在启动的时候扫描到该类,并添加到spring容器中
* 在application.properties内可以直接通过${}引用其他属性的值;通过${random}获取随机数
* 如果不使用默认名称的配置文件,如改名为test.properties这份默认配置,则通过在bean添加@Configuration和@PropertySource("classpath:test.properties")来设置
1. 使用spring支持的@Value()加载

@Component
public class Student {
@Value("com.student.id")privateintid;@Value("{com.student.id}") private int id; @Value("com.student.id")privateintid;@Value("{com.student.name}")
private String name;
@Value("${com.student.desc}")
private String desc;
}

1
2. 使用@ConfigurationProperties(prefix="") 设置前缀,属性上不需要添加注解

@Component
@ConfigurationProperties(prefix = “com.student”)
public class Student {
private int id;
private String name;
private String desc;
}

1
使用:

@Autowired
private Student student;

1
2
3
4
5
6
7
8
9
10
11
## 属性配置优先级
application.properties和application.yml文件可以放在一下四个位置:
* 外置,在相对于应用程序运行目录的/congfig子目录里。
* 外置,在应用程序运行的目录里
* 内置,在config包内
* 内置,在Classpath根目录

相同优先级位置同时有application.properties和application.yml,那么application.yml里面的属性就会覆盖application.properties里的属性

## 多环境配置
在application.properties/在application.yml同目录下新建不同环境下的配置文件,格式:application-{profile}.properties,如:

application-dev.properties //开发环境的配置文件
application-test.properties //测试环境的配置文件
application-prod.properties //生产环境的配置文件

1
2
3
4
5
6
在application.properties/在application.yml中设置spring.profiles.active的值为{profile}(dev/test/prod)来启用不同的配置属性

# 静态资源处理
## 默认静态资源映射
Spring Boot对静态资源映射提供了默认路径配置, 其内内容均为静态资源,可直接访问,提供的静态资源映射如下:
![image](/pub-images/静态资源优先级.png)

//优先级由高到低
classpath:/META-INF/resources
classpath:/resources
classpath:/static
classpath:/public

1
2
3
4
5
6
7
可以通过修改spring.mvc.static-path-pattern来修改默认的映射,例如我改成/test/**,那运行的时候访问http://lcoalhost:8080/test/index.html


## 自定义静态资源映射
如访问static下资源,如:http://localhost:8080/static/test.jpg,则可通过如下方式
方式1:在application.properties中添加配置:spring.mvc.static-path-pattern=/static/** 则只能通过/static/来访问静态资源
方式2:代码实现

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//将所有/static/** 访问都映射到classpath:/static/ 目录下
registry.addResourceHandler("/static/**").addResourceLocations(“classpath:/static/”);
}
}

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

# 模板引擎
* Spring Boot 推荐使用Thymeleaf、FreeMarker、Velocity、Groovy、Mustache等模板引擎,不建议使用JSP
* 默认 src/main/resources/templates 目录为以上模板引擎的配置路径
使用流程:
1. pom中对应模版starter引入
2. 编写controller
3. 在templates下编写模版

# 热部署
热部署:监听Class文件的变动,只把发生修改的Class重新加载,而不需要重启应用
1. 使用spring-boot-maven-plugin
* 把项目打包成一个可执行的超级JAR(uber-JAR),包括把应用程序的所有依赖打入JAR文件内,并为JAR添加一个描述文件,其中的内容能让你用java -jar来运行应用程序。
* 搜索public static void main()方法来标记为可运行类
* 详细讲解参考:https://blog.csdn.net/taiyangdao/article/details/75303181
* 官网:https://docs.spring.io/spring-boot/docs/current/reference/html/build-tool-plugins-maven-plugin.html
2. 使用spring-boot-devtools

# ControllerAdvice
可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping中,通常用于拦截异常并统一处理
https://www.cnblogs.com/magicalSam/p/7198420.html

# SpringBoot项目运行模式
1. main方法方式
2. 用命令 mvn spring-boot:run”在命令行启动该应用,可通过IDEA的Maven插件中Plugins-》spring-boot找到
3. Jar/War方式 :运行“mvn package”进行打包时,会打包成一个可以直接运行的 JAR 文件,使用“java -jar”命令就可以直接运行,war包形式,需要有webapp->WEB-INF->web.xml,java -jar [war名称.war]

# 默认日志框架配置
* SLF4J——Simple Logging Facade For Java,它是一个针对于各类Java日志框架的统一Facade抽象
* SLF4J定义了统一的日志抽象接口,而真正的日志实现则是在运行时决定的——它提供了各类日志框架的binding
* Logback是log4j框架的作者开发的新一代日志框架,它效率更高、能够适应诸多的运行环境,同时天然支持SLF4J。
* Spring Boot在所有内部日志中使用Commons Logging,但是默认配置也提供了对常用日志的支持
* 默认情况下,Spring Boot会用Logback来记录日志,并用INFO级别输出到控制台
* spring-boot-starter-logging为logback的starter,一般会包含在其他starter中如spring-boot-starter,不需要显式引入
* 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL
* 可以按如下规则组织配置文件名:Logback:logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy

参考文章:https://www.cnblogs.com/zheting/p/6707041.html

# 自定义 Filter

# JPA数据库操作
http://www.ityouknow.com/springboot/2016/08/20/spring-boo-jpa.html
org.springframework.boot spring-boot-starter-data-jpa mysql mysql-connector-java
1
2
3
4
5
6
7
8
9
* Jpa 是利用 Hibernate 生成各种自动化的 sql,如果只是简单的增删改查,基本上不用手写了,Spring 内部已经帮大家封装实现了
* Spring Data Jpa 还有很多功能,比如封装好的分页,可以自己定义 SQL,主从分离等等

# mybatis
http://www.ityouknow.com/springboot/2016/11/06/spring-boo-mybatis.html



# Redis
org.springframework.boot spring-boot-starter-data-redis org.apache.commons commons-pool2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# Spring Factories机制
* Java SPI(Service Provider Interface)机制:为某个接口寻找服务实现的机制
1. 当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件,该文件里就是实现该服务接口的具体实现类
2. 当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入
* Spring Boot中的SPI机制:Spring Factories(Spring Boot中一种非常解耦的扩展机制)
1. 在META-INF/spring.factories文件中配置接口的实现类名称
2. 当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。这种自定义的SPI机制是Spring Boot Starter实现的基础。

# 自定义starter
* starter可以理解为一个可拔插式的插件
* starter的artifactId的命名规则
1. 官方Starter通常命名为spring-boot-starter-{name}如 spring-boot-starter-web
2. 非官方Starter命名应遵循{name}-spring-boot-starter的格式, 如mybatis-spring-boot-starter

Starter的工作原理:
1. Spring Boot在启动时扫描项目所依赖的JAR包,寻找包含spring.factories文件的JAR包,
2. 读取spring.factories文件获取配置的自动配置类AutoConfiguration,
3. 将自动配置类下满足条件(@ConditionalOnXxx)的@Bean放入到Spring容器中(Spring Context)
4. 这样使用者就可以直接用来注入,因为该类已经在容器中了

自定义starter步骤:
1. maven引入:

dependency>
org.springframework.boot
spring-boot-autoconfigure


org.springframework.boot
spring-boot-configuration-processor
true

1
2
3
* spring-boot-configuration-processor:spring默认使用yml中的配置,但有时候要用传统的xml或properties配置,则需要依赖他,这样就可以在你的配置类开头加上@PropertySource("classpath:your.properties"),其余用法与加载yml的配置一样
* spring-boot-autoconfigure: http://ifeve.com/spring-boot-autoconfigure/
2. 定义自己的Properties类,如PersonProperties.java:

@ConfigurationProperties(prefix = “spring.person”)
@Data
public class PersonProperties {
private String name;
private int age;
}

1
3. 核心服务类,如PersonService.java:

public class PersonService {
private PersonProperties properties;
public PersonService() {}
public PersonService(PersonProperties properties) {
this.properties = properties;
}
public void sayHello(){
System.out.println("大家好,我叫: " + properties.getName() + “, 今年” + properties.getAge() + “岁”);
}
}

1
4. 自动配置类:一般每个starter都至少会有一个自动配置类,一般命名规则使用XxxAutoConfiguration,如:PersonServiceAutoConfiguration

@Configuration
@EnableConfigurationProperties(PersonProperties.class)
@ConditionalOnClass(PersonService.class)
@ConditionalOnProperty(prefix = “spring.person”, value = “enabled”, matchIfMissing = true)
public class PersonServiceAutoConfiguration {
@Autowired
private PersonProperties properties;

@Bean
@ConditionalOnMissingBean(PersonService.class)  // 当容器中没有指定Bean的情况下,自动配置PersonService类
public PersonService personService(){
    PersonService personService = new PersonService(properties);
    return personService;
}

}

1
所用注解说明:

@ConditionalOnClass:当类路径classpath下有指定的类的情况下进行自动配置
@ConditionalOnMissingBean:当容器(Spring Context)中没有指定Bean的情况下进行自动配置
@ConditionalOnProperty(prefix = “example.service”, value = “enabled”, matchIfMissing = true),当配置文件中example.service.enabled=true时进行自动配置,如果没有设置此值就默认使用matchIfMissing对应的值
@ConditionalOnMissingBean,当Spring Context中不存在该Bean时。
@ConditionalOnBean:当容器(Spring Context)中有指定的Bean的条件下
@ConditionalOnMissingClass:当类路径下没有指定的类的条件下

@ConditionalOnExpression:基于SpEL表达式作为判断条件

@ConditionalOnJava:基于JVM版本作为判断条件
@ConditionalOnJndi:在JNDI存在的条件下查找指定的位置
@ConditionalOnNotWebApplication:当前项目不是Web项目的条件下
@ConditionalOnWebApplication:当前项目是Web项目的条件下
@ConditionalOnResource:类路径下是否有指定的资源
@ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者在有多个Bean的情况下,用来指定首选的Bean

@ConfigurationProperties: 主要用来把properties配置文件转化为对应的XxxProperties来使用的,并不会把该类放入到IOC容器中,想放入容器可通过@Component来标注或@EnableConfigurationProperties(XxxProperties.class)
@EnableConfigurationProperties(XxxProperties.class) 注解的作用是@ConfigurationProperties注解生效

1
2
5. src/main/resources/META-INF/spring.factories
注意:META-INF是自己手动创建的目录,spring.factories也是手动创建的文件,在该文件中配置自己的自动配置类

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.my.PersonServiceAutoConfiguration

1
2
3
4
6. 打包mvn clean install,生成starter的jar包
7. 使用starter
* 创建新项目,引入starter
* 配置application.properties,如:

spring.person.name=jack
spring.person.age=28

1
* 调用

@Autowired
private PersonService personService;

@Test
public void testHelloWorld() {
personService.sayHello();
}


# 其他SpringBoot学习资料
* http://www.ityouknow.com/springboot/2015/12/30/springboot-collect.html


拦截器功能:
重写WebMvcConfigurerAdapter中的addInterceptors方法把自定义的拦截器类添加进来即可简单的判断是否登录的使用

注解:
@SpringBootApplication是Sprnig Boot项目的核心注解,主要目的是开启自动配置
@RestController 这个注解相当于同时添加@Controller和@ResponseBody注解,用这个注解的类里面的方法都以json格式输出
@Component:让spring在启动的时候扫描到该类,并添加到spring容器中
@Bean:任何一个标注了@Bean的方法,其返回值将作为一个bean定义注册到Spring的IoC容器,方法名将默认成该bean定义的id
@ControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping中

@Configuration:任何一个标注了@Configuration的Java类定义都是一个JavaConfig配置类
@ComponentScan:
* 自动扫描并加载符合条件的组件(比如@Component和@Repository等)或者bean定义,最终将这些bean定义加载到IoC容器中
* 可以通过basePackages等属性来细粒度的定制@ComponentScan自动扫描的范围,如果不指定,则默认Spring框架实现会从声明@ComponentScan所在类的package进行扫描
* 所以SpringBoot的启动类最好是放在root package下,因为默认不指定basePackages
@EnableAutoConfiguration:借助@Import的支持,收集和注册特定场景相关的bean定义
@EnableScheduling是通过@Import将Spring调度框架相关的bean定义都加载到IoC容器

NuGet

发表于 2018-11-02 | 分类于 C#

https://www.cnblogs.com/nizhenghua/p/6422078.html

NW.js入门

发表于 2018-10-26 | 分类于 前端

[toc]

简介

NW.js (原名 node-webkit)是一个基于 Chromium 和 node.js 的应用运行时,通过它可以用 HTML 和 JavaScript 编写原生应用程序。它还允许您从 DOM 调用 Node.js 的模块 ,实现了一个用所有 Web 技术来写原生应用程序的新的开发模式。

  • 官网:https://nwjs.io/
  • 中文文档:https://www.gitbook.com/book/wizardforcel/nwjs-doc/details

功能特性

  • 用现代 HTML5,CSS3,JS 和 WebGL 来编写应用程序
  • 完全支持 Node.js APIs 和所有其 第三方模块
  • 良好的性能:Node 和 WebKit
  • 运行在相同的线程:函数调用是更简洁;对象在同一堆可以互相引用
  • 容易打包和分发应用程序
  • 支持 Linux、Mac OS X 和 Windows

窗口外观常用属性

在package.json文件中设置

1
2
3
4
5
6
7
8
9
10
11
12
title : 字符串,设置默认 title。
width/height : 主窗口的大小。
toolbar : bool 值。是否显示导航栏。
icon : 窗口的 icon。
position :字符串。窗口打开时的位置,可以设置为“null”、“center”或者“mouse”。
min_width/min_height : 窗口的最小值。
max_width/max_height : 窗口显示的最大值。
resizable : bool 值。是否允许调整窗口大小。
always-on-top : bool 值。窗口置顶。
fullscreen : bool 值。是否全屏显示。
show_in_taskbar : 是否在任务栏显示图标。
frame : bool 值。如果设置为 false,程序将无边框显示。

webstorm项目创建及调试

下载三个不同 OS 平台的 NW.js

创建项目并运行

  1. 创建空项目
  2. 创建package.json,编辑起内容,最简为:
1
2
3
4
5
{
"name": "helloworld",
"version": "0.0.1",
"main": "index.html"
}
  1. 在webstorm 中添加一个nw.js:run – edit configurations – + nw.js
1
2
3
NW.js app : 可以是当前项目目录,但要包含package.json文件. 或者是一个.nw的文件
NW.js interpreter 指定可执行的 nw(官网下的包中的) (mac下是nwjs),如:/MyDeveloper/nwjs-v0.22.1-osx-x64/nwjs.app
working direction : 项目目录
  1. 运行查看效果

调试

https://www.jetbrains.com/help/webstorm/2017.1/run-debug-configuration-node-webkit.html

打包到各个平台

https://github.com/nwjs/nw.js/wiki/how-to-package-and-distribute-your-apps

mac下打包

  1. 拷贝下载的nwjs-sdk-v0.22.1-osx-x64.zip中的nwjs.app文件到项目的根目录的同级目录
  2. 修改nwjs.app目录名称为你想要的名称,如:MyNW.app
  3. 在项目根目录执行如下命令:zip -r …/MyNW.app/Contents/Resources/app.nw *,将当前目录下所有文件打包到MyNW.app中
  4. open MyNW.app可以打开项目
  5. 制作成dmg文件
    • 在应用程序->实用工具下打开磁盘工具
    • 新建一个磁盘映像,放在桌面上(可随意),名称设置为temp.dmg(可随意),存储为mytemp
    • 拷贝4中的文件到mytemp中
    • 执行:ln -s /Applications /Volumes/temp.dmg/Applications
  1. 成功

问题:4中制作的文件太大

代码加密保护

有些情况下,代码还是不能直接暴露给用户的;我们可以使用V8 Snapshot 的方式来达到代码加密保护的目的

具体的方式是:

  1. 使用 /nwjs.exe 来运行 nwjc source.js core.bin命令
  2. 在index.html里使用require(‘nw.gui’).Window.get().evalNWBin(null, ‘./app/v0.0.1/core.bin’);(注意这里的路径,是相对于nw.exe的位置)将代码引入到项目中;
  3. 加密的代码里不要使用 let、const这些关键字,可能因为这个始终编译不通过

自动更新

项目代码需要更新

前面介绍项目接口就提到 /app/v0.0.1/ 就是放置V0.0.1的所有代码的位置;
那么如果要更新到V0.0.2,那我们新建一个文件夹 /app/V0.0.2,然后把V0.0.2的代码都放到这个文件下,然后把/package.json替换成新版本的package.json;这样重启客户端之后,然会读取v0.0.2的代码了。具体的更新代码就不写了,可以把新版本的代码打包成zip包,然后客户端下载好,解压就行。

nw.js本身需要更新

通常情况下,不会遇到需要更新nw.js 本身的情况,因为当选定一个版本的NW.js后,就认定它了,除非遇到了什么无法解决的BUG

系列教程

https://blog.csdn.net/zeping891103/column/info/19257

ECMAScript规范

发表于 2018-10-26 | 分类于 前端

ECMAScript 6(简称ES6)是JavaScript语言的下一代标准,于2015年6月正式发布,也称ECMAScript 2015。

1
2
参考资料
《ECMAScript 6 入门》: http://es6.ruanyifeng.com/

ECMA是标准,js是实现

[toc]

历史

  • 1996 ES1.0 js稳定,Netscapte将js提交给ECMA组织,ES正式出现
  • 1998 ES2.0 ES2.0正式发布
  • 1999 ES3.0 ES3被浏览器广泛支持
  • 2007 ES4.0 ES4过于激进,被废除了
  • 2008 ES3.1 4.0退化为严重缩水版3.1,代号Harmony(和谐)
  • 2009 ES5.0 ES5正式发布了,公布了JS.next,即后来的ES6.0
  • 2011 ES5.1 ES5.1成为了ISO国际标准
  • 2013.3 ES6.0 制定草案
  • 2013.12 ES6.0 ES6.0草案发布
  • 2015.6 ES6.0 ES6.0预计发布正式版,同时JS.next指向ES7.0

兼容性

目前ES5、ES6支持还可以,凑合;ES5、ES6逐渐沦为后台语言

在浏览器中使用需要用到编译工具,babel/traceur(由google出的编译器,把ES6语法编译成ES5)

使用的三种方式

  1. 网页内直接使用
1
2
3
4
5
<script src="traceur.js"></script>
<script src="bootstrap.js"></script>
<script type="module">
//此出写ES6代码
</script>
  1. 直接在线编译(主要用于测试)
  • http://babeljs.io/repl/
  • https://google.github.io/traceur-compiler/demo/repl.html
  1. 直接在node中使用
  • 直接用,需添加‘use strict’
1
2
3
4
//test.js
'use strict'
let a=2;
console.log(a);

node test.js

  • node --harmony_desctructuring test.js

新增功能

定义变量 let

  • let定义的变量只能在代码块中使用,具备块级作用域;var具备函数级作用域;
  • 块级作用域其实就是匿名函数立即调用
  • 变量不能重复定义
  • 可用于封闭空间;封闭空间可解决i问题
    以前:
    (function(i){
    var a=12;
    })(i);
    现在:
    {
    let a=12;
    }

定义常量 const

定义后则不能修改

字符串连接

==反单引号==:==``==,内容模版,==${变量名}填充模版==

解构赋值

  • var [a,b,c]=[12,5,101];解析结构,给a、b、c都赋值;
  • json格式(通过名称匹配,与顺序无关)也支持
  • ==模式匹配==:var [a,[b,c],d] =[12,[3,2],101],左侧的样子需要和右侧一样
  • 可==以给默认值==。var {time=12,date} ={data=123}

复制数组

数组赋值为引用赋值,复制以前用for循环🔥 Array.from()函数,现在使用==超引用’…’==, var arr2 = […arr1]; 在函数中通过 …args 接收多个参数

循环

以前是for或for in,现在:for of,支持数组、json、map

1
2
3
4
//i表示数组或者json的值,for in中i是下标,for of中表示key+value,实质是jsonObj.entrys(),类似的还有jsonObj.keys()、jsonObj.values()
for(var i of arr){
console.log(i);
}

map操作

get()\set()\delete()

箭头函数 =>

注意事项

  • this问题 //this指向了window对象
  • arguments不能使用,箭头函数没有自己的 arguments
1
2
3
4
5
6
function foo() { 
var f = (...args) => args[0];
return f(2);
}

foo(1); // 2

更多:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions

对象语法简洁化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//以前
var person={
name:'abc',
age:100,
showName:function(){
alert(this.name); //this有问题
}
}

//ES6
var name='abc';
var age =100;
var person={
name,
age,
showName(){
alert(this.name);
}
}

面向对象

1
2
3
4
5
6
7
8
9
10
//以前面向对象
function Person(name,age){ //类和构造函数一体
this.name = name;
this.age = age;
}
Person.prototype.showName=function(){
return this.name;
}
var p1 = new Person('abc',100);
alert(p1.name);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//ES6面向对象
class Person{
constructor(name='defalut',age=0){ //此处可以设置默认值,这是函数的功能,即:函数参数可以给默认值
this.name = name;
this.age = age;
}
showName(){
return this.name;
}
}

var p1 = new Person('abc',100);
alert(p1.name);
alert(p1.showName());

继承

1
2
3
4
5
6
7
8
9
10
11
12
//以前  子类.prototype = new 父类();
function Worker(name,age){
Person.apply(this,arguments);
}
Worker.prototype=new Person();

//ES6
class Woker extends Person{
constructor(){
super(); //调用父级构造
}
}

ES5: this.bind();

模块化

当前使用模块化必须引入traceur和bootstrap,type必须写成module

1
2
3
4
5
6
//定义
export default {a,b}
//引用
import modA from './a.js';
//使用
var sum = modA.a + modA.b

Promise

本身为一个对象,用来传递异步操作的数据

整体是链式操作

1
2
pending(等待、处理中)  ---> Resolve(完成)   
---> Reject (拒绝)

使用

1
2
3
4
5
6
var p1 = new Promise(function(resolve,reject){
if(异步处理成功了)
resolve(成功数据)
else
reject(失败原因)
});

包含方法如下:

1
2
3
4
5
6
7
所有方法都支持链式编程
* then(成功(resolve数据),失败(reject数据)) //此方法可以防止异步编程括号深度太多的的问题
* catch(function(e){}); // 用来捕获错误
* all[p1,p2,p3....] //用于将多个promise对象组合/包装成一个全新的promise对象,数组中的Promise又一个错误则按错误流程走,所有都成功则按成功流程走
* Promise.race([p1,p2....]).then(function(value){}); //返回最先执行的Promise的结果
* Promise.reject() //生成错误的Promise
* Promise.resolve() //生成成功的Promise

Generator+yield

Generator:生成器,是一个函数,可以遍历

  • Generator函数名字前有*
  • Generator函数内部使用yield语句
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
//普通函数
function show(){

}
//generator函数
function* show(){
yield “Hello”;
yield "World";
}
//generator函数
*show(){
yield “Hello”;
yield "World";
}

var res=show();
console.log(res.next()); //{value:"Hello",done:false}
console.log(res.next()); //{value:"World",done:false}
console.log(res.next()); //{value:"undefined",done:true}
~~~
* Generator函数调用后的对象有next方法
* next方法每次返回一个value和done结果,value位yield后面的值,done代表是否遍历结束
* yield语句本身没有返回值或每次返回undefined
* next可以带参数,所带参数给了上一个yield
* for ...of循环支持Generator函数

for (let v of show()){
document.write(v);
}

1
2
3
4

#### 展开运算符
扩展语法允许一个表达式在期望多个参数(用于函数调用)或多个元素(用于数组文本)或多个变量(用于解构赋值)的位置扩展
1. 用于函数调用

myFunction(…iterableObj);

1
2. 用于数组字面量

[…iterableObj, 4, 5, 6]


ECMA-262文档下载:https://chetaofeng.github.io/pub-images/Ecma-262.pdf

Ant Design of React+dva入门

发表于 2018-10-26 | 分类于 前端

[toc]

简介

是 Ant Design 的 React 实现,开发和服务于企业级后台产品

安装使用Antd

  1. npm install antd --save
  2. 浏览器引入
  • 在浏览器中使用 script 和 link 标签直接引入文件,并使用全局变量 antd
  • 在 npm 发布包内的 antd/dist 目录下提供了 antd.js antd.css 以及 antd.min.js antd.min.css
  • 也可以通过 CDNJS https://cdnjs.com/libraries/antd 或 UNPKG https://unpkg.com/antd@3.0.2/dist/ 进行下载
  • 强烈不推荐使用已构建文件,这样无法按需加载,而且难以获得底层依赖模块的 bug 快速修复支持

安装使用dva

dva 是一个基于 React 和 Redux 的轻量应用框架,概念来自 elm,支持 side effects、热替换、动态加载、react-native、SSR 等,已在生产环境广泛应用。

1
2
3
4
5
npm install dva-cli -g
dva -v
dva new dva-quickstart
cd dva-quickstart
npm start

在浏览器里打开 http://localhost:8000 ,你会看到 dva 的欢迎界面

dva项目中使用Antd

  1. npm install antd babel-plugin-import --save
  2. 编辑 .roadhogrc,使 babel-plugin-import 插件生效

按需加载Antd

使用 babel-plugin-import

1
2
3
4
5
6
// .babelrc or babel-loader option
{
"plugins": [
["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }] // `style: true` 会加载 less 文件
]
}

然后只需从 antd 引入模块即可,无需单独引入样式。等同于下面手动引入的方式。

// babel-plugin-import 会帮助你加载 JS 和 CSS
import { DatePicker } from ‘antd’;

在 create-react-app 中使用

create-react-app 是业界最优秀的 React 应用开发工具之一

使用create-react-app只是创建出了react应用的基本架构,类似于dva-cli创建的架构,antd还是需要自己添加

dva的出现背景

https://github.com/sorrycc/blog/issues/1

1…8910…50
行锋

行锋

496 日志
15 分类
74 标签
GitHub E-Mail
自古写字楼如青楼,不许楼里见白头
© 2015 — 2019 行锋
博客全站共229.9k字