后端编码规范

关于java编码规范需要注意的内容

阿里编码规范学习
类名以及常量编码命名规则:
1.不允许中文,不能使用拼音缩写(会导致看不懂),不能将英文和中文拼音混合内容
2.代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。
3.类的命名需要采用大驼峰,除外以下情形:DO / BO / DTO / VO / AO / PO 等。
4.方法名、参数名、成员变量、局部变量都统一使用小驼峰。
5.常量命名字母全部需要大写,每个单词间用下划线隔开。
6.包名使用小写,包名使用单数形式,但是类名如果有复数含义,类名可以使用复数形式。
7.类型与中括号紧挨相连来定义数组。例:int[] arrayDemo。
8.抽象类命名使用Abstract或Base开头;异常类命名使用Exception结尾;测试类命名以它要测试的类名开始,以Test结尾。

代码格式
1.大括号的使用条例:
如果是大括号内为空,则简洁地写成{}即可,不需要换行;如果是非空代码块需要满足以下规则:
(1)左大括号前不换行。
(2)左大括号后换行。
(3)右大括号前换行。
(4)右大括号后还有else等代码则不换行;表示终止的右大括号后必须换行。
2.方法参数在定义和传入时,多个参数逗号后边必须加空格。
例:下例中实参的"a",后边必须要有一个空格。
method(“a”, “b”, “c”);
3.IDE的text file encoding设置为UTF-8; IDE中文件的换行符使用Unix格式,不要使用Windows格式。
4.不同逻辑、不同语义、不同业务的代码之间插入一个空行分隔开来以提升可读性。
5.采用4个空格,禁止使用tab
6.注释的双斜线和内容要有空格
7.强制类型转换时,右括号与强制转换值之间不用空格
8.单行字符不超过120个,超过要换行
9.方法在定义和传参时,必须要加空格

面向对象(OOP)规范
1.不用一个类型的对象引用来访问静态方法和静态属性,直接类名访问即可
2.所有覆写方法,必须加@Override注解
3.相同业务含义,相同参数类型才能使用java可变参数
4.外部依赖或者二方库依赖的接口,不能修改方法签名。接口过时必须用@Deprecated 注解,并说明新接口或者新服务是什么
5…不能使用过时的类或者方法
6. Object的equals方法容易抛出空指针,应使用常量或者确定值的对象来调用equals
7.所有整型包装类之间的值比较都用equals 方法比较
8.浮点数之间的等值判断,基本类型不能用==,包装类不能用equals。
解决方案:(1) 指定一个误差范围,两个浮点数的差值在此范围之内,则认为是相等的。
(2) 使用BigDecimal来定义值,再进行浮点数的运算操作。
9.定义DO类时,属性类型要数据库字段类型相匹配
10.防止精度丢失,禁止使用BigDecimal(double)方式将double对象转换成BigDecimal。建议使用BigDecimal的valueOf方法
11.基本类型和包装类型的使用标准
(1.所有POJO的属性必须用包装类型
(2.RPC方法的参数和返回值必须使用包装类型
(3.所有局部变量使用基本变量
12.所有POJO 不要对其属性设置默认值
13.序列化类新增时不要修改其serialVersionUID字段
14.构造方法里禁止加任何业务处理逻辑,有要加在init()
15.POJO类必须要写toString方法
16.禁止在POJO类中对属性xxx 同时存在isXxx()和getXxx()
17.使用索引访问用String的split方法得到数组时,需要对最后一个分隔符有无内容做检查
18.一个类有多个构造方法或者多个同名方法,要按照顺序来。
19.类中的方法顺序 :共有方法-> 私有方法 -> get/set
20.setter方法中参数名称和成员变量名称一致,不要在getter和setter方法中加业务逻辑
21.循环体内用StringBuilder的append方法进行扩展
22.final可以修饰类,方法,变量。
23.慎用Object的clone方法
24.类成员与方法访问控制从严
1)如果不允许外部直接通过new来创建对象,那么构造方法必须是private。
2)工具类不允许有public或default构造方法。
3)类非static成员变量并且与子类共享,必须是protected。
4)类非static成员变量并且仅在本类使用,必须是private。
5)类static成员变量如果仅在本类使用,必须是private。
6)若是static成员变量,考虑是否为final。
7)类成员方法只供类内部调用,必须是private。
8)类成员方法只对继承类公开,那么访问权限必须为protected。

安全方面
1.与用户个人信息和个人页面有关联的必须进行权限验证
2.用户敏感信息必须进行脱敏,严禁直接展示(比如手机号等)
3.用户传入的参数必须防止SQL注入,传入的任何参数必须做有效性验证
4.禁止向HTML页面输出未经安全过滤或为正确转义的用户信息
5.表单,ajax提交必须进行CSRF验证

直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC语法后生成一个完美的目录。

数据库
1.表达是与否概念的字段,必须使用is_xxx命名,数据类型是unsigned tinyint(1表示是,0表示否)。
2.表名/字段名必须使用小写字母或者数字,并且禁止出现数字开头,禁止两个下划线之间只出现数字。
3.表名不使用复数名词。
4.禁止使用保留字和关键字。
5.主键的索引名为pk_字段名;唯一索引名为uk_字段名,普通索引名则为idx_字段名。
6.小数类型为decimal,禁止使用float和double。
7.如果储存的字符串长度几乎相等,使用定长char字符串类型。
8.表必备三字段,id,create_time,update_time。
9.业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引。
10.超过三个表禁止join,数据类型必须保持一致,多表关联查询时需要保证被关联的列需要有索引。
11.页面搜索禁止左模糊或者全模糊如果需要请走搜索引擎来解决。
12.使用ISNULL()判断是否是null值。
13.不得使用外键与级联,一切外键概念必须在应用层解决。
14.禁止使用储存过程,储存过程难以调试和拓展,更没有移植性。
15.数据修正时需要先select,防止数据误操作,确认无误才进行操作。
16.在表查询中,一律不要使用*作为查询的字段列表,查询需要明确写明要查询的列名。
17.pojo布尔属性不能加is,但是数据库中必须加,使用需要在resultMap中进行一一映射。
18.sql.xml尽量不要使用${},因为不能防止SQL注入
19.不允许直接拿HashMap和HashTable直接作为查询结果集的输出

springboot编码注意事项和编码规范
注意:主要针对前后端分离项目的后台部分来说明这些内容
ResultAPI的编码样式
HTTP请求方式分别代表的请求方式
GET(SELECT):从服务器取出资源(一项或多项)。
POST(CREATE):在服务器新建一个资源。
PUT(UPDATE):在服务器更新全部资源(客户端提供改变后的完整资源)。
PATCH(UPDATE):在服务器更新部分资源(客户端提供改变的属性)。
DELETE(DELETE):从服务器删除资源。

响应状态码分别代表的内容
100~199:信息状态码,代表请求已被接受,需要继续处理。
200~299:成功状态码,代表请求已成功被服务器接收、理解、并接受。
300~399:重定向状态码,代表需要客户端采取进一步的操作才能完成请求。
400~499:客户端错误状态码,代表了客户端看起来可能发生了错误,妨碍了服务器的处理。
500~599:服务器错误状态码,代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以当前的软硬件资源无法完成对请求的处理。

需要常用postman进行测试,

校验注解
1.常见的文本、邮件、不能为空等之类的验证,采用spring boot自带注解可以快速实现:@Valid注解和BindingResult验证请求参数的合法性并处理校验结果。
2.创建用户时,接口参数中用户名不能为空。@NotBlank(message = “用户名不能为空”)
在请求方法的字段上加上@valid注解时,以上的注解将生效。如果请求接口的参数无法通过校验,将返回状态码为400

返回错误信息的解决
1.后台已经能够按照RestFulApi的方式返回400的错误信息状态码,但是返回的异常信息不是很友好(有很多乱七八糟的字段,与我们自定义的400错误信息json结构不一致,在前端接受到此json时还需进行其他特殊处理),并且错误信息也没有进行统一的维护。所以 我们重构注解的异常方法,让其错误信息按着我们统一格式返回。
1)定义错误消息枚举
2)在dto中加入相应注解并在message中传入定义的枚举
3)通过发送请求进行测试,可以采用postman
4)前端接收到后端返回的json对象,做统一的拦截处理,判断 status==400弹出统一的提示(提示框为警告黄色状态,提示语为返回json对 象中“error”信息)
总结得出:使用此方式,代码精简、错误码与消息能够统一维护、返回客户端的状态更加明确.

复杂业务判断验证的逻辑
默认的校验注解只能够满足一小部分校验要求。例如需要校验一个字段是否唯一,就无法通过默认的注解完成。还有可能有更多的复杂校验逻辑。
这种情况一般有两种思路来实现验证数据
1.重构校验注解(自定义注解)
2.在service层【特别注意代码逻辑不允许写在controller层】代码逻辑判断后做异常抛出。(这里我们重点介绍这种方式)
第一步:定义错误返回消息的实体类
第二步:定义错误消息枚举
第三步:定义全局错误消息处理类,重构400错误异常方法
通过使用注解@ControllerAdvice,类RestExceptionHandler就 可以实现全局异常的拦截处理功能。自定义的方 handleResourceBadRequestException旨在拦截BadRequestException异 常,一旦拦截成功后,我们可以进行各种处理操作,并且返回自己想要的结 果。
第四步:Service代码实现
① 在枚举中加入错误消息
② Service层中直接抛出自己重构过的400方法
第五步:发送请求进行测试结果
第六步: 前端接收到后端返回的json对象,做统一的拦截处理,判断 status==400弹出统一的提示(提示框为警告黄色状态,提示语为返回json对象中“error”信息)
总结:使用此方式,代码精简、错误码与消息能够统一维护、返回客户端的状态更加明确。

发生异常的处理
定义全局的异常处理方法,避免异常未经处理直接暴露给前端,前端无法处理未知错误的异常,经常给客户造成系统bug。

解决方案:传统的解决办法是用try catch去捕获异常并按照相应的逻辑状态输出json错误码,但是新手经常遗漏或者不重视此块的代码编写,往往造成大量的程序漏洞。所以建议采用spring boot 全局异常重构的方法处理此问题。
第一步 在yml配置文件中定义异常后跳转路由
第二步 重构ErrorController方法,此方法最大的作用是将所有http错误状态 加入code错误码方便前端获取此类状态,所有未定义的错误 前端code都将收到500的错误状态码,但是也将系统异常信息返回给前端,方便程序员日常维护与定位错误.
第三步 发送请求进行测试
第四步 前端接收到后端返回的json对象,做统一的拦截处理,判断 status==500弹出统一的提示(提示框为危险红色状态,提示语为“系统错误,请联系管理员处理!”,在浏览器中console.log出json对象信息)
总结:如请求得到的测试结果找不到此路由本来系统返回的是status 404状态,但通过重构全局的异常方法,将所有http错误状态统一返回status为500服务器内部错误状态(返回的status同样保留系统原始异常抛出的状态方便程序员定位错误原因),方便前端获取此状态后做统一的判断处理。避免由于系统开发造成的未知bug,引起前端做无状态的处理或者处理起来容易遗漏。

数据库账号密码等数据
    开发过程中需要注意如数据库密码、用户名等可配置信息请存放在配置文件中,读取配置文件参数,配置类在包config/DemoConfig.java(根据需求新增新的配置类)下面书写。配置文件 统一使用yml的方式,并且书写四个yml配置文件,用于不同环境下面的参数书写。
1
参数设置
SpringBoot Web项目的参数绑定:URL传参及默认参数设置
第一种情况:参数类型必须书写包装类型
第二种情况:如果页面上表单里的参数和代码里的参数名不一样,使用注解:@RequestParam(value = “paramTest”)
第三种情况:有时候页面上的表单客户不填任何值,但是在控制器里希望它有默认值
可以使用注解默认值设置:@RequestParam(defaultValue = “5”)
第四种情况:
RequestParam还有个属性:required(必填)但是当required=true,和defaultValue= 同时出现时,required失效,可传可不传
此处注意:需要拦截异常处理方法,让返回的错误码是我们的格式。

关于spring boot的配置文件解读
spring-boot-start-tomcat这个依赖带了tomcat

AOP的理解
① 若是需要一个记录日志的功能,首先想到的是在方法中通过log4j或其他框架来进行记录日志,但写下来发现一个问题,在每个方法都需要写log日志的输出代码。②判断用户是否有登录过,登录后才能让其访问我们的controller层,也需要在每个controller方法前写统一的判断方法。所以 我们使用AOP切面进行操作。
使用AOP实现 http请求中验证http签名
思路:

if (webAppConfing.isAutoGraph()) {//开启签名认证
            //1.前端在Header中加入请求时间参数
            String timestamp = request.getHeader("timestamp");
            //2.前端与后端使用同一种加密算法加密出sign 并在Header中加入
            String sign = request.getHeader("sign");
            //3.后端使用同样的算法计算sign
            String _sign = MD5Util.MD5string(URLEncoder.encode(webAppConfing.getAppKey() + timestamp, "UTF-8"));
            if (_sign.equals(sign) == false) {
               // log.error("【签名错误】{}", sign);
                //4.如果计算出来的sign不一致,则抛出异常,不让其访问接口
                throw new RuntimeException("【签名错误】" + sign);
            }
if (webAppConfing.isAutoGraph()) {//开启签名认证
            //1.前端在Header中加入请求时间参数
            String timestamp = request.getHeader("timestamp");
            //2.前端与后端使用同一种加密算法加密出sign 并在Header中加入
            String sign = request.getHeader("sign");
            //3.后端使用同样的算法计算sign
            String _sign = MD5Util.MD5string(URLEncoder.encode(webAppConfing.getAppKey() + timestamp, "UTF-8"));
            if (_sign.equals(sign) == false) {
               // log.error("【签名错误】{}", sign);
                //4.如果计算出来的sign不一致,则抛出异常,不让其访问接口
                throw new RuntimeException("【签名错误】" + sign);
            }

第一步:在yml文件中加入配置参数,并实现参数的调用(参考上面内容如何写配置文件)
第二步:新建AOP切面,并写切面逻辑
第三步:发送测试请求
总结: 使用切面可以轻松完成签名认证,防止我们后端接口没有任何安全策略的情况下暴露给任何人,从而提高系统的健壮性。

一些细节内容
代码逻辑必须写在service层,除非极为特殊情况,可以将少量逻辑放在controller
使用前后端分离开发的项目,需要定义统一的前置路由规范
注解@JsonView的使用,有时候我们希望在不同的请求中隐藏一些字段。可以用@JsonView控制输出内容。条件查询时候不返回用户的密码,查看详情时候返回用户的密码。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值