网站数字化建设,中国建设银行门户网站企业,2019年做网站还有机会吗,dz网站收款即时到账怎么做的前后端分离项目中#xff0c;当前前端请求后端接口的时候通常需要传输参数#xff0c;对于参数的校验应该在哪一步进行校验#xff1f;Controller中还是Service中#xff1f;答案是都需要校验#xff0c;只不过负责的板块不一样#xff0c;Controller中通常校验请求参数的…前后端分离项目中当前前端请求后端接口的时候通常需要传输参数对于参数的校验应该在哪一步进行校验Controller中还是Service中答案是都需要校验只不过负责的板块不一样Controller中通常校验请求参数的合法性包括必填项校验数据格式校验比如是否为空是否符合一定的日期格式等。Service中要校验的是业务规则相关的内容比如课程已经审核通过所以提交失败。Service中根据业务规则去校验通常因为业务各异所以一般无法提取成通用代码Controller中则可以将校验的代码写成通用代码。 在JavaEE6规范中就定义了参数校验的规范JSR-303它定义了Bean Validation即对bean属性进行校验。同时SpringBoot也提供了JSR-303的支持即spring-boot-starter-validation底层使用Hibernate ValidatorHibernate Validator是Bean Validation 的参考实现。 接下来在Controller层使用spring-boot-starter-validation完成对请求参数的基本合法性进行校验。
首先在项目所属或依赖工程中添加相应依赖
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-validation/artifactId
/dependency在javax.validation.constraints包下有很多校验注解用于定义校验规则。
Constraint详细信息Null被注释的元素必须为 nullNotNull被注释的元素必须不为 nullAssertTrue被注释的元素必须为 trueAssertFalse被注释的元素必须为 falseMin(value)被注释的元素必须是一个数字其值必须大于等于指定的最小值Max(value)被注释的元素必须是一个数字其值必须小于等于指定的最大值DecimalMin(value)被注释的元素必须是一个数字其值必须大于等于指定的最小值DecimalMax(value)被注释的元素必须是一个数字其值必须小于等于指定的最大值Size(max, min)被注释的元素的大小必须在指定的范围内Digits(integer, fraction)被注释的元素必须是一个数字其值必须在可接受的范围内Past被注释的元素必须是一个过去的日期Future被注释的元素必须是一个将来的日期Pattern(regex)被注释的元素必须符合指定的正则表达式Valid被注释的元素需要递归验证Email被注释的元素必须是电子邮箱地址Length(min下限, max上限)被注释的字符串的大小必须在指定的范围内NotEmpty被注释的元素的必须非空并且size大于0NotBlank被注释的元素必须不为空且不能全部为’ (空字符串)Range(min最小值, max最大值)被注释的元素必须在合适的范围内
例如项目中存在一个接口用于创建课程
ApiOperation(新增课程)
PostMapping(/course)
public CourseBaseInfoDto createCourseBase(RequestBody AddCourseDto addCourseDto) {Long companyId 10000L;CourseBaseInfoDto courseBase courseBaseInfoService.createCourseBase(companyId, addCourseDto);return courseBase;
}此接口使用AddCourseDto模型对象接收参数可进入AddCourseDto类在属性上添加校验规则。
package com.gavin.content.model.dto;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.math.BigDecimal;/*** author Gavin* description 添加课程dto* date 2024/10/14*/
Data
ApiModel(value AddCourseDto, description 新增课程基本信息)
public class AddCourseDto {NotEmpty(message 课程名称不能为空)ApiModelProperty(value 课程名称, required true)private String name;NotEmpty(message 适用人群不能为空)Size(message 适用人群内容过少, min 10)ApiModelProperty(value 适用人群, required true)private String users;ApiModelProperty(value 课程标签)private String tags;NotEmpty(message 课程分类不能为空)ApiModelProperty(value 大分类, required true)private String mt;NotEmpty(message 课程分类不能为空)ApiModelProperty(value 小分类, required true)private String st;NotEmpty(message 课程等级不能为空)ApiModelProperty(value 课程等级, required true)private String grade;ApiModelProperty(value 教学模式普通录播直播等, required true)private String teachmode;ApiModelProperty(value 课程介绍)private String description;ApiModelProperty(value 课程图片, required true)private String pic;NotEmpty(message 收费规则不能为空)ApiModelProperty(value 收费规则对应数据字典, required true)private String charge;ApiModelProperty(value 价格)private Float price;ApiModelProperty(value 原价)private Float originalPrice;ApiModelProperty(value qq)private String qq;ApiModelProperty(value 微信)private String wechat;ApiModelProperty(value 电话)private String phone;ApiModelProperty(value 有效期)private Integer validDays;
}上述程序中NotEmpty表示属性不能为空Size表示限制属性内容的长短。 定义好校验规则还需要开启校验在controller方法中添加Validated注解如下
ApiOperation(新增课程)
PostMapping(/course)
public CourseBaseInfoDto createCourseBase(RequestBody Validated AddCourseDto addCourseDto) {//获取到用户所属机构的idLong companyId 10000L;CourseBaseInfoDto courseBase courseBaseInfoService.createCourseBase(companyId, addCourseDto);return courseBase;
}如果校验出错Spring会抛出MethodArgumentNotValidException异常为了使得报错信息更加明确可以在统一异常处理器中捕获异常解析出异常信息。在全局异常处理器中添加对该类异常的解析处理(全局异常处理类的建立见【实战案例】SpringBoot项目中异常处理通用解决方案)如下
ResponseBody
ExceptionHandler(MethodArgumentNotValidException.class)
ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public RestErrorResponse methodArgumentNotValidException(MethodArgumentNotValidException e) {BindingResult bindingResult e.getBindingResult();ListString msgList new ArrayList();//将错误信息放在msgListbindingResult.getFieldErrors().stream().forEach(item-msgList.add(item.getDefaultMessage()));//拼接错误信息String msg StringUtils.join(msgList, ,);log.error(【系统异常】{},msg);return new RestErrorResponse(msg);
}经过测试可在不合法的数据参数情况下返回类似如下的异常信息
{errMessage: 课程名称不能为空,适用人群内容过少
}可见校验器生效。
有时候在同一个属性上设置一个校验规则不能满足要求比如订单编号由系统生成在添加订单时要求订单编号为空在更新 订单时要求订单编写不能为空。此时就用到了分组校验同一个属性定义多个校验规则属于不同的分组比如添加订单定义NULL规则属于insert分组更新订单定义NotEmpty规则属于update分组insert和update是分组的名称是可以修改的。 可以用class类型来表示不同的分组定义不同的接口类型空接口表示不同的分组如下
public class ValidationGroups {public interface Insert{};public interface Update{};public interface Delete{};}定义校验规则时指定分组
NotEmpty(groups {ValidationGroups.Insert.class},message 添加课程名称不能为空)
NotEmpty(groups {ValidationGroups.Update.class},message 修改课程名称不能为空)
ApiModelProperty(value 课程名称, required true)
private String name;在Controller方法中启动校验规则指定要使用的分组名
ApiOperation(新增课程基础信息)
PostMapping(/course)
public CourseBaseInfoDto createCourseBase(RequestBody Validated({ValidationGroups.Insert.class}) AddCourseDto addCourseDto){Long companyId 10000L;return courseBaseInfoService.createCourseBase(companyId,addCourseDto);
}通过上述配置则可实现不同类型的异常信息在不同类型的请求过来使用模型类的时候加以区分。 如果javax.validation.constraints包下的校验规则满足不了需求可通过手写校验代码或自定义校验规则注解。 自定义校验规则注解示例如下 定义一个自定义注解 OnlyLetters用于验证字段是否只包含字母字符
package com.gavin.validation;import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;// 指定注解的适用范围字段级别
Target({ElementType.FIELD, ElementType.METHOD})
// 指定注解的生命周期在运行时可用
Retention(RetentionPolicy.RUNTIME)
// 关联校验器类
Constraint(validatedBy OnlyLettersValidator.class)
public interface OnlyLetters {// 错误信息String message() default 只能包含字母字符;// 用于分组校验Class?[] groups() default {};实现 OnlyLettersValidator 类编写具体的校验逻辑
package com.gavin.validation;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;public class OnlyLettersValidator implements ConstraintValidatorOnlyLetters, String {// 初始化方法可以用来获取注解的属性值Overridepublic void initialize(OnlyLetters constraintAnnotation) {// 不需要初始化操作}// 校验逻辑Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {// 如果字段为空不进行验证可以在其他注解中处理空值校验if (value null) {return true;}// 校验字符串是否只包含字母return value.matches([a-zA-Z]);}
}通过上述自定义注解即可跟前序流程一样进行使用。 文章转载自: http://www.morning.lhqw.cn.gov.cn.lhqw.cn http://www.morning.tgpgx.cn.gov.cn.tgpgx.cn http://www.morning.kphsp.cn.gov.cn.kphsp.cn http://www.morning.zcwwb.cn.gov.cn.zcwwb.cn http://www.morning.fxwkl.cn.gov.cn.fxwkl.cn http://www.morning.hgbzc.cn.gov.cn.hgbzc.cn http://www.morning.dnmwl.cn.gov.cn.dnmwl.cn http://www.morning.rfpq.cn.gov.cn.rfpq.cn http://www.morning.kldtf.cn.gov.cn.kldtf.cn http://www.morning.stwxr.cn.gov.cn.stwxr.cn http://www.morning.xkjrs.cn.gov.cn.xkjrs.cn http://www.morning.jnvivi.com.gov.cn.jnvivi.com http://www.morning.jcwrb.cn.gov.cn.jcwrb.cn http://www.morning.gcqs.cn.gov.cn.gcqs.cn http://www.morning.lzph.cn.gov.cn.lzph.cn http://www.morning.hkysq.cn.gov.cn.hkysq.cn http://www.morning.zmwd.cn.gov.cn.zmwd.cn http://www.morning.pshpx.cn.gov.cn.pshpx.cn http://www.morning.rrms.cn.gov.cn.rrms.cn http://www.morning.fxzgw.com.gov.cn.fxzgw.com http://www.morning.qgjp.cn.gov.cn.qgjp.cn http://www.morning.xjqhh.cn.gov.cn.xjqhh.cn http://www.morning.ryqsq.cn.gov.cn.ryqsq.cn http://www.morning.pzjrm.cn.gov.cn.pzjrm.cn http://www.morning.jwbfj.cn.gov.cn.jwbfj.cn http://www.morning.zxybw.cn.gov.cn.zxybw.cn http://www.morning.dtcsp.cn.gov.cn.dtcsp.cn http://www.morning.twhgn.cn.gov.cn.twhgn.cn http://www.morning.wxckm.cn.gov.cn.wxckm.cn http://www.morning.gsyns.cn.gov.cn.gsyns.cn http://www.morning.hlxpz.cn.gov.cn.hlxpz.cn http://www.morning.jsljr.cn.gov.cn.jsljr.cn http://www.morning.rzrbw.cn.gov.cn.rzrbw.cn http://www.morning.blqgc.cn.gov.cn.blqgc.cn http://www.morning.htbsk.cn.gov.cn.htbsk.cn http://www.morning.zmtrk.cn.gov.cn.zmtrk.cn http://www.morning.hmxrs.cn.gov.cn.hmxrs.cn http://www.morning.jrqbr.cn.gov.cn.jrqbr.cn http://www.morning.swimstaracademy.cn.gov.cn.swimstaracademy.cn http://www.morning.jyzxt.cn.gov.cn.jyzxt.cn http://www.morning.rwrn.cn.gov.cn.rwrn.cn http://www.morning.lrprj.cn.gov.cn.lrprj.cn http://www.morning.dtnyl.cn.gov.cn.dtnyl.cn http://www.morning.lsmgl.cn.gov.cn.lsmgl.cn http://www.morning.zfyfy.cn.gov.cn.zfyfy.cn http://www.morning.ftnhr.cn.gov.cn.ftnhr.cn http://www.morning.yrdkl.cn.gov.cn.yrdkl.cn http://www.morning.kkqgf.cn.gov.cn.kkqgf.cn http://www.morning.jzykw.cn.gov.cn.jzykw.cn http://www.morning.jcrlx.cn.gov.cn.jcrlx.cn http://www.morning.qkgwx.cn.gov.cn.qkgwx.cn http://www.morning.glxdk.cn.gov.cn.glxdk.cn http://www.morning.jiuyungps.com.gov.cn.jiuyungps.com http://www.morning.qineryuyin.com.gov.cn.qineryuyin.com http://www.morning.mdnnz.cn.gov.cn.mdnnz.cn http://www.morning.trlhc.cn.gov.cn.trlhc.cn http://www.morning.wdply.cn.gov.cn.wdply.cn http://www.morning.xlmgq.cn.gov.cn.xlmgq.cn http://www.morning.bhmnp.cn.gov.cn.bhmnp.cn http://www.morning.wjlhp.cn.gov.cn.wjlhp.cn http://www.morning.cwyrp.cn.gov.cn.cwyrp.cn http://www.morning.zkzjm.cn.gov.cn.zkzjm.cn http://www.morning.qqnh.cn.gov.cn.qqnh.cn http://www.morning.dyght.cn.gov.cn.dyght.cn http://www.morning.ntqjh.cn.gov.cn.ntqjh.cn http://www.morning.slmbg.cn.gov.cn.slmbg.cn http://www.morning.grbp.cn.gov.cn.grbp.cn http://www.morning.ttryd.cn.gov.cn.ttryd.cn http://www.morning.kjsft.cn.gov.cn.kjsft.cn http://www.morning.cxryx.cn.gov.cn.cxryx.cn http://www.morning.tmbtm.cn.gov.cn.tmbtm.cn http://www.morning.yjxfj.cn.gov.cn.yjxfj.cn http://www.morning.rlfr.cn.gov.cn.rlfr.cn http://www.morning.hqwtm.cn.gov.cn.hqwtm.cn http://www.morning.fcrw.cn.gov.cn.fcrw.cn http://www.morning.qpnmd.cn.gov.cn.qpnmd.cn http://www.morning.ltrms.cn.gov.cn.ltrms.cn http://www.morning.jpzcq.cn.gov.cn.jpzcq.cn http://www.morning.snnwx.cn.gov.cn.snnwx.cn http://www.morning.qrndh.cn.gov.cn.qrndh.cn