1. controller
1.1 @Valid (建议使用)
https://blog.csdn.net/m0_73311735/article/details/126439095
https://www.cnblogs.com/hanease/p/16951568.html
建议使用@Valid
import javax.validation.Valid;
@Valid的嵌套校验(校验的对象中引入的其他对象或者List对象的校验),嵌套类时只需写一个类文件。
import org.springframework.validation.annotation.Validated;
@Validate不支持嵌套校验(校验的对象中引入的其他对象或者List对象的校验),
嵌套类时需写多个类文件。
如下参数校验示例:
package com.XX.ms.cartechmessageservice.model.vo.message.req;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
@NoArgsConstructor
@ApiModel("(单条)消息推送接口入参")
@Data
public class MsgSendReq {
@ApiModelProperty(value = "消息二级分类名称", required = true)
@NotBlank(message = "消息二级分类名称不能为空")
private String msgSecondTypeName;
@ApiModelProperty(value = "需要接收消息的用户工号集合 例:[\"20004855\",\"20004852\"]", required = true)
@NotEmpty(message = "需要接收消息的用户工号集合不能为空")
private List<String> pushUserCodeList;
@ApiModelProperty(value = "发送消息的用户工号 例:\"20004855\"")
private String sendUserCode;
@ApiModelProperty(value = "是否加急消息 1:加急 2:不加急(默认)", required = false)
private Integer isUrgent;
@ApiModelProperty(value = "推送目标", hidden = true)
private PushTargetDTO pushTarget;
@Valid
@ApiModelProperty("推送展示细节配置")
private PushNotifyDTO pushNotify;
@Valid
@ApiModelProperty("link相关打开配置")
private PushForwardDTO pushForward;
// 推送目标
@NoArgsConstructor
@Data
public static class PushTargetDTO {
@ApiModelProperty(value = "推送目标类型", hidden = true)
private Integer target;
@ApiModelProperty(value = "推送rid集合", hidden = true)
private List<String> rids;
}
// 推送展示细节配置
@NoArgsConstructor
@Data
public static class PushNotifyDTO {
@ApiModelProperty(value = "推送rid集合", hidden = true)
private List<Integer> plats;
@ApiModelProperty(value = "推送的内容", required = true)
@NotBlank(message = "推送的内容不能为空")
private String content;
@ApiModelProperty(value = "推送的标题", required = false)
private String title;
@ApiModelProperty(value = "推送类型 1:通知 2:不通知(自定义)", required = true)
@NotNull(message = "推送类型不能为空")
private Integer type;
}
// link相关打开配置
@NoArgsConstructor
@Data
public static class PushForwardDTO {
@ApiModelProperty(value = "后续动作 - 0:打开首页 - 1:link跳转 - 2:scheme 跳转 - 3:Intent", required = true)
@NotNull(message = "后续动作不能为空")
private Integer nextType;
@ApiModelProperty("nextType=2 必填 moblink功能的的scheme 例:mlink://com.mob.mobpush.linkone")
private String scheme;
@ApiModelProperty("scheme参数 例:{\"key1\":\"value1\",\"key2\":\"value2\",…}")
private JSONObject schemeData;
}
/*
{
"msgSecondTypeName": "消息二级分类名称",
"pushNotify": { // 推送目标
"content": "推送的内容", // 必填 推送的内容
"title": "推送的标题", // 非必填 推送的标题
"type": 1 // 必填 推送类型 1:通知 2:不通知(自定义)
},
"pushForward": { // link 相关打开配置
"nextType": 2, // 必填 后续动作 - 0:打开首页 - 1:link跳转 - 2:scheme 跳转 - 3:Intent TODO二级分类
"scheme": "mlink://com.mob.mobpush.linkone", // 如果: nextType=2,必填 moblink功能的的scheme 例:mlink://com.mob.mobpush.linkone"
"schemeData": { // scheme参数 例:{"key1":"value1","key2":"value2",…}
"key1": "value1",
"key2": "value2"
}
}
}
*/
/*
{
"source": "webapi",
"appkey": "moba6b6c6d6",
"pushTarget": { // 推送目标
"target": 4, // 4:rid // 推送目标类型
"rids": [ // 推送rid集合
"c262bac10d05ec1c9b04126d"
]
},
"pushNotify": { // 推送展示细节配置
"plats": [ // 推送生效渠道- 1:android - 2:iOS - 8:harmony
1,2,8
],
"content": "推送的内容", // 推送内容
"title": "推送的标题", // 推送的标题
"type": 1
// pushNotify.type 是 推送类型 TODO二级分类
// - 1:通知
// - 2:自定义
},
"pushForward": { // link 相关打开配置
"nextType": 2, // 后续动作 - 0:打开首页 - 1:link跳转 - 2:scheme 跳转 - 3:Intent TODO二级分类
"scheme": "mlink://com.mob.mobpush.linkone", // scheme moblink功能的的scheme
"schemeDataList": [ // scheme参数 例:{"key1":"value1","key2":"value2",…}
{
"key": "schemekey",
"value": "schemevalue"
}
]
}
}
*/
}
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
**import javax.validation.Valid;**
import java.util.List;
@ApiOperation(value = "(单条)消息推送接口")
@PostMapping(Constants.SERVER_BASE_URL + "/message/send")
public JsonResult<Void> send(@RequestBody @Valid MsgSendReq msgSendReq) {
msgInfoService.send(msgSendReq);
return JsonResult.success();
}
1.2 @Validate
import org.springframework.validation.annotation.Validated;
@Validate @RequestBody StatReqVo statReqVo
package com.xx.assembler.web.stat;
import com.xx.assembler.orm.vo.req.stat.StatReqVo;
import com.xx.assembler.service.stat.StatService;
import com.xx.techless.boot.vo.JsonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* <p>
* 统计接口
* </p>
*
* @author 20004855
* @since 2023-11-17
*/
@Slf4j
@Api(value = "统计接口", tags = {"统计接口"})
@RestController
@RequestMapping("/stat")
public class StatController {
@Autowired
private StatService statService;
@ApiOperation(value = "统计结果")
@PostMapping("/result")
public JsonResult<Map<String, String>> statResult(@Validated @RequestBody StatReqVo statReqVo) {
return JsonResult.success(statService.statResult(statReqVo));
}
}
2. 参数校验
2.1 vo
@NotBlank(message = "开始时间不能为空。")
package com.xx.assembler.orm.vo.req.stat;
import com.xx.assembler.util.DateUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
/**
* 统计--入参
*
* @author 20004855
*/
@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("统计--入参")
public class StatReqVo {
/**
* 查询条件:开始时间(必填),结束时间(必填),是否只查询真实子应用(非必填)
*/
@ApiModelProperty("开始时间")
@NotBlank(message = "开始时间不能为空。")
@Pattern(regexp = "^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\\s+([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$", message = "请填写正确的start时间格式:" + DateUtil.pattern)
private String start;
@ApiModelProperty("结束时间")
@NotBlank(message = "结束时间不能为空。")
@Pattern(regexp = "^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\\s+([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$", message = "请填写正确的end时间格式:" + DateUtil.pattern)
private String end;
/**
* 是否只查询真实子应用(非必填)
* true:只查询真实子应用
* false/null:查询所有子应用
*/
@ApiModelProperty("是否只查询真实子应用:true:只查询真实子应用,false/null:查询所有子应用")
private Boolean isRealApp;
}
2.2 @Pattern正则校验
入参校验时间格式 “yyyy-MM-dd HH:mm:ss”
https://blog.csdn.net/x_christ1/article/details/108241000
@ApiModelProperty("开始时间")
@NotBlank(message = "开始时间不能为空。")
@Pattern(regexp = "^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\\s+([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$", message = "请填写正确的start时间格式:" + DateUtil.pattern)
private String start;
package com.xx.assembler.orm.vo.req.stat;
import com.xx.assembler.util.DateUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
/**
* 统计--入参
*
* @author 20004855
*/
@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("统计--入参")
public class StatReqVo {
/**
* 查询条件:开始时间(必填),结束时间(必填),是否只查询真实子应用(非必填)
*/
@ApiModelProperty("开始时间")
@NotBlank(message = "开始时间不能为空。")
@Pattern(regexp = "^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\\s+([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$", message = "请填写正确的start时间格式:" + DateUtil.pattern)
private String start;
@ApiModelProperty("结束时间")
@NotBlank(message = "结束时间不能为空。")
@Pattern(regexp = "^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\\s+([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$", message = "请填写正确的end时间格式:" + DateUtil.pattern)
private String end;
/**
* 是否只查询真实子应用(非必填)
* true:只查询真实子应用
* false/null:查询所有子应用
*/
@ApiModelProperty("是否只查询真实子应用:true:只查询真实子应用,false/null:查询所有子应用")
private Boolean isRealApp;
}
2.3 长度
@Length(max = 512, message = “默认值长度不能超过512,请修改数据库。”)
2.4 空值
@ApiModelProperty("主键ID")
@NotNull(message = "主键ID不允许为NULL")
private Long id;
@NotBlank(message = "语种标识不允许为空!")
@ApiModelProperty("语种标识")
private String key;
@NotEmpty(message = "语种不允许为空!")
@ApiModelProperty("选择的语种标识")
private List<String> language;
/**
* 多语种文案列表
*/
@ApiModelProperty("多语种文案列表")
@NotEmpty(message = "多语种文案列表不允许为空!")
@Valid
private List<MultiLanguageContentReq> contentList;
@Data
@ApiModel("多语言文案内容")
public class MultiLanguageContentReq {
/**
* 语种标识
*/
@ApiModelProperty("语种标识")
@NotBlank(message = "语种标识不允许为空!")
private String languageKey;
/**
* 文案内容
*/
@ApiModelProperty("文案内容")
@NotBlank(message = "文案内容不允许为空!")
private String content;
}
2.5 @RequestBody required 默认为空写法
@RequestBody(required = false)
@ApiOperation("定时任务--批量插入接口")
@PostMapping("/batchInsert")
public JsonResult<Boolean> batchInsert(@RequestBody(required = false) IndexDataReq indexDataReq) {
boolean flag = indexDataWorkOrderService.batchInsertPreMonthDeviceData(indexDataReq);
return JsonResult.success(flag);
}