From: Tang Cheng Date: Tue, 9 Jul 2019 08:30:30 +0000 (+0800) Subject: 增加了bean validation X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=9cc4331ec8366264fece7772330f0379114fae80;p=epayment%2Ffood_payapi.git 增加了bean validation --- diff --git a/common/build.gradle b/common/build.gradle index 3347b797..dcfba9ea 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -8,9 +8,16 @@ dependencies { implementation 'javax.validation:validation-api:2.0.1.Final' implementation 'javax.servlet:javax.servlet-api:4.0.1' implementation 'commons-beanutils:commons-beanutils:1.9.3' + implementation('org.springframework.boot:spring-boot-starter-validation:2.1.6.RELEASE') + + implementation 'org.hibernate:hibernate-validator:6.0.2.Final' + compile 'javax.el:javax.el-api:3.0.0' + compile 'org.glassfish.web:javax.el:2.2.6' compileOnly 'org.projectlombok:lombok:1.18.8' annotationProcessor 'org.projectlombok:lombok:1.18.8' implementation 'org.apache.commons:commons-lang3:3.9' + + testImplementation 'junit:junit:4.12' } \ No newline at end of file diff --git a/common/src/main/java/com/supwisdom/dlpay/api/annotation/Sex.java b/common/src/main/java/com/supwisdom/dlpay/api/annotation/Sex.java index 46978074..44fb69e7 100644 --- a/common/src/main/java/com/supwisdom/dlpay/api/annotation/Sex.java +++ b/common/src/main/java/com/supwisdom/dlpay/api/annotation/Sex.java @@ -1,12 +1,14 @@ package com.supwisdom.dlpay.api.annotation; -import com.supwisdom.dlpay.api.validator.StatusValidator; +import com.supwisdom.dlpay.api.util.SexTypes; +import com.supwisdom.dlpay.api.validator.SexValidator; +import com.supwisdom.dlpay.api.validator.UserStatusValidator; import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.*; -@Constraint(validatedBy = {StatusValidator.class}) +@Constraint(validatedBy = {SexValidator.class}) @Documented @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @@ -16,4 +18,6 @@ public @interface Sex { Class[] groups() default {}; Class[] payload() default {}; + + SexTypes value() default SexTypes.ALL; } diff --git a/common/src/main/java/com/supwisdom/dlpay/api/annotation/UserStatus.java b/common/src/main/java/com/supwisdom/dlpay/api/annotation/UserStatus.java index 3b034fb2..bbfbc6d4 100644 --- a/common/src/main/java/com/supwisdom/dlpay/api/annotation/UserStatus.java +++ b/common/src/main/java/com/supwisdom/dlpay/api/annotation/UserStatus.java @@ -1,15 +1,15 @@ package com.supwisdom.dlpay.api.annotation; -import com.supwisdom.dlpay.api.validator.StatusValidator; +import com.supwisdom.dlpay.api.validator.UserStatusValidator; import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.*; -@Constraint(validatedBy = {StatusValidator.class}) +@Constraint(validatedBy = {UserStatusValidator.class}) @Documented -@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD}) +@Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface UserStatus { String message() default "不正确的状态 , 应该是 'open', 'closed', 'losed' 其中之一"; diff --git a/common/src/main/java/com/supwisdom/dlpay/api/bean/CitizenCardPayinitParam.java b/common/src/main/java/com/supwisdom/dlpay/api/bean/CitizenCardPayinitParam.java index 79c51607..5b0e7dc0 100644 --- a/common/src/main/java/com/supwisdom/dlpay/api/bean/CitizenCardPayinitParam.java +++ b/common/src/main/java/com/supwisdom/dlpay/api/bean/CitizenCardPayinitParam.java @@ -7,8 +7,8 @@ import com.supwisdom.dlpay.api.util.DateUtil; import lombok.Getter; import lombok.Setter; -import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; +import javax.validation.constraints.Positive; import java.util.List; @Getter @@ -23,8 +23,8 @@ public class CitizenCardPayinitParam extends APIRequestParam { private String shopaccno; @Sign - @NotNull - @Min(value = 0L, message = "交易金额必须大于零") + @NotNull(message = "交易金额不能为空") + @Positive(message = "交易金额必须大于零") private Integer amount; private List feelist; diff --git a/common/src/main/java/com/supwisdom/dlpay/api/util/SexTypes.java b/common/src/main/java/com/supwisdom/dlpay/api/util/SexTypes.java new file mode 100644 index 00000000..380110fc --- /dev/null +++ b/common/src/main/java/com/supwisdom/dlpay/api/util/SexTypes.java @@ -0,0 +1,22 @@ +package com.supwisdom.dlpay.api.util; + +public enum SexTypes { + MALE("male"), + FEMALE("female"), + UNKNOWN("unknown"), + ALL(new SexTypes[]{MALE, FEMALE, UNKNOWN}); + + SexTypes(Object data) { + this.data = data; + } + + public String value() { + return this.data.toString(); + } + + public Object getData() { + return this.data; + } + + private Object data; +} diff --git a/common/src/main/java/com/supwisdom/dlpay/api/validator/MobileNumberValidator.java b/common/src/main/java/com/supwisdom/dlpay/api/validator/MobileNumberValidator.java index 0be737f1..8fc1a26a 100644 --- a/common/src/main/java/com/supwisdom/dlpay/api/validator/MobileNumberValidator.java +++ b/common/src/main/java/com/supwisdom/dlpay/api/validator/MobileNumberValidator.java @@ -10,6 +10,9 @@ public class MobileNumberValidator implements ConstraintValidator { - private final String[] ALL_TYPE = {"male", "female", "unknown"}; + private String[] sexTypes; @Override public boolean isValid(String value, ConstraintValidatorContext context) { - return Collections.singletonList(ALL_TYPE).contains(value); + return Arrays.asList(sexTypes).contains(value); } @Override public void initialize(Sex constraintAnnotation) { + if (constraintAnnotation.value().getData() instanceof SexTypes[]) { + SexTypes[] arrays = (SexTypes[]) constraintAnnotation.value().getData(); + sexTypes = new String[arrays.length]; + for (int i = 0; i < arrays.length; i++) { + sexTypes[i] = arrays[i].value(); + } + } else { + sexTypes = new String[]{constraintAnnotation.value().value()}; + } } } diff --git a/common/src/main/java/com/supwisdom/dlpay/api/validator/StatusValidator.java b/common/src/main/java/com/supwisdom/dlpay/api/validator/UserStatusValidator.java similarity index 86% rename from common/src/main/java/com/supwisdom/dlpay/api/validator/StatusValidator.java rename to common/src/main/java/com/supwisdom/dlpay/api/validator/UserStatusValidator.java index 84b8e5bb..b124f658 100644 --- a/common/src/main/java/com/supwisdom/dlpay/api/validator/StatusValidator.java +++ b/common/src/main/java/com/supwisdom/dlpay/api/validator/UserStatusValidator.java @@ -6,7 +6,7 @@ import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.Arrays; -public class StatusValidator implements ConstraintValidator { +public class UserStatusValidator implements ConstraintValidator { private final String[] ALL_STATUS = {"open", "closed", "losed"}; @Override diff --git a/common/src/test/java/com/supwisdom/dlpay/api/bean/CitizenCardPayinitParamTest.java b/common/src/test/java/com/supwisdom/dlpay/api/bean/CitizenCardPayinitParamTest.java new file mode 100644 index 00000000..f39af2ec --- /dev/null +++ b/common/src/test/java/com/supwisdom/dlpay/api/bean/CitizenCardPayinitParamTest.java @@ -0,0 +1,47 @@ +package com.supwisdom.dlpay.api.bean; + +import org.junit.Test; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; +import java.util.Set; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class CitizenCardPayinitParamTest { + + private Validator validator; + + @org.junit.Before + public void setUp() throws Exception { + ValidatorFactory factor = Validation.buildDefaultValidatorFactory(); + validator = factor.getValidator(); + } + + @Test + public void testCitizenPay() { + CitizenCardPayinitParam param = new CitizenCardPayinitParam(); + + Set> violations = validator.validate(param); + StringBuilder message = new StringBuilder(); + for (ConstraintViolation item : violations) { + message.append(item.getMessage()).append("\n"); + } + assertFalse(message.toString(), violations.isEmpty()); + } + + @Test + public void testOpenUserParam() { + OpenUserParam param = new OpenUserParam(); + param.setIdtype("12323"); + Set> violations = validator.validate(param); + StringBuilder message = new StringBuilder(); + for (ConstraintViolation item : violations) { + message.append(item.getMessage()).append("\n"); + } + assertFalse(message.toString(), violations.isEmpty()); + } +} \ No newline at end of file diff --git a/payapi-sdk/build.gradle b/payapi-sdk/build.gradle index 3523c69b..e0f0d0d8 100644 --- a/payapi-sdk/build.gradle +++ b/payapi-sdk/build.gradle @@ -59,6 +59,7 @@ dependencies { implementation 'javax.servlet:javax.servlet-api:4.0.1' compileOnly 'org.projectlombok:lombok:1.18.8' annotationProcessor 'org.projectlombok:lombok:1.18.8' + compile 'com.github.mwiede:feign-validation:1.0' testImplementation 'org.springframework:spring-test' testImplementation 'org.springframework.boot:spring-boot-test' diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/CitizenCardPayProxy.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/CitizenCardPayProxy.java index e46d5f71..e2042d95 100644 --- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/CitizenCardPayProxy.java +++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/CitizenCardPayProxy.java @@ -8,9 +8,12 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import javax.validation.Valid; + @FeignClient(value = "citizenCardPay", url = "${payapi.url}") public interface CitizenCardPayProxy { @RequestMapping(value = "/api/consume/citizencard/payinit", method = RequestMethod.GET) + @Valid CitizenPayResponse citizencardPayinit(@RequestBody CitizenCardPayinitParam param); @RequestMapping(value = "/api/consume/citizencard/payfinish", method = RequestMethod.GET) diff --git a/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/CitizenCardPayProxyTest.java b/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/CitizenCardPayProxyTest.java index 6a1037c0..812930d6 100644 --- a/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/CitizenCardPayProxyTest.java +++ b/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/CitizenCardPayProxyTest.java @@ -61,10 +61,11 @@ public class CitizenCardPayProxyTest { CitizenCardPayinitParam initParam = new CitizenCardPayinitParam(); initParam.setBillno("20190708172756000001"); - initParam.setCardNo("1231231213"); - initParam.setAmount(100); + initParam.setCardNo("20190619001"); + initParam.setAmount(0); initParam.setTransdate("20190708"); initParam.setTranstime("172713"); + initParam.setShopaccno("2000000038"); CitizenPayResponse payInit = citizenCardPayProxy.citizencardPayinit(initParam); assertThat("pay initialized " + payInit.getRetmsg() + payInit.getException(), payInit.getRetcode(), equalTo(0)); diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/advices.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/advices.kt index b2ff84d7..9fab5f0d 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/advices.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/advices.kt @@ -13,6 +13,8 @@ import org.aspectj.lang.annotation.Aspect import org.aspectj.lang.annotation.Pointcut import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Value +import org.springframework.http.HttpHeaders +import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity import org.springframework.security.core.context.SecurityContextHolder import org.springframework.stereotype.Component @@ -20,6 +22,13 @@ import org.springframework.web.bind.annotation.ExceptionHandler import org.springframework.web.bind.annotation.RestControllerAdvice import java.lang.reflect.UndeclaredThrowableException import javax.servlet.http.HttpServletRequest +import java.util.stream.Collectors +import org.springframework.validation.BindingResultUtils.getBindingResult +import java.util.LinkedHashMap +import org.springframework.web.context.request.WebRequest +import org.springframework.web.bind.MethodArgumentNotValidException +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler +import org.springframework.web.bind.annotation.ControllerAdvice @RestControllerAdvice("com.supwisdom.dlpay.api") @@ -43,6 +52,22 @@ class RestControllerAdvice { } } +@ControllerAdvice +class CustomGlobalExceptionHandler : ResponseEntityExceptionHandler() { + + // error handle for @Valid + override fun handleMethodArgumentNotValid(ex: MethodArgumentNotValidException, + headers: HttpHeaders, + status: HttpStatus, request: WebRequest): ResponseEntity { + val msg = ex.bindingResult.fieldErrors.joinToString(",") { + it?.defaultMessage ?: "" + } + return ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(300001, msg)) + + } +} + @Component @Aspect class RestControllerAspect { diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt index 9479e50f..0b726b72 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt @@ -18,6 +18,7 @@ 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 javax.validation.Valid @RestController @RequestMapping("/api/consume") @@ -39,7 +40,7 @@ class ConsumeAPIController { * ============================================================================ * */ @PostMapping("/queryresult") - fun queryDtlResult(@RequestBody param: QueryDtlResultParam): ResponseEntity { + fun queryDtlResult(@Valid @RequestBody param: QueryDtlResultParam): ResponseEntity { consumePayService.getTransactionMainDtl(param.refno, param.billno, param.shopaccno)?.let { return ResponseEntity.ok(ResponseBodyBuilder.create() .success(QueryTransDtlResponse(it.refno, it.outTradeNo, it.shopDtl.amount, @@ -126,7 +127,7 @@ class ConsumeAPIController { * ============================================================================ * */ @PostMapping("/citizencard/payinit") - fun citizencardPayinit(@RequestBody param: CitizenCardPayinitParam): ResponseEntity { + fun citizencardPayinit(@Valid @RequestBody param: CitizenCardPayinitParam): ResponseEntity { val person = userService.findPersonByIdentityCheckStatus(param.cardNo) if (consumePayService.checkShopPaytype(param.shopaccno, TradeDict.PAYTYPE_CITIZEN_CARD)) { @@ -197,7 +198,7 @@ class ConsumeAPIController { * ============================================================================ * */ @PostMapping("/citizencard/payfinish") - fun citizencardPayinit(@RequestBody param: CitizenCardPayfinishParam): ResponseEntity { + fun citizencardPayinit(@Valid @RequestBody param: CitizenCardPayfinishParam): ResponseEntity { val code = transactionService.wip(param.refno).let { CallService.CallCitizenCardPay( consumePayService.getPaytypeConfig(TradeDict.PAYTYPE_CITIZEN_CARD, it.shopDtl.shopaccno), @@ -225,7 +226,7 @@ class ConsumeAPIController { * ============================================================================ * */ @PostMapping("/paycancel") - fun payCancel(@RequestBody param: ConsumePayCancelParam): ResponseEntity { + fun payCancel(@Valid @RequestBody param: ConsumePayCancelParam): ResponseEntity { consumePayService.getTransactionMainDtl(param.refno, param.billno, param.shopaccno)?.let { val builder = TransactionBuilder().apply { setTransInfo(param.transdate, param.transtime, it.transCode, it.sourceType) @@ -249,7 +250,7 @@ class ConsumeAPIController { * ============================================================================ * */ @PostMapping("/payrefund") - fun payRefund(@RequestBody param: ConsumePayRefundParam): ResponseEntity { + fun payRefund(@Valid @RequestBody param: ConsumePayRefundParam): ResponseEntity { consumePayService.getTransactionMainDtl(param.refno, param.billno, param.shopaccno)?.let { val builder = TransactionBuilder().apply { setTransInfo(param.transdate, param.transtime, it.transCode, it.sourceType)