-
參考阿里Java規範文件
- 不建議使用過時方法
-
泛型需要加上<>,這種方式建立的物件是不推薦的。
Map object = new HashMap();//禁止使用
- 字串比較時,不需要大小寫時,使用equalsIgnore方法,不使用toUppers方法
str.equals(string.toUppers());//不推薦使用
str.equalsIgnore(string);//推薦使用
- Integer很多時候沒有必須要.intValue()方法,在使用Intger或者int時,不需要使用Integer,valueof(i)進行強制轉化,java內部會進行自動拆箱和裝箱
Integer.parseInt(str); //推薦使用
Integer,valueof(str);//不推薦使用
-
儘量使用StringBuilder來替換StringBuffer,在使用執行緒的時候除外。
-
logger方式內部不建議用+進行拼接,而使用字串中帶{}的方式,也不需要進行isDebug的方式進行判斷,在使用{}語法之後,JVM執行到這時不會進行字串拼接,logger會自動進行識別某個日誌級別是否開啟。使用log4j2
logger.info("{}",str);
- 使用了StringBuilder之後,就不需要使用+在繼續拼接了。
StringBuilder builder = new StringBuilder();
builder.append("hello" + kitty); //禁止使用
builder.append("hello").append("kitty");//推薦使用
- 程式必須要異常攔截,方法內部處理異常,必須要列印異常日誌
try{
}catch(Exception e){
//什麼都不做 // 不推薦
logger.error("{}",e);//推薦異常日誌列印出來
}
- Spring攔截,統一處理空格(需要封裝request)
@Configuration
public class HttpFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
WebServletRequestWrapper wrapperRequest = null;
if (servletRequest instanceof HttpServletRequest) {
wrapperRequest = new WebServletRequestWrapper((HttpServletRequest) servletRequest);
}
if (wrapperRequest == null) {
filterChain.doFilter(servletRequest, servletResponse);
} else {
filterChain.doFilter(wrapperRequest, servletResponse);
}
}
@Override
public void destroy() {
}
}
public class WebServletRequestWrapper extends HttpServletRequestWrapper {
private Map<String, String[]> params = new HashMap<String, String[]>();
private final String body;
public WebServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
body = inputStreamBody(request);
//處理引數
Map<String, String[]> parameterMap = request.getParameterMap();
this.params.putAll(parameterMap);
this.modifyParameterValues();
}
@Override
public ServletInputStream getInputStream() throws IOException {
//將input流封裝一次
final ByteArrayInputStream byteArrayInputStream =
new ByteArrayInputStream(body.getBytes("utf-8"));
DelegatingServletInputStream delegatingServletInputStream = new DelegatingServletInputStream(
byteArrayInputStream);
//非json型別,直接返回
if (!super.getHeader(HttpHeaders.CONTENT_TYPE)
.equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)) {
return delegatingServletInputStream;
}
//為空,直接返回
if (StringUtils.isEmpty(body)) {
return delegatingServletInputStream;
}
Map<String, String> map = new HashMap<>();
json2Map(map, body);
return new DelegatingServletInputStream(
new ByteArrayInputStream(JSON.toJSONString(map).getBytes("utf-8")));
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream(), "UTF-8"));
}
public String getBody() {
return this.body;
}
/**
* 將parameter的值去除空格後重寫回去
*/
public void modifyParameterValues() {
Iterator<Entry<String, String[]>> it = params.entrySet().iterator();
while (it.hasNext()) {
Entry<String, String[]> entry = it.next();
String key = entry.getKey();
String[] values = entry.getValue();
values[0] = values[0].trim();
params.put(key, values);
}
}
/**
* 重寫getParameter 引數從當前類中的map獲取
*/
@Override
public String getParameter(String name) {
String[] values = params.get(name);
if (values == null || values.length == 0) {
return null;
}
return values[0];
}
@Override
public String[] getParameterValues(String name) {//同上
return params.get(name);
}
@Override
public Map<String, String[]> getParameterMap() {
return this.params;
}
/**
* 轉化body
*/
public String inputStreamBody(HttpServletRequest request) throws IOException {
StringBuffer stringBuilder = new StringBuffer();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
return stringBuilder.toString();
}
/**
* 將json字串轉化為Map,並去除掉值的空格
*/
public static void json2Map(Map<String, String> map, String json) {
JSONObject object = JSONObject.parseObject(json);
Set set = object.keySet();
for (Object o : set) {
String key = (String) o;
String s = object.getString(key);
if (s.indexOf(`{`) == 0 && s.lastIndexOf(`}`) == s.length() - 1) {//物件.
JSONObject oo = fromObject(s);
if (oo == null) {
map.put(key, s.trim());
} else {
json2Map(map, s);
}
} else {
map.put(key, s.trim());
}
}
}
/**
* 將json字串轉化為JSONObject,異常返回null
*/
public static JSONObject fromObject(String jsonStr) {
return JSONObject.parseObject(jsonStr);
}
}
- 每個web請求輸入和輸出列印(Spring 切面)
@Aspect
@Component(value = "lmsControllerInterceptor")
public class ControllerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(ControllerInterceptor.class);
@Pointcut("execution(* com.cootf.resim.lms.web.controller.*..*(..))")
public void methodPointcut() {
}
@AfterThrowing(pointcut = "methodPointcut()", throwing = "e")
public void doThrowingAfterMethodPointcut(JoinPoint jp, Throwable e) {
logger.error("exception: {}", MiscUtil.trace(e));
}
@SuppressWarnings("unchecked")
@Around("methodPointcut()")
public Object aroundMethodPointcut(ProceedingJoinPoint pjp) {
Object result = null;
long startTime = System.currentTimeMillis();
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
if (attributes == null) {
return result;
}
WebServletRequestWrapper request = (WebServletRequestWrapper) attributes.getRequest();//封裝了流
String method = request.getMethod();
String uri = request.getRequestURI();
long endTime;
//獲取引數
Map<String, String> paramMap = new HashMap<>();
Enumeration<String> paramNames = request.getParameterNames();
while (paramNames.hasMoreElements()) {
String paramName = paramNames.nextElement();
String valueStr = request.getParameter(paramName);
paramMap.put(paramName, valueStr);
}
logger.info("request start,uri: {},method: {},req: {},body:{}", uri, method, paramMap,
request.getBody().replaceAll("\r|\n", ""));
try {
result = pjp.proceed();
endTime = System.currentTimeMillis();
logger.info("request end,elap: {}ms,uri: {},method: {},rsp: {}", (endTime - startTime), uri,
method, MiscUtil.obj2Json(result));
} catch (Throwable throwable) {
endTime = System.currentTimeMillis();
logger
.error("request end,elap: {}ms,uri: {},method: {},e: {}", (endTime - startTime),
uri, method, MiscUtil.trace(throwable));
return Rsp.transEnd(RpcFailReasonEnum.ERR_SYSTEM_ERROR.getCode(),
RpcFailReasonEnum.ERR_SYSTEM_ERROR.getDesc());
}
return result;
}
}
- 引數需要校驗, 使用Hibernate-validate框架,每個請求都建立實體,註解式的引數校驗。
- 出現兩次以上的程式碼塊需要抽離單獨的方法。
- idea中置灰的程式碼刪除
- resutful風格的路徑,都必須要小寫
@PostMapping("/device/new") // 新增裝置介面
- 每個介面或方法(介面的實現除外)都需要有一個簡短的中文註釋
/**
* 通過電話號碼查詢使用者
*/
Custom selectCustom(String phoneNumber);
- 不同層的方法開頭規則
- DAO層 方法以select開頭。 selectUserInfo(); insert,update,delete(即mysql使用的關鍵詞)
- Service和Controller層方法queryUserInfo(),saveUserInfo(),editUserInfo(),deleteUserInfo()
- 資料庫對映實體 字尾entity UserEntity
- controller 返回實體字尾Rsp UserRsp
- 引數校驗實體 UserVo
- 部署需要寫指令碼,或者是利用框架,實現自動化
- 狀態等型別必須使用列舉型別或者是單獨一個類的實體的靜態變數
public enum UserEnum{
ENABLE(0,"啟用"),
DISABLE(1,"禁止");
private int code;
private String desc;
UserEnum(int code,String desc){
this.code = code;
this.desc = desc;
}
public int getCode(){
return this.code;
}
public String desc(){
return this.desc;
}
}
public class Constant{
public static final int ENABLE = 0;//啟用
public static final int DISABLE = 1;//禁止
···
}
- if 巢狀不能超過三層,多使用if(){return;}
if(引數不正確){
return "返回引數不正確";
}
if(使用者沒有找到){
return "使用者沒有找到";
}
這個是自己最近總結的Java規範文件,在看別人程式碼並且對照自己編碼習慣,總結以上幾點。 以上有幾點是關於web程式的建議。
程式碼一定要規範起來,這樣自己再看自己的程式碼時,就可以形成一個固定的格式,很容易就能夠理解,其他人在看自己的程式碼時,也能夠清晰。寫程式碼不僅僅讓自己能夠看得懂,而且還能夠讓其他人看的懂,需要有一個良好的編碼習慣。