java8 Lambda&Stream Code

 /**
     * 获取年龄是22岁的员工
     */
    @Test
    public void testFilter() {
       list.stream()
               .filter(employee -> employee.getAge() == 22)
               .forEach(System.out::println);
    }

    /**
     *  获取所有员工的姓名,并用","连接
     */
    @Test
    public void testMap() {
        String str = list.stream()
                .map(Employee::getName)
                .collect(Collectors.joining(","));
        System.out.println(str);
    }

    /**
     * 按照工资倒序排列,并获取第一个
     */
    @Test
    public void testSort() {
        Optional<Employee> optional = list.stream().sorted((e1, e2) -> {
            if (e1.getSlary() > e2.getSlary()) {
                return -1;
            } else if (e1.getSlary() == e2.getSlary()) {
                return 0;
            } else {
                return 1;
            }
        }).findFirst();

        System.out.println(optional.get());
    }

    /**
     * 最少工资
     */
    @Test
    public void testMin() {
        Double slary = list.stream()
                .map(Employee::getSlary)
                .min(Double::compareTo)
                .get();

        System.out.println(slary);
    }

    /**
     * 根据年龄进行分组
     */
    @Test
    public void testGroup() {
        Map<Integer, List<Employee>> map = list.stream().collect(Collectors.groupingBy(Employee::getAge));
        System.out.println(map);
    }

    /**
     * 工资大于5000的个数
     */
    @Test
    public void testCount() {
        Long count = list.stream().filter(employee -> employee.getSlary() > 8000)
                .count();

        System.out.println(count);
    }

    @Test
    public void testA() {

        BiPredicate<String, String> predicate2 = (s1, s2) -> s1.equals(s2);

        BiPredicate<String, String> predicate = String::equals;
        BiConsumer<List, String> bf = List::add;
        Function<Employee, String> f = Employee::getName;
        Supplier<String> s = String::new;

    }

    /**
     * 总薪水
     */
    @Test
    public void testStatistic() {
        DoubleSummaryStatistics statistics = list.stream().collect(Collectors.summarizingDouble(Employee::getSlary));
        System.out.println(statistics.getSum());
    }

scss语法代码片段

/* Welcome to Compass.
 * In this file you should write your main styles. (or centralize your imports)
 * Import this file using the following HTML or equivalent:
 * <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css" /> */

@import "variable"; //导入变量文件

// 需要安装插件 gem install compass-normalize
// config.rb配置 require 'compass-normalize'
@import "normalize" ; 
//@import "compass/reset";
@import "compass/layout";

@include sticky-footer(54px);

/**
`commonProperty`先声明再使用
*/
@mixin commonProperty($w: 50%) {
    background: #fff;
    padding: 5px;
    width: $w;
    float: left;
}

.btn { // 编译「显示」到css中
    margin: 0;
}


%btn-hidden { // 编译「不显示」到css中
    text-align: center;
}

//----
.btn-primary {
    @extend .btn;
    @extend %btn-hidden;
    @include commonProperty();
    padding: 9px;
}

html, body {
    color: $color;

    font: { // 属性嵌套
        family: '黑体';
        size: 16px;
    }

    @at-root { // 保留层次关系,编译后到顶层
        .header {
            position: relative;
        }
    }
}

p {
    @include commonProperty(100%);

    background-image: image-url("a.png"); //属性中,直接调用函数
}

@debug append-url("hello.png"); 

/**
`makecText`先声明再使用
*/
@function makeText($selector) {
    @return $selector;
}


#{ makeText(".hello-world") } { //如果在选择器材中使用,#{functionName}
    color: red;
    font-size: 20px;
}

Apache + Let’s Encrypt配置HTTPS

申请通配符证书

# 下载 Certbot 客户端
$ wget https://dl.eff.org/certbot-auto

# 设为可执行权限
$ chmod a+x certbot-auto

# 移动的bin目录下
mv certbot-auto /usr/bin

部署apache

$ sudo certbot-auto --apache

根据命令行提示进行操作

  • 校验证书信息
openssl x509 -in  /etc/letsencrypt/live/xhope.top/cert.pem -noout -text
  • 证书和密钥保存在下列目录
tree /etc/letsencrypt/live/xhope.top/

修改配置文件

  • 查看apache配置文件路径
$ httpd -V
  • 编辑/conf.d/ssl.conf,使用证书。
LoadModule ssl_module modules/mod_ssl.so

Listen 443
<VirtualHost *:443>
    ServerName www.xhope.top
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/xhope.top/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/xhope.top/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/xhope.top/chain.pem
</VirtualHost>

  • 强制跳转到https,在网站的根目录下创建.htaccess文件
$ cd /var/www/html
$ vi .htaccess

编辑.htaccess

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R,L]

参考Apache 强制 HTTP 全部跳转到 HTTPS

  • 检查证书状态

https://www.ssllabs.com/ssltest/analyze.html?d=xhope.top

  • 其他工具检查

https://www.whynopadlock.com/

使用 crontab 让 lets encrypt 自动续期

Let’s Encrypt 证书只有 90 天的有效期,一旦我们忘记了就会失效了。所以建议使用 crontab 进行自动续期,让证书一直有效。

$ crontab -e

在编辑模式下添加

0 3 1 * * /usr/bin/certbot-auto renew 2>>/var/log/cert-renew.log >>/var/log/cert-renew.log

用 crontab -l 命令查看一下是否存在刚才添加的定时命令。如果存在的话,那么每月 1 日的凌晨 3 点就会执行一次所有域名的续期操作。不过有请求次数的限制所以别太频繁了。

$ crontab -l

https://www.vpsss.net/1328.html

参考网站:

阿里云API使用

阿里云获取Access Key,在控制台 > 头像hover > accesskeys

API:域名查看是否可以注册

文档地址:域名Check接口

手动实现签名

手动实现比较麻烦,但是可以了解签名的组成过程。

参考资料
* 公共参数
* 签名机制

package com.yodean.component.site;

import org.springframework.util.Base64Utils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * All rights Reserved, Designed By www.xhope.top
 *
 * @version V1.0
 * @Description: (用一句话描述该文件做什么)
 * @author: Rick.Xu
 * @date: 11/19/18 18:49
 * @Copyright: 2018 www.yodean.com. All rights reserved.
 */
public class Test {

    private static final String ENCODING = "UTF-8";

    private static final  String ALGORITHM = "HmacSHA1";

    private static String percentEncode(String value) throws UnsupportedEncodingException {
        return value != null ? URLEncoder.encode(value, ENCODING).replace("+", "%20").replace("*", "%2A").replace("%7E", "~") : null;
    }

    private static final String ISO8601_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";

    private static String formatIso8601Date(Date date) {
        SimpleDateFormat df = new SimpleDateFormat(ISO8601_DATE_FORMAT);
        df.setTimeZone(new SimpleTimeZone(0, "GMT"));
        return df.format(date);
    }

    public static void main(String[] args) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException {
        Map<String, String> parameters = new HashMap();
        // 输入请求参数
        parameters.put("Action", "CheckDomain");//变量
        parameters.put("DomainName", "google.com");
        parameters.put("FeeCommand", "create");
        parameters.put("FeeCurrency", "CNY");
        parameters.put("FeePeriod", "1");

        // 公共参数
        parameters.put("Version", "2018-01-29"); //变量
        parameters.put("AccessKeyId", "test");

        parameters.put("Timestamp", formatIso8601Date(new Date()));
        parameters.put("SignatureMethod", "HMAC-SHA1");
        parameters.put("SignatureVersion", "1.0");
        parameters.put("SignatureNonce", UUID.randomUUID().toString());
        parameters.put("Format", "JSON");

        StringBuilder url = new StringBuilder();

        url.append("http://domain.aliyuncs.com/?"); //变量

        parameters.forEach((k, v) -> {
            url.append(k).append("=").append(v).append("&");
        });

        // 获取签名字符串
        String stringToSign = getStringToSign(parameters);


        System.out.println(stringToSign);
        System.out.println();

        // 签名
        String signature = signature(stringToSign);
        System.out.println(signature);
        System.out.println();

        // 添加签名到原始url
        url.append("Signature=" + signature);
        System.out.println(url.toString());

    }

    private static String signature(String stringToSign) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
        String key = "testsecret&";
        Mac mac = Mac.getInstance(ALGORITHM);
        mac.init(new SecretKeySpec(key.getBytes(ENCODING), ALGORITHM));
        byte[] signData = mac.doFinal(stringToSign.getBytes(ENCODING));
        String signature = new String(Base64Utils.encodeToString(signData));

        return percentEncode(signature);
    }

    private static String getStringToSign(Map<String, String> parameters) throws UnsupportedEncodingException {
        final String HTTP_METHOD = "GET";
        // 排序请求参数
        String[] sortedKeys = parameters.keySet().toArray(new String[]{});
        Arrays.sort(sortedKeys);
        final String SEPARATOR = "&";
        // 构造 stringToSign 字符串
        StringBuilder stringToSign = new StringBuilder();
        stringToSign.append(HTTP_METHOD).append(SEPARATOR);
        stringToSign.append(percentEncode("/")).append(SEPARATOR);
        StringBuilder canonicalizedQueryString = new StringBuilder();
        for(String key : sortedKeys) {
            // 这里注意编码 key 和 value
            canonicalizedQueryString.append("&")
                    .append(percentEncode(key)).append("=")
                    .append(percentEncode(parameters.get(key)));
        }
        // 这里注意编码 canonicalizedQueryString
        stringToSign.append(percentEncode(
                canonicalizedQueryString.toString().substring(1)));

        return stringToSign.toString();
    }
}

SDK

SDK

百度云API使用

Access Key

域名服务API仅对申请的用户开放
,使用前请先提交工单申请。提交工单需要提供AK(Access Key),查看方式如下:管理控制平台>鼠标悬浮到右上角,您的用户名的地方不要点击,下面有一个”安全认证”>点击安全认证,里面有AK。
一般半天就能审核下来

使用API前的准备

自己搞签名太繁琐,可以用提供的SDK下载地址,也可通过maven引用

pom.xml

 <dependency>
   <groupId>com.baidubce</groupId>
   <artifactId>bce-java-sdk</artifactId>
   <version>0.10.42</version>
 </dependency>

SDK入门指南

通过使用【位置服务】测试SDK正确性。帮助文档

main.java


BceClientConfiguration config = new BceClientConfiguration(); config.setCredentials(new DefaultBceCredentials(ACCESS_KEY_ID, SECRET_ACCESS_KEY)); // 设置网络协议 config.setProtocol(Protocol.HTTPS); // 设置允许打开的最大连接数 config.setMaxConnections(10); // 设置建立连接的超时时间 config.setConnectionTimeoutInMillis(5000); DuMapClient client = new DuMapClient(config); PlaceSearchByRegionParam param = PlaceSearchByRegionParam.builder() .query("ATM机") // 检索关键字 .tag("银行") // 检索分类偏好 .region("北京") // 检索行政区划区域 .output("json") // 输出格式为json字符串或者xml字符串 .build(); String response = client.placeQuery(appId, param); // <your-app-id> 为用户的appId,即前端应用列表中的应用id System.out.println(response); //JSON字符串

位置服务需要提供your-app-id,这个可以在控制台设置,链接

调用域名API

域名服务并没有自己的xxxClient,需要模仿DuMap服务,写一个。

DomainResponse.java

public class DomainResponse extends AbstractBceResponse {
    private String payload;

    public DomainResponse() {
    }

    public String getPayload() {
        return this.payload;
    }

    public void setPayload(String payload) {
        this.payload = payload;
    }
}

DomainResponseHandler.java

public class DomainResponseHandler implements HttpResponseHandler {

    @Override
    public boolean handle(BceHttpResponse httpResponse, AbstractBceResponse response) throws Exception {

        InputStream content = httpResponse.getContent();
        DomainResponse domainResponse = (DomainResponse)response;
        if (content != null) {
            domainResponse.setPayload(new String(ByteStreams.toByteArray(content)));
            content.close();
        }

        return true;
    }
}

DomainClient.java

public class DomainClient extends AbstractBceClient {

    private static HttpResponseHandler[] dumapHandlers = new HttpResponseHandler[]{new BceMetadataResponseHandler(), new BceErrorResponseHandler(), new DomainResponseHandler()};


    public DomainClient(BceClientConfiguration config){
        super(config, dumapHandlers);
    }

    public String query() throws URISyntaxException {

        String s = "http://bcd.baidubce.com";

        URI uri = HttpUtils.appendUri(new URI(s), "/v1/domain/price");

        InternalRequest request = new InternalRequest(HttpMethodName.GET, uri);

        request.addParameter("domain", "51fzlh.com");

        DomainResponse response = this.invokeHttpClient(request, DomainResponse.class);

        return response.getPayload();

    }

}

Main.java


BceClientConfiguration config = new BceClientConfiguration(); config.setCredentials(new DefaultBceCredentials(ACCESS_KEY_ID, SECRET_ACCESS_KEY)); DomainClient client = new DomainClient(config); System.out.println(client.query());