- 参考阿里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程序的建议。
代码一定要规范起来,这样自己再看自己的代码时,就可以形成一个固定的格式,很容易就能够理解,其他人在看自己的代码时,也能够清晰。写代码不仅仅让自己能够看得懂,而且还能够让其他人看的懂,需要有一个良好的编码习惯。