java 笔记

all contains

Posted by laosuan on July 2, 2020

1 重写compare方法排序

 // 4 排序优先级: 1相关自选股回答数降序 2所有答案回答数降序
userInvitationDtoList.sort(new Comparator<UserInvitationDto>() {
  @Override
  public int compare(UserInvitationDto o1, UserInvitationDto o2) {
    if (o1.getStockAnswerCount() > o2.getStockAnswerCount()) {
      return -1;
    } else if (o1.getStockAnswerCount() < o2.getStockAnswerCount()) {
      return 1;
    }

    if (o1.getAnswerCount() > o2.getAnswerCount()) {
      return -1;
    } else if (o1.getAnswerCount() < o2.getAnswerCount()) {
      return 1;
    }

    return 0;
  }
});
 // 课程按照pv降序排序
list.sort(new Comparator<QuestionOverViewDto>() {
  @Override
  public int compare(QuestionOverViewDto o1, QuestionOverViewDto o2) {
    long o1PageView = o1.getQuestion().getPageView();
    long o2PageView = o2.getQuestion().getPageView();
    if (o1PageView > o2PageView) {
      return -1;
    } else if (o1PageView < o2PageView) {
      return 1;
    }
    return 0;
  }

2 切面

@AspectJ支持以下3种通配符。

*: 匹配任意字符,但它只能匹配上下文中的一个元素。

//匹配任何public 的方法,返回值,方法名,和参数都匹配任意。
execution(public * *(..))
//匹配所有以To结尾的方法   
execution(* *To(..))
1234

… : 匹配任意字符,可以匹配上下文中的多个元素,但在表示类时,必须和*联合使用,在表示入参时则单独使用。

//匹配com.smart包下,任何 TOTO
within(com. smart. service..*.*Service+)
12

+:表示按类型匹配指定类的所有类,必须跟在类名后面,如com.smart.Car+。继承或扩展指定类的所有类,同时还包括指定类本身。

3 用curl的格式打印restTemplate的http请求

1 调用

@Autowired
RTHelper rtHelper;

/**
 * 带有重试机制的http请求
 */
    return parseResponseBody(httpRequestTemplate, flag, resp);
}

/**
 * 通用url请求打印curl语句(调试用)
 */
public static <T> Map<String, Object> commonRequestLogCurl(HttpRequestTemplate httpRequestTemplate, String url, String flag,
    HttpMethod httpMethod, Map<String, String> headParam, T postParam) throws CommonCodeException {
    ResponseEntity<Map> resp = RTHelper.newExchange(url, httpMethod, headParam, postParam, Map.class);
    return parseResponseBody(httpRequestTemplate, flag, resp);
} ### 2 工具类
package com.gf.ask.rest.util;

import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED;
import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.gf.ask.rest.JsonHelper;

/**
 * @Auther: liuxuan
 * @Date: 2020/12/17 14:42
 * @Description:
 */
@Component
public class RTHelper {

    private static final long serialVersionUID = 4726784355951323347L;

    protected static final Logger logger = LoggerFactory.getLogger(RTHelper.class);

    private static MediaType mediaType = new MediaType("application", "json", Charset.forName("UTF-8"));

    @Autowired
    private RestTemplate restTemplate;

    /**
     * get类型Params请求
     * 为url?xxx=yyy&aaa=bbb类型
     * @param <R>
     * @param url
     * @param httpHeaders 可以为null
     * @param params
     * @param responseType
     */
    public <R> ResponseEntity<R> get(String url, HttpHeaders httpHeaders, Map<String, Object> params, Class<R> responseType) throws Exception {
        StringBuilder urlSuffix = new StringBuilder();
        LinkedMultiValueMap<String, Object> paramsMultiValueMap = new LinkedMultiValueMap();
        if (!CollectionUtils.isEmpty(params)) {
            urlSuffix.append("?");
            params.forEach(paramsMultiValueMap::add);
        }
        convertMapHttpParam(paramsMultiValueMap, urlSuffix);
        return exchange(url + urlSuffix.toString(), HttpMethod.GET, httpHeaders, null, responseType);
    }

    static private void convertMapHttpParam(LinkedMultiValueMap<String, Object> params, StringBuilder urlSuffix) {
        if (!CollectionUtils.isEmpty(params)) {
            List<String> paramList = new ArrayList<>();
            params.forEach((k, v) -> paramList.add(k + "=" + (CollectionUtils.isEmpty(v) ? "" : String.valueOf(v.get(0)))));
            urlSuffix.append(StringUtils.join(paramList, "&"));
        }
    }

    /**
     * get类型path请求
     * 为url/{1}/{2}
     * @param url
     * @param httpHeaders 可以为null
     * @param params 路径请求参数,比如/{1}/{2},list顺序代表url内部请求路径 不能使用Collections.singletonList,如果为空Collections.EMPTY_LIST 则是普通get请求
     * @param responseType
     * @param <R>
     * @return
     */
    public <R> ResponseEntity<R> get(String url, HttpHeaders httpHeaders, List<Object> params, Class<R> responseType) throws Exception {
        StringBuilder urlSuffix = new StringBuilder();
        if (!CollectionUtils.isEmpty(params)) {
            for (int i = 0; i < params.size(); i++) {
                params.set(i, String.valueOf(params.get(i)));
            }
            if (!url.endsWith("/")) {
                urlSuffix.append("/");
            }
            urlSuffix.append(StringUtils.join(params, "/"));
        }
        return exchange(url + urlSuffix.toString(), HttpMethod.GET, httpHeaders, null, responseType);
    }

    /**
     * json类型请求 application/json;charset=UTF-8
     * @param url
     * @param httpHeaders
     * @param obj 实体对象或者map
     * @param responseType
     * @param <R>
     * @return
     */
    public <R> ResponseEntity<R> json(String url, HttpHeaders httpHeaders, Object obj, Class<R> responseType) throws Exception {
        httpHeaders.setContentType(mediaType);
        return exchange(url, HttpMethod.POST, httpHeaders, obj, responseType);
    }

    /**
     * form表单类型请求 application/x-www-form-urlencoded
     * @param url
     * @param httpHeaders
     * @param obj 实体对象或者map
     * @param responseType
     * @param <R>
     * @return
     */
    public <R> ResponseEntity<R> form(String url, HttpHeaders httpHeaders, Object obj, Class<R> responseType) throws Exception {
        httpHeaders.setContentType(APPLICATION_FORM_URLENCODED);
        LinkedMultiValueMap objFormParam = new LinkedMultiValueMap();
        if (obj != null) {
            Map<String, Object> objMap = JsonHelper.json2Object(JsonHelper.object2Json(obj), Map.class);
            objMap.remove(serialVersionUID);
            objMap.forEach((k, v) -> objFormParam.add(k, v));
        }
        return exchange(url, HttpMethod.POST, httpHeaders, objFormParam, responseType);
    }

    /**
     * form表单类型请求 同上
     * @param url
     * @param obj 实体对象或者map
     * @param responseType
     * @param <R>
     * @return
     */
    public <R> ResponseEntity<R> form(String url, Object obj, Class<R> responseType) throws Exception {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(APPLICATION_FORM_URLENCODED);
        return form(url, httpHeaders, obj, responseType);
    }

    /**
     * 处理请求以及日志
     * @param url
     * @param httpMethod
     * @param httpHeaders
     * @param body 不能为string
     * @param responseType
     * @param <R>
     * @return
     */
    public <R> ResponseEntity<R> exchange(String url, HttpMethod httpMethod, HttpHeaders httpHeaders, Object body, Class<R> responseType) throws Exception {

        HttpEntity<Object> httpEntity = new HttpEntity<>(body, httpHeaders);

        StringBuilder restLogStr = new StringBuilder();

        setCurlLog(restLogStr, url, httpMethod, httpHeaders, body);

        ResponseEntity<R> exchange;

        try {
            exchange = restTemplate.exchange(url, httpMethod, httpEntity, responseType);
            setRespLog(restLogStr, exchange);

        } catch (Exception e) {
            setExceptionLog(restLogStr, e);
            throw new Exception(e);
        } finally {
            logger.info(String.valueOf(restLogStr));
        }
        return exchange;
    }

    /**
     * 处理请求以及日志curl
     * 使用:
     *     @Autowired
     *     private RTHelper rtHelper;
     * ResponseEntity<Map> resp = rtHelper.newExchange(requestListUrl, HttpMethod.GET, null, null, Map.class);
     * @return
     */
    public static <T> ResponseEntity<Map> newExchange(String url, HttpMethod httpMethod, Map<String, String> headParam, T postParam, Class<Map> responseType) {
        logger.info("url = {}", url);
        HttpHeaders httpHeaders = new HttpHeaders();
        if (headParam != null) {
            httpHeaders.setAll(headParam);
        }

        HttpEntity<T> entity = new HttpEntity<T>(postParam, httpHeaders);

        // HttpEntity<Object> httpEntity = new HttpEntity<>(body, httpHeaders);

        StringBuilder restLogStr = new StringBuilder();

        setCurlLog(restLogStr, url, httpMethod, httpHeaders, postParam);

        ResponseEntity<Map> exchange = null;
        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
        try {
            exchange = restTemplate.exchange(url, httpMethod, entity, responseType);
            setRespLog(restLogStr, exchange);

        } catch (Exception e) {
            setExceptionLog(restLogStr, e);
            // throw new Exception(e);
        } finally {
            logger.info(String.valueOf(restLogStr));
        }
        return exchange;
    }

    /**
     * 设置curl日志
     * @param restLog
     * @param url
     * @param httpMethod
     * @param httpHeaders
     * @param body
     */
    static private void setCurlLog(StringBuilder restLog, String url, HttpMethod httpMethod, HttpHeaders httpHeaders, Object body) {
        String methodName = httpMethod.name();
        StringBuilder logTag = new StringBuilder();
        logTag.append("\ncurl -X ").append(methodName).append(" \\\n");
        logTag.append("  ").append(url).append(" \\\n");

        if (!CollectionUtils.isEmpty(httpHeaders)) {
            httpHeaders.forEach((k, v) -> logTag.append("  -H '").append(k).append(": ").append(v.get(0)).append("' \\\n"));
        }

        MediaType contentType = httpHeaders.getContentType();
        if (body != null) {

            if (contentType != null && !StringUtils.isEmpty(contentType.toString())
                && APPLICATION_FORM_URLENCODED_VALUE.equals(contentType.toString())) {
                LinkedMultiValueMap<String, Object> bodyParam = (LinkedMultiValueMap) body;
                // bodyParam.remove(TAG_SERIALVERSIONUID);
                logTag.append("  -d '");
                convertMapHttpParam(bodyParam, logTag);
                logTag.append("'");
            } else {
                logTag.append("--header 'Content-Type: application/json'").append(" \\\n");;
                String bodyString = JsonHelper.object2Json(body);
                logTag.append("  -d '").append(bodyString).append("'");
            }
        }

        String curlStr = String.valueOf(logTag);
        if (curlStr.endsWith(" \\\n")) {
            curlStr = curlStr.substring(0, curlStr.length() - 3);
        }
        restLog.append(curlStr).append("\n");
    }

    /**
     * 设置异常日志
     * @param restLog
     * @param e
     */
    static private void setExceptionLog(StringBuilder restLog, Exception e) {
        restLog.append("Exception:").append(e.getMessage()).append("\n");
    }

    /**
     * 设置响应日志
     * @param restLog
     * @param exchange
     * @param <R>
     */
    static private <R> void setRespLog(StringBuilder restLog, ResponseEntity<R> exchange) {
        R body = exchange.getBody();
        restLog.append("Response code:'").append(exchange.getStatusCode()).append("',message:'");
        if (body instanceof String) {
            restLog.append(body);
        } else {
            restLog.append(JsonHelper.object2Json(body));
        }
        restLog.append("'\n");
    }
}

正则替换注释

搜索
\/\*\*\n *\* ([^\n]*)\n *\*\/

/* Location:              C:\Users\liux21\Desktop\bes-lite-spring-boot-1.x-starter-9.5.2.jar!\com\bes\enterprise\appserver\common\i18n\LocalStringsImpl.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       1.1.3
 */

替换为
@ApiModelProperty(value = "$1")

IDEA 快捷键

# go to file
mac: cmd + o
win: ctrl + shift + n

# search in all place
mac: cmd + shift + f
win: ctrl + shift + f

# back last step
mac: cmd + alt + left
win: shift + alt + left

技术分析

Java线程池ThreadPoolExecutor原理分析 https://ppj19891020.github.io/2018/11/20/Java%E7%BA%BF%E7%A8%8B%E6%B1%A0ThreadPoolExecutor%E5%8E%9F%E7%90%86%E5%88%86%E6%9E%90/

Java线程池Executors分析 https://ppj19891020.github.io/2018/11/23/Java%E7%BA%BF%E7%A8%8B%E6%B1%A0Executors%E5%88%86%E6%9E%90/

Spring源码构建环境搭建 https://ppj19891020.github.io/2019/09/01/Spring%E6%BA%90%E7%A0%81%E6%9E%84%E5%BB%BA%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/