@Getter
public class PolicyRequestDto {
@Getter
@Builder
@AllArgsConstructor
public static class InsertPolicyRequest {
@NotNull(message = "need typeNo")
private Integer typeNo;
private String typeDescription;
private Long volume;
private Integer retryCnt;
private Integer authTime;
public InsertPolicyRequest insertValidate() {
PolicyTypeEnum policyEnumList = new PolicyTypeEnum();
Stream<Integer> volumeList = policyEnumList.getVolumeList().stream();
Stream<Integer> authTimeList = policyEnumList.getAuthTimeList().stream();
Stream<Integer> retryCntList = policyEnumList.getRetryCntList().stream();
switch (Objects.requireNonNull(typeNo, "no typeNo")) {
case 0 :
// case 0
break;
case 1 :
// case 1
break;
case 2 :
// case 2
break;
default : throw new IllegalArgumentException("Error");
}
return this;
}
public PolicyEntity toEntity () {
return PolicyEntity.builder()
.typeNo(typeNo)
.volume(volume)
.retryCnt(retryCnt)
.authTime(authTime)
.build();
}
}
}
public PolicyResponseDto.CommonResponse addWifiServicePolicy(@Valid PolicyRequestDto.InsertPolicyRequest insertRequest) {
insertRequest.insertValidate();
PolicyEntity policyEntity = insertRequest.toEntity();
...
return ...
}
如果該服務所需的驗證無法使用 @Validated 注釋完成,是否可以在 DTO 中完成?
目前,驗證程序處于根據輸入引數(例如代碼)而變化的級別。該服務希望僅使用已通過此驗證的資料執行業務邏輯。驗證代碼放在每個方法的頂部很煩人,但我認為這是必要的代碼。
在 DTO 中這樣做有什么問題嗎?
ps 我想做一個獨立于控制器的服務物件,這樣即使只分離服務也沒有問題。
uj5u.com熱心網友回復:
您可以創建自定義驗證注釋。
@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MyConstraintValidator.class)
public @interface MyConstraint {
String message() default "default error message";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
此注釋適用于欄位或方法級別。驗證器必須實作ConstraintValidator。
public class MyConstraintValidator implements ConstraintValidator<MyConstraint, Integer> {
@Override
public boolean isValid(Integer typeNo, ConstraintValidatorContext context) {
PolicyTypeEnum policyEnumList = new PolicyTypeEnum();
Stream<Integer> volumeList = policyEnumList.getVolumeList().stream();
Stream<Integer> authTimeList = policyEnumList.getAuthTimeList().stream();
Stream<Integer> retryCntList = policyEnumList.getRetryCntList().stream();
switch (Objects.requireNonNull(typeNo, "no typeNo")) {
case 0 :
// case 0
break;
case 1 :
// case 1
break;
case 2 :
// case 2
break;
default :
return false;
}
return true;
}
}
如果您需要訪問其他欄位的資料,則需要更新注釋以適用于型別級別 - @Target( { ElementType.TYPE }),并相應地更改驗證器以使用型別 - InsertPolicyRequest:
public class MyConstraintValidator implements ConstraintValidator<MyConstraint, InsertPolicyRequest> {
@Override
public boolean isValid(InsertPolicyRequest request, ConstraintValidatorContext context) {
PolicyTypeEnum policyEnumList = new PolicyTypeEnum();
Stream<Integer> volumeList = policyEnumList.getVolumeList().stream();
Stream<Integer> authTimeList = policyEnumList.getAuthTimeList().stream();
Stream<Integer> retryCntList = policyEnumList.getRetryCntList().stream();
switch (Objects.requireNonNull(request.getTypeNo(), "no typeNo")) {
case 0 :
// case 0
break;
case 1 :
// case 1
break;
case 2 :
// case 2
break;
default :
return false;
}
return true;
}
}
也請檢查本指南。
編輯:只需一個注釋即可。有一個介面負責提取公共資料,我們稱之為PolicyRequestData.
public interface PolicyRequestData {
Integer getTypeNo();
String getTypeName();
}
然后從上面更改注釋以在型別級別上作業并將其重命名為MyCommonConstraint. 更新ConstraintValidator以使用PolicyRequestData而不是具體類。
public class MyCommonConstraintValidator implements ConstraintValidator<MyCommonConstraint, PolicyRequestData> {
@Override
public boolean isValid(PolicyRequestData request, ConstraintValidatorContext constraintValidatorContext) {
PolicyTypeEnum policyEnumList = new PolicyTypeEnum();
Stream<Integer> volumeList = policyEnumList.getVolumeList().stream();
Stream<Integer> authTimeList = policyEnumList.getAuthTimeList().stream();
Stream<Integer> retryCntList = policyEnumList.getRetryCntList().stream();
switch (Objects.requireNonNull(request.getTypeNo(), "no typeNo")) {
case 0 :
// case 0
break;
case 1 :
// case 1
break;
case 2 :
// case 2
break;
default :
return false;
}
return true;
}
}
像這樣,注釋將適用于任何實作PolicyRequestData.
@MyCommonConstraint
public class InsertPolicyRequest implements PolicyRequestData {
private Integer typeNo;
private String typeName;
@Override
public Integer getTypeNo() {
return this.typeNo;
}
@Override
public String getTypeName() {
return this.typeName;
}
//setters, if needed
}
UpdatePolicyRequest是完全一樣的,除了類名。
如果您需要驗證具有特定資料的類,請擴展介面。
public interface SpecificPolicyRequestData extends PolicyRequestData {
String getOtherData();
}
讓特定的類實作它并創建注釋以使用此介面。然后在類上應用兩個注釋(如果需要兩個驗證):
@MyCommonConstraint
@MySpecificConstraint
public class SomeSpecificPolicyRequest implements SpecificPolicyRequestData {
@Override
public Integer getTypeNo() {
return null;
}
@Override
public String getTypeName() {
return null;
}
@Override
public String getOtherData() {
return null;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/462064.html
