JSON Web token简称JWT, 是用于对应用程序上的用户进行身份验证的标记。也就是说, 使用 JWTS 的应用程序不再需要保存有关其用户的 cookie 或其他session数据。此特性便于可伸缩性, 同时保证应用程序的安全。
随着技术的发展,分布式web应用的普及,通过session管理用户登录状态成本越来越高,因此慢慢发展成为token的方式做登录身份校验,然后通过token去取redis中的缓存的用户信息,随着之后jwt的出现,校验方式更加简单便捷化,无需通过redis缓存,而是直接根据token取出保存的用户信息,以及对token可用性校验,单点登录更为简单。
详见使用JWT实现Token认证
Flyway 是一款开源的数据库版本管理工具,它更倾向于规约优于配置的方式。Flyway 可以独立于应用实现管理并跟踪数据库变更,支持数据库版本自动升级,并且有一套默认的规约,不需要复杂的配置,Migrations 可以写成 SQL 脚本,也可以写在 Java 代码中,不仅支持 Command Line 和 Java API,还支持 Build 构建工具和 Spring Boot 等,同时在分布式环境下能够安全可靠地升级数据库,同时也支持失败恢复等。
当 Flyway 连接数据库中的 schema 后,会先检查是否已存在 flyway_schema_history 表,如果没有则创建。该表用于跟踪数据库的状态,如数据迁移的版本,迁移成功状态等信息。当 flyway_schema_history 存在后,Flyway 会扫描文件系统或应用中的 classpath 目录的数据迁移文件,然后根据它们的版本号进行按序迁移。
Flyway在执行脚本时,如果文件的版本号小于或等于标记为当前版本的版本号,则忽略它们不执行。
所以需要注意下:
编写脚本的时候不要去修改原有的脚本内容;
注意如果在server上执行flyway,确保本地的脚本代码运行成功,之后再通过版本管理工具传递到server上。
SpringBoot返回给页面的json数据中,如果有数据为null,则返回空字符串。
SpringBoot默认使用Jackson解析返回json数据。
@Configuration
public class JacksonConfig {
@Bean
@Primary
@ConditionalOnMissingBean(ObjectMapper.class)
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
// 通过该方法对mapper对象进行设置,所有序列化的对象都将按改规则进行系列化
// Include.Include.ALWAYS 默认
// Include.NON_DEFAULT 属性为默认值不序列化
// Include.NON_EMPTY 属性为 空("") 或者为 NULL 都不序列化,则返回的json是没有这个字段的。这样对移动端会更省流量
// Include.NON_NULL 属性为NULL 不序列化,就是为null的字段不参加序列化
//objectMapper.setSerializationInclusion(Include.NON_EMPTY);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
objectMapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_NULL);
// 字段保留,将null值转为""
objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer
HandlerMethodArgumentResolver组件的作用主要是用来做参数解析及校验的,我们可以通过写一个类实现HandlerMethodArgumentResolver接口来实现对Controller层中方法参数的修改,包含2个方法:
/** 是否是支持的类型 **/
boolean supportsParameter(MethodParameter parameter);
/** 具体解析参数方法 **/
Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception;
下面是自定义的一个实现:
public class ListArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
//仅作用于添加了注解ListAttribute的参数
// return parameter.getParameterAnnotation(ListAttribute.class) != null;
return parameter.hasParameterAnnotation(ListAttribute.class);
}
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
List personList = new ArrayList();
String[] names = nativeWebRequest.getParameterValues("name");
String[] ages = nativeWebRequest.getParameterValues("age");
for (int i = 0; i < names.length; i++) {
Person person = new Person();
BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(person);
String name = names[i];
String age = ages[i];
beanWrapper.setPropertyValue("name", name);
beanWrapper.setPropertyValue("age", age);
personList.add(person);
}
return personList;
}
}
@Configuration
public class MyConfig extends WebMvcConfigurerAdapter {
@Override
public void addArgumentResolvers(List argumentResolvers) {
// super.addArgumentResolvers(argumentResolvers);
argumentResolvers.add(new ListArgumentResolver ());
}
}
@Controller
public class ListArgumentController {
@ResponseBody
@RequestMapping("/list")
public String argumentResolver(@ListAttribute List list) {
...
}
}
HttpMessageConverter 的作用也可以用来解析参数,主要用于请求体的解析,列如对Json类型的请求解析,将请求体中的Json字符串转化为目标类型
alter table tableName move; /** 收缩水位线,影响索引*/
alter index indexName rebuild; /** 索引重建 */
create index 索引名 on table_name (A1,B1) online;
加上online关键字,减少锁表时间。
实际上AMD 是 RequireJS 在推广过程中对模块定义的规范化的产出
主要解决两个问题:
AMD (Asynchronous Module Definition,异步模块定义) 指定一种机制,在该机制下模块和依赖可以异步加载.这对浏览器端的异步加载尤其适用.
根据AMD规范,我们可以使用define定义模块,使用require调用模块
RequireJS的基本思想是,通过define方法,将代码定义为模块;通过require方法,实现代码的模块加载。
首先,将require.js嵌入网页,然后就能在网页中进行模块化编程了。
上面代码的data-main属性不可省略,用于指定主代码所在的脚本文件,在上例中为scripts子目录下的main.js文件。用户自定义的代码就放在这个main.js文件中。