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/