1 F:programmeJavajdk1.8.0_201in>keytool.exe -genkeypair -alias boot -keyalg RSA -keystore e:/boot/boot.key
pwd :boot11 库密码和boot对应的密码
2
F:programmeJavajdk1.8.0_201in>keytool -importkeystore -srckeystore e:/boot/boot.key -destkeystore e:/boot/boot.key -deststoretype pkcs12
3 springboot 的https的使用:
4 iconfont.cn 阿里矢量图集
用第二部转码后的无法使用,只能用第一次生成的旧的,
在4 启动类配置 链接的跳转方法
springboot2的写法和 1不一样,下面是正确的
// springboot2 写法 @Bean public TomcatServletWebServerFactory servletContainer() { TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() { @Override protected void postProcessContext(Context context) { SecurityConstraint constraint = new SecurityConstraint(); constraint.setUserConstraint("CONFIDENTIAL"); SecurityCollection collection = new SecurityCollection(); collection.addPattern("/*"); constraint.addCollection(collection); context.addConstraint(constraint); } }; tomcat.addAdditionalTomcatConnectors(httpConnector()); return tomcat; } @Bean public Connector httpConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setScheme("http"); //Connector监听的http的端口号 connector.setPort(8080); connector.setSecure(false); //监听到http的端口号后转向到的https的端口号 connector.setRedirectPort(8443); return connector; }
3 Minor GC 和 Full GC有什么区别?
Minor GC:新生代 GC,指发生在新生代的垃圾收集动作,因为 Java 对象大多死亡频繁,所以 Minor GC 非常频繁,一般回收速度较快。
Full GC:老年代 GC,也叫 Major GC,速度一般比 Minor GC 慢 10 倍以上。
4 Java 内存
为什么要将堆内存分区?
对于一个大型的系统,当创建的对象及方法变量比较多时,即堆内存中的对象比较多,如果逐一分析对象是否该回收,效率很低。分区是为了进行模块化管理,管理不同的对象及变量,以提高 JVM 的执
行效率。
分代收集算法
内存分配有哪些原则?
对象优先分配在 Eden
大对象直接进入老年代
长期存活的对象将进入老年代
动态对象年龄判定
空间分配担保
Young Generation Space (采用复制算法)
主要用来存储新创建的对象,内存较小,垃圾回收频繁。这个区又分为三个区域:一个 Eden Space 和两个 Survivor Space。
当对象在堆创建时,将进入年轻代的Eden Space。
垃圾回收器进行垃圾回收时,扫描Eden Space和A Suvivor Space,如果对象仍然存活,则复制到B Suvivor Space,如果B Suvivor Space已经满,则复制 Old Gen
扫描A Suvivor Space时,如果对象已经经过了几次的扫描仍然存活,JVM认为其为一个Old对象,则将其移到Old Gen。
扫描完毕后,JVM将Eden Space和A Suvivor Space清空,然后交换A和B的角色(即下次垃圾回收时会扫描Eden Space和B Suvivor Space。
Tenure Generation Space(采用标记-整理算法)
主要用来存储长时间被引用的对象。它里面存放的是经过几次在 Young Generation Space 进行扫描判断过仍存活的对象,内存较大,垃圾回收频率较小。
Permanent Space
存储不变的类定义、字节码和常量等。
5 一个类展示内存结构模型
package com.example.springbootdemo; //对象分配原则 //对象优先分配在 Eden //大对象直接进入老年代 //长期存活的对象将进入老年代 public class JVMModule { public static void main(String[] args) { } } class Memory{ //永久区 PemanentSpace pemanentSpace; //堆内存区 HeapSpace heapSpace; } class PemanentSpace{ //字节码 Object bytecode; //constants常量 Object constants; // Object classDefine; } //堆内存 class HeapSpace{ //新生代, YoungGenerateSpace youngGenerateSpace; //旧生代,也叫old 老年代 TenureGenerateSpace tenureGenerateSpace; } class YoungGenerateSpace{ //eden 伊甸园 Object edenSpace; //幸存者0 Object suvivor0space; //幸存者1 Object suvivor1space; } //新生代 class TenureGenerateSpace{ }
6 jvm参数调优
根据web (可以中断)gui 不可中断 ,
根据 内存和cpu个数
来调整
7 内存参数调优的例子
-XX:+PrintCommandLineFlags 或者jmx 查询 $ java -XX:InitialHeapSize=128m -XX:MaxHeapSize=2g MyApp 缩写是 Xms Xmx 下面是内存溢出时 保持内存快照,并保存路径,因为很大,所以需要指定位置, 第三个参数内存溢出时直线shell脚本 cleanup,例如可以发送邮件 java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof -XX:OnOutOfMemoryError ="sh ~/cleanup.sh" MyApp
8 -XX:+PrintCommandLineFlags 或者jmx 查询
$ java -XX:InitialHeapSize=128m -XX:MaxHeapSize=2g MyApp 缩写是 Xms Xmx
下面是内存溢出时 保持内存快照,并保存路径,因为很大,所以需要指定位置, 第三个参数内存溢出时直线shell脚本 cleanup,例如可以发送邮件
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof -XX:OnOutOfMemoryError ="sh ~/cleanup.sh" MyApp'''
设置永久区会独立于 上面 的 maxheap size ,另外再占内存
java -XX:PermSize=128m -XX:MaxPermSize=256m MyApp
初始缓存,如果发生问题,字节码会不编译,速度降低了数量级,
-XX:InitialCodeCacheSize and -XX:ReservedCodeCacheSize
代码缓存被填满时让JVM放弃一些编译代码。通过使用-XX:+UseCodeCacheFlushing 这个参数
9 阿里和网易开源镜像站
你可以使用阿里或者网易的镜像服务器上面的。阿里:https://opsx.alibaba.com/mirror,网易:http://mirrors.163.com/
10 测试用抓包工具 fiddler
1 swagger
2 @data lombok的用法
1
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.4</version> <scope>provided</scope> </dependency>
2 plugin ,browser response , search lombok, (新版本只有marketplace),install
3 解决编译问题
build,compile, annonation process,default enable
4 直接开始使用
3 bean验证 完整
4 mongodb
5 分页 pagehelper-spring-boot-starter
6 shiro
7 jpush
8 quartz distribute
9 miaodi demo
10 email spring boot
11 springboot 配置 lockback 日志
12 aop 打印日志方法
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
@Aspect
@Component
@Slf4j
public class LogAspectServiceApi {
@Pointcut("execution(public * com.xxxxxx.controller.*.*(..))")
private void controllerAspect() {
}
@Before(value = "controllerAspect()")
public void methodBefore(JoinPoint joinPoint) {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
log.info("===============请求内容===============");
try {
log.info("请求地址:" + request.getRequestURL().toString());
log.info("请求方式:" + request.getMethod());
log.info("请求类方法:" + joinPoint.getSignature());
log.info("请求类方法参数:" + Arrays.toString(joinPoint.getArgs()));
} catch (Exception e) {
log.error("ERROR:", e);
}
log.info("===============请求内容===============");
}
@AfterReturning(returning = "o", pointcut = "controllerAspect()")
public void methodAfterReturing(Object o) {
log.info("--------------返回内容----------------");
try {
log.info("Response内容:" + JSONObject.toJSONString(o));
} catch (Exception e) {
log.error("### ERROR:", e);
}
log.info("--------------返回内容----------------");
}
}
13 配置忽略ssl https证书的 resttemplate
import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContexts; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; import javax.net.ssl.SSLContext; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; @Configuration public class SSLNoUseRestConfig { /** * 配置忽略 SSL证书的 resttemplate */ @Bean public RestTemplate restTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException { RestTemplate restTemplate = new RestTemplate(getFactory()); return restTemplate; } private HttpComponentsClientHttpRequestFactory getFactory() { HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); try { TrustStrategy acceptingTrustStrategy = (x509Certificates, authType) -> true; SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build(); SSLConnectionSocketFactory connectionSocketFactory = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier()); HttpClientBuilder httpClientBuilder = HttpClients.custom(); httpClientBuilder.setSSLSocketFactory(connectionSocketFactory); CloseableHttpClient httpClient = httpClientBuilder.build(); factory.setHttpClient(httpClient); } catch (Exception e) { e.printStackTrace(); } return factory; } }
14 mongodb
save对象时移除 _class属性的配置
/** * 移除 mongo _class 属性字段 */ @Configuration public class MongoDBConfig { @Autowired MongoDbFactory mongoDbFactory; @Autowired MongoMappingContext mongoMappingContext; @Bean public MappingMongoConverter mappingMongoConverter() { DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory); MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mongoMappingContext); converter.setTypeMapper(new DefaultMongoTypeMapper(null)); return converter; } }
15 开启swagger
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.xxxxxxxx.controller")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("my manager") .description("mydesc") .termsOfServiceUrl("http://www.ityouknow.com/") //servide network .version("1.0") .contact(new Contact("mycompany", "url", "imydata")) .build(); } }
15 极光推送
import cn.jiguang.common.ClientConfig; import cn.jiguang.common.resp.APIConnectionException; import cn.jiguang.common.resp.APIRequestException; import cn.jpush.api.JPushClient; import cn.jpush.api.push.PushResult; import cn.jpush.api.push.model.Options; import cn.jpush.api.push.model.Platform; import cn.jpush.api.push.model.PushPayload; import cn.jpush.api.push.model.audience.Audience; import cn.jpush.api.push.model.notification.AndroidNotification; import cn.jpush.api.push.model.notification.IosNotification; import cn.jpush.api.push.model.notification.Notification; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class JigPushUtil { private static final Logger log = LoggerFactory.getLogger(JigPushUtil.class); private static String masterSecret = "abc"; private static String appKey = "def"; public static void jiguangPush(String alias, String message){ try { PushResult result = push(String.valueOf(alias),message); log.info("result?"成功":"失败")); } catch (Exception e) { log.error("发生错误:"+e.toString()); } } private static PushPayload buildPushObject_android_ios_alias_alert(String alias,String message){ return PushPayload.newBuilder() .setPlatform(Platform.all()) .setAudience(Audience.alias(alias)) .setNotification(Notification.newBuilder() .addPlatformNotification(AndroidNotification.newBuilder() .addExtra("type", "infomation") .setAlert(message) .build()) .addPlatformNotification(IosNotification.newBuilder() .addExtra("type", "infomation") .setAlert(message) .build()) .build()) .setOptions(Options.newBuilder() .setApnsProduction(true)//true-推送生产环境 false-推送开发环境(测试使用参数) .setTimeToLive(90)//消息在JPush服务器的失效时间 .build()) .build(); } private static PushResult push(String alias,String message){ try { ClientConfig clientConfig = ClientConfig.getInstance(); JPushClient jpushClient = new JPushClient(masterSecret, appKey, null, clientConfig); PushPayload payload = buildPushObject_android_ios_alias_alert(alias,message); PushResult result = jpushClient.sendPush(payload); jpushClient.close(); return result; } catch (APIConnectionException e) { log.error("Connection error. Should retry later. ", e); return null; } catch (APIRequestException e) { log.error("Error response from JPush server. Should review and fix it. ", e); return null; }catch (Exception e) { log.error("Failed to send push to app ",e); return null; } } public static void main(String[] args) { jiguangPush("123","mysesssge"); }
上次 nginx 配置出错因为,
1 tomcat下配置了本地的rabbitmq,放到服务器找不到了
2 重启nginx需要使用 进程不是服务来关闭,当时没有关闭成功
vscode 快捷键大全
20 使用winscp 默认用 秘钥登录 配置 ppk的方法
默认使用putty登录
winscp 怎么用私钥文件登录的,以.ppk结尾的密钥文件
Winscp默认用帐号密码登录,用私钥文件登录需要在高级选项里面的SSH--验证里面选择文件。
Winscp使用的是putty作为SSH登录工具,而puttygen所生成的是以.ppk结尾的密钥文件。
如果是pub类型的需要转换为putty类型的,文件类型里选择所有文件,选择密钥文件会提示你是否转换,按提示操作转换保存后就会自动选择转换后的.ppk密钥文件了。
jdk8的新特性之时间
import java.time.ZonedDateTime; import java.time.ZoneId; public class Java8Tester { public static void main(String args[]){ Java8Tester java8tester = new Java8Tester(); java8tester.testZonedDateTime(); } public void testZonedDateTime(){ // 获取当前时间日期 ZonedDateTime date1 = ZonedDateTime.parse("2015-12-03T10:15:30+05:30[Asia/Shanghai]"); System.out.println("date1: " + date1); ZoneId id = ZoneId.of("Europe/Paris"); System.out.println("ZoneId: " + id); ZoneId currentZone = ZoneId.systemDefault(); System.out.println("当期时区: " + currentZone); }
jdk8 技术总结
1 使用 google工具类实现一行添加数据新建list
com.google.common.collect.Lists
2 list 的 foreach的两种方式
::双冒号和 拉姆达表达式
3 求和 ,过滤,跳过等操作
import com.google.common.collect.Lists; import org.junit.Test; import java.lang.annotation.*; import java.nio.charset.StandardCharsets; import java.time.*; import java.util.*; import java.util.concurrent.ThreadLocalRandom; import java.util.function.Supplier; /** * * @ClassName:JDK8_features * @Description:JDK8新特性 * @author diandian.zhang * @date 2017年4月17日上午9:13:24 */ public class JDK8_features { public List<Integer> list = Lists.newArrayList(1,2,3,4,5,6,7,8,9,10); /** * 1.Lambda表达式 */ @Test public void testLambda(){ list.forEach(System.out::println); list.forEach(e -> System.out.println("方式二:"+e)); } /** * 2.Stream函数式操作流元素集合 */ @Test public void testStream(){ List<Integer> nums = Lists.newArrayList(1,1,null,2,3,4,null,5,6,7,8,9,10); System.out.println("求和:"+nums .stream()//转成Stream .filter(team -> team!=null)//过滤 .distinct()//去重 .mapToInt(num->num*2)//map操作 .skip(2)//跳过前2个元素 .limit(4)//限制取前4个元素 .peek(System.out::println)//流式处理对象函数 .sum());// } /** * 3.接口新增:默认方法与静态方法 * default 接口默认实现方法是为了让集合类默认实现这些函数式处理,而不用修改现有代码 * (List继承于Iterable<T>,接口默认方法不必须实现default forEach方法) */ @Test public void testDefaultFunctionInterface(){ //可以直接使用接口名.静态方法来访问接口中的静态方法 JDK8Interface1.staticMethod(); //接口中的默认方法必须通过它的实现类来调用 new JDK8InterfaceImpl1().defaultMethod(); //多实现类,默认方法重名时必须复写 new JDK8InterfaceImpl2().defaultMethod(); } public class JDK8InterfaceImpl1 implements JDK8Interface1 { //实现接口后,因为默认方法不是抽象方法,重写/不重写都成! // @Override // public void defaultMethod(){ // System.out.println("接口中的默认方法"); // } } public class JDK8InterfaceImpl2 implements JDK8Interface1,JDK8Interface2 { //实现接口后,默认方法名相同,必须复写默认方法 @Override public void defaultMethod() { //接口的 JDK8Interface1.super.defaultMethod(); System.out.println("实现类复写重名默认方法!!!!"); } } /** * 4.方法引用,与Lambda表达式联合使用 */ @Test public void testMethodReference(){ //构造器引用。语法是Class::new,或者更一般的Class< T >::new,要求构造器方法是没有参数; final Car car = Car.create( Car::new ); final List< Car > cars = Arrays.asList( car ); //静态方法引用。语法是Class::static_method,要求接受一个Class类型的参数; cars.forEach( Car::collide ); //任意对象的方法引用。它的语法是Class::method。无参,所有元素调用; cars.forEach( Car::repair ); //特定对象的方法引用,它的语法是instance::method。有参,在某个对象上调用方法,将列表元素作为参数传入; final Car police = Car.create( Car::new ); cars.forEach( police::follow ); } public static class Car { public static Car create( final Supplier< Car > supplier ) { return supplier.get(); } public static void collide( final Car car ) { System.out.println( "静态方法引用 " + car.toString() ); } public void repair() { System.out.println( "任意对象的方法引用 " + this.toString() ); } public void follow( final Car car ) { System.out.println( "特定对象的方法引用 " + car.toString() ); } } /** * 5.引入重复注解 * 1.@Repeatable * 2.可以不用以前的“注解容器”写法,直接写2次相同注解即可 * * Java 8在编译器层做了优化,相同注解会以集合的方式保存,因此底层的原理并没有变化。 */ @Test public void RepeatingAnnotations(){ RepeatingAnnotations.main(null); } /** * 6.类型注解 * 新增类型注解:ElementType.TYPE_USE 和ElementType.TYPE_PARAMETER(在Target上) * */ @Test public void ElementType(){ Annotations.main(null); } /** * 7.最新的Date/Time API (JSR 310) */ @Test public void DateTime(){ //1.Clock final Clock clock = Clock.systemUTC(); System.out.println( clock.instant() ); System.out.println( clock.millis() ); //2. ISO-8601格式且无时区信息的日期部分 final LocalDate date = LocalDate.now(); final LocalDate dateFromClock = LocalDate.now( clock ); System.out.println( date ); System.out.println( dateFromClock ); // ISO-8601格式且无时区信息的时间部分 final LocalTime time = LocalTime.now(); final LocalTime timeFromClock = LocalTime.now( clock ); System.out.println( time ); System.out.println( timeFromClock ); // 3.ISO-8601格式无时区信息的日期与时间 final LocalDateTime datetime = LocalDateTime.now(); final LocalDateTime datetimeFromClock = LocalDateTime.now( clock ); System.out.println( datetime ); System.out.println( datetimeFromClock ); // 4.特定时区的日期/时间, final ZonedDateTime zonedDatetime = ZonedDateTime.now(); final ZonedDateTime zonedDatetimeFromClock = ZonedDateTime.now( clock ); final ZonedDateTime zonedDatetimeFromZone = ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) ); System.out.println( zonedDatetime ); System.out.println( zonedDatetimeFromClock ); System.out.println( zonedDatetimeFromZone ); //5.在秒与纳秒级别上的一段时间 final LocalDateTime from = LocalDateTime.of( 2014, Month.APRIL, 16, 0, 0, 0 ); final LocalDateTime to = LocalDateTime.of( 2015, Month.APRIL, 16, 23, 59, 59 ); final Duration duration = Duration.between( from, to ); System.out.println( "Duration in days: " + duration.toDays() ); System.out.println( "Duration in hours: " + duration.toHours() ); } /** * 8.新增base64加解密API */ @Test public void testBase64(){ final String text = "就是要测试加解密!!abjdkhdkuasu!!@@@@"; String encoded = Base64.getEncoder() .encodeToString( text.getBytes( StandardCharsets.UTF_8 ) ); System.out.println("加密后="+ encoded ); final String decoded = new String( Base64.getDecoder().decode( encoded ), StandardCharsets.UTF_8 ); System.out.println( "解密后="+decoded ); } /** * 9.数组并行(parallel)操作 */ @Test public void testParallel(){ long[] arrayOfLong = new long [ 20000 ]; //1.给数组随机赋值 Arrays.parallelSetAll( arrayOfLong, index -> ThreadLocalRandom.current().nextInt( 1000000 ) ); //2.打印出前10个元素 Arrays.stream( arrayOfLong ).limit( 10 ).forEach( i -> System.out.print( i + " " ) ); System.out.println(); //3.数组排序 Arrays.parallelSort( arrayOfLong ); //4.打印排序后的前10个元素 Arrays.stream( arrayOfLong ).limit( 10 ).forEach( i -> System.out.print( i + " " ) ); System.out.println(); } /** * 10.JVM的PermGen空间被移除:取代它的是Metaspace(JEP 122)元空间 */ @Test public void testMetaspace(){ //-XX:MetaspaceSize初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整 //-XX:MaxMetaspaceSize最大空间,默认是没有限制 //-XX:MinMetaspaceFreeRatio在GC之后,最小的Metaspace剩余空间容量的百分比,减少为分配空间所导致的垃圾收集 //-XX:MaxMetaspaceFreeRatio在GC之后,最大的Metaspace剩余空间容量的百分比,减少为释放空间所导致的垃圾收集 } } interface JDK8Interface1 { //1.接口中可以定义静态方法了 public static void staticMethod(){ System.out.println("接口中的静态方法"); } //2.使用default之后就可以定义普通方法的方法体了 public default void defaultMethod(){ System.out.println("接口中的默认方法"); } } interface JDK8Interface2 { //接口中可以定义静态方法了 public static void staticMethod(){ System.out.println("接口中的静态方法"); } //使用default之后就可以定义普通方法的方法体了 public default void defaultMethod(){ System.out.println("接口中的默认方法"); } } /** * * @ClassName:RepeatingAnnotations * @Description:重复注解@Repeatable * @author diandian.zhang * @date 2017年3月31日下午3:48:13 */ class RepeatingAnnotations { @Target( ElementType.TYPE ) @Retention( RetentionPolicy.RUNTIME ) public @interface Filters { Filter[] value(); } @Target( ElementType.TYPE ) @Retention( RetentionPolicy.RUNTIME ) @Repeatable( Filters.class ) public @interface Filter { String value(); String value2(); }; @Filter( value="filter1",value2="111" ) @Filter( value="filter2", value2="222") //@Filters({@Filter( value="filter1",value2="111" ),@Filter( value="filter2", value2="222")}).注意:JDK8之前:1.没有@Repeatable2.采用本行“注解容器”写法 public interface Filterable { } public static void main(String[] args) { //获取注解后遍历打印值 for( Filter filter: Filterable.class.getAnnotationsByType( Filter.class ) ) { System.out.println( filter.value() +filter.value2()); } } } /** * * @ClassName:Annotations * @Description:新增类型注解:ElementType.TYPE_USE 和ElementType.TYPE_PARAMETER(在Target上) * @author diandian.zhang * @date 2017年3月31日下午4:39:57 */ class Annotations { @Retention( RetentionPolicy.RUNTIME ) @Target( { ElementType.TYPE_USE, ElementType.TYPE_PARAMETER } ) public @interface NonEmpty { } public static class Holder< @NonEmpty T > extends @NonEmpty Object { public void method() throws @NonEmpty Exception { } } public static void main(String[] args) { final Holder< String > holder = new @NonEmpty Holder< String >(); @NonEmpty Collection< @NonEmpty String > strings = new ArrayList<>(); } }
1 echart数据才会刷新,需要设置true
this.currchart1=echarts.init(document.getElementById('chart1')).setOption(option,true);
2 获取属性个数
Object.keys(abc).length
3 遍历 对象的方法
abc={a:1,b:2};
{a: 1, b: 2}
for(k in abc){console.log(k)}
VM158:1 a
VM158:1 b
4 使用parseFloat 解决 数字字符串相加问题
parseFloat(d.doorClose_average_vibrationX)+parseFloat(d.doorClose_envelope_vibrationX)]
5 使用mongodb原生的in的例子
BasicDBList values = new BasicDBList();
values.add(30);
values.add(50);
queryCondition.put("a", new BasicDBObject("$in", values));
或用第二种方法
condition.put("loadClass",new BasicDBObject("$in","我是java数组"));
1 jdk自带的 常用命令
jad xxx.class
会生成 反编译的 文件xxxx
2 jmap 进程对 内存的使用情况
jmap -histo:live 2743
jmap 2743
jmap -heap 38574
3 jstat 对资源和性能的监控,包括老生代,新生代等等全部都有
4 jstack 打印线程堆栈快照信息,分析现场等待,思索问题
1.想拷贝别人项目到自己帐号下就fork一下。 2.持续关注别人项目更新就star一下 3.watch是设置接收邮件提醒的。
好的方式
好用的英文字体
Times New Roman
5 spring boot 邮件发送方法
1 依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> 2 邮件配置 spring.mail.host=smtp.gmail.com spring.mail.username=<your email username> spring.mail.password=<your email password> spring.mail.default-encoding=utf-8 #If you use Gmail, the follow two lines are necessary spring.mail.properties.mail.smtp.socketFactory.port = 465 spring.mail.properties.mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory 3 import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class DemoApplicationTests { @Test public void contextLoads() { sendSimpleMail("","title","content"); } @Value("${spring.mail.username}") private String from; @Autowired private JavaMailSender mailSender; public void sendSimpleMail(String to, String subject, String content) { SimpleMailMessage message = new SimpleMailMessage(); message.setTo("xxxxx@qq.com"); message.setSubject(subject); message.setText(content); message.setFrom(from); mailSender.send(message); } }
1 mqtt 打debug调试会导致mqtt链接中断(因为超时?)
踩坑总结
nknown custom element did you register the component correc 因为没有注册组件
少计算了一个data,导致数据为空,
少计算了 flag为ture导致都没数据
最终使用合并的数据列
很重要需要选好时机
this.$nextTick(function(){
this.drawCharts3D(this.chartParams);//画3d图
return;
})
new Date().toJSON()
"2019-08-21T21:46:03.555Z"
cst 和sgt 时区相同
EEE MMM dd HH:mm:ss zzz yyyy
BaseCalendar.Date date = normalize();
TimeZone zi = date.getZone();
if (zi != null) {
sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US)); // zzz
} else {
sb.append("GMT");
}
ZZZ是 +0800
2019-08-22 05:59:45 +0800
zzz 是CST/SGT
只用 三行 就够了 simpledateformat,可以格式化为字符串,也可解析字符串为时间
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss zzz");
System.out.println(format.format(new Date()));
System.out.println("============"+format.parse("2019-04-03 03:22:11 CST"));
2019-08-22 06:16:45 CST
============Wed Apr 03 03:22:11 CST 2019
1 时间出错原因竟然是因为 日期自动转为了java的date到mongo的 timestamp,导致再转出来的时候已经格式不匹配了
无法long转为 date
shiro 拦截器的正常思路:
loginservice新添加
userservice添加 @lazy
handler的拦截器
HandlerInterceptorAdapter 继承 实现preHandler方法
功能有
1 判读如果不是Handler handler不是 HandlerMethod 类型映射的方法直接放过
2 如果是swagger直接放过
3 如果是errorhtml直接抛出异常被捕获后html跳转
4 如果是errorhtml直接放过
5 从header获取等3个地方获取token
从Authorization获取,
从api_key获取(考虑万一是从swagger也用token),两个key都可以
如果header的为空,从token获取,key是token
如果cookie为空从参数获取 key为token
6 判断为空
des解密
判断为空
解析字符串为Token对象
token包含了type是否为web和手机
如果手机不退出就用于在线,判读除了web的都是true
web需要判断时间的有效性,默认12小时有效
7 再次检测token是否为空和保存的user是否为空
8 再次检测传递的user是否为空
9 检测token在redis中存储是否过期,通过判断token_开头的是否存在
redis.get(token_+userid)的方式
10 再次检测传递的token和redistoken是否一致,判断设备
11 查询user是否在db中存在,没有重新登录,有的话状态为2 重新登录
12 没明白 token_expires_的用法
cron的表达式使用
Quartz使用类似于Linux下的Cron表达式定义时间规则,Cron表达式由6或7个由空格分隔的时间字段组成,如表1所示: 表1 Cron表达式时间字段 位置 时间域名 允许值 允许的特殊字符 1 秒 0-59 , - * / 2 分钟 0-59 , - * / 3 小时 0-23 , - * / 4 日期 1-31 , - * ? / L W C 5 月份 1-12 , - * / 6 星期 1-7 , - * ? / L C # 7 年(可选) 空值1970-2099 , - * / Cron表达式的时间字段除允许设置数值外,还可使用一些特殊的字符,提供列表、范围、通配符等功能,细说如下: ●星号(*):可用在所有字段中,表示对应时间域的每一个时刻,例如,*在分钟字段时,表示“每分钟”; ●问号(?):该字符只在日期和星期字段中使用,它通常指定为“无意义的值”,相当于点位符; ●减号(-):表达一个范围,如在小时字段中使用“10-12”,则表示从10到12点,即10,11,12; ●逗号(,):表达一个列表值,如在星期字段中使用“MON,WED,FRI”,则表示星期一,星期三和星期五; ●斜杠(/):x/y表达一个等步长序列,x为起始值,y为增量步长值。如在分钟字段中使用0/15,则表示为0,15,30和45秒,而5/15在分钟字段中表示5,20,35,50,你也可以使用*/y,它等同于0/y;
在恰当的断字点进行换行: p.test {word-break:hyphenate;} break-all 自适应 范围 一般数据库连接 后缀 ?serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull 设置颜色的几种方式 background-color:rgb(255,0,255); border:1px solid rgb(112, 197, 236);
=========================》》》》》》》》》》》》》》》》》》》》》》
1 三大特性: CAS
高并发,高可见,高性能, 悲观锁安全,每次来都必须占用锁, select for update,这样导致低性能
乐观锁,先相信,然后比较 version或者 时间戳,用的多,但是高并发时错误率低,因为修改的多,这个时缺点,瑕不掩瑜
idea 热部署的四个步骤 查看端口对应进程号 netstat -ano |findstr 9091 窗口变化触发事件 addEventListener('resize',function(){alert(1)})
openssl的使用方法:
----------------------------
openssl 用法:
d:openssl>set RANDFILE=d:openssl.rnd
d:openssl>set OPENSSL_CONF=d:opensslOpenSSL-Win64inopenssl.cfg
先要进去 openssl.exe
生成私钥
genrsa -out ca.key 2048
根据私钥生成公钥
rsa -in ca.key -out ca.key.public
根据私钥生成证书