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
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)
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
+
+ SexTypes value() default SexTypes.ALL;
}
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' 其中之一";
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
private String shopaccno;
@Sign
- @NotNull
- @Min(value = 0L, message = "交易金额必须大于零")
+ @NotNull(message = "交易金额不能为空")
+ @Positive(message = "交易金额必须大于零")
private Integer amount;
private List<ConsumeFeetype> feelist;
--- /dev/null
+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;
+}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
+ if (value == null) {
+ return true;
+ }
return MobileNumberCheck.isPhone(value);
}
import com.supwisdom.dlpay.api.annotation.Sex;
+import com.supwisdom.dlpay.api.util.SexTypes;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
-import java.util.Collections;
+import java.util.Arrays;
public class SexValidator implements ConstraintValidator<Sex, String> {
- 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()};
+ }
}
}
import javax.validation.ConstraintValidatorContext;
import java.util.Arrays;
-public class StatusValidator implements ConstraintValidator<UserStatus, String> {
+public class UserStatusValidator implements ConstraintValidator<UserStatus, String> {
private final String[] ALL_STATUS = {"open", "closed", "losed"};
@Override
--- /dev/null
+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<ConstraintViolation<CitizenCardPayinitParam>> violations = validator.validate(param);
+ StringBuilder message = new StringBuilder();
+ for (ConstraintViolation<CitizenCardPayinitParam> 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<ConstraintViolation<OpenUserParam>> violations = validator.validate(param);
+ StringBuilder message = new StringBuilder();
+ for (ConstraintViolation<OpenUserParam> item : violations) {
+ message.append(item.getMessage()).append("\n");
+ }
+ assertFalse(message.toString(), violations.isEmpty());
+ }
+}
\ No newline at end of file
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'
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)
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));
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
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")
}
}
+@ControllerAdvice
+class CustomGlobalExceptionHandler : ResponseEntityExceptionHandler() {
+
+ // error handle for @Valid
+ override fun handleMethodArgumentNotValid(ex: MethodArgumentNotValidException,
+ headers: HttpHeaders,
+ status: HttpStatus, request: WebRequest): ResponseEntity<Any> {
+ val msg = ex.bindingResult.fieldErrors.joinToString(",") {
+ it?.defaultMessage ?: ""
+ }
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(300001, msg))
+
+ }
+}
+
@Component
@Aspect
class RestControllerAspect {
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")
* ============================================================================
* */
@PostMapping("/queryresult")
- fun queryDtlResult(@RequestBody param: QueryDtlResultParam): ResponseEntity<Any> {
+ fun queryDtlResult(@Valid @RequestBody param: QueryDtlResultParam): ResponseEntity<Any> {
consumePayService.getTransactionMainDtl(param.refno, param.billno, param.shopaccno)?.let {
return ResponseEntity.ok(ResponseBodyBuilder.create()
.success(QueryTransDtlResponse(it.refno, it.outTradeNo, it.shopDtl.amount,
* ============================================================================
* */
@PostMapping("/citizencard/payinit")
- fun citizencardPayinit(@RequestBody param: CitizenCardPayinitParam): ResponseEntity<Any> {
+ fun citizencardPayinit(@Valid @RequestBody param: CitizenCardPayinitParam): ResponseEntity<Any> {
val person = userService.findPersonByIdentityCheckStatus(param.cardNo)
if (consumePayService.checkShopPaytype(param.shopaccno, TradeDict.PAYTYPE_CITIZEN_CARD)) {
* ============================================================================
* */
@PostMapping("/citizencard/payfinish")
- fun citizencardPayinit(@RequestBody param: CitizenCardPayfinishParam): ResponseEntity<Any> {
+ fun citizencardPayinit(@Valid @RequestBody param: CitizenCardPayfinishParam): ResponseEntity<Any> {
val code = transactionService.wip(param.refno).let {
CallService.CallCitizenCardPay(
consumePayService.getPaytypeConfig(TradeDict.PAYTYPE_CITIZEN_CARD, it.shopDtl.shopaccno),
* ============================================================================
* */
@PostMapping("/paycancel")
- fun payCancel(@RequestBody param: ConsumePayCancelParam): ResponseEntity<Any> {
+ fun payCancel(@Valid @RequestBody param: ConsumePayCancelParam): ResponseEntity<Any> {
consumePayService.getTransactionMainDtl(param.refno, param.billno, param.shopaccno)?.let {
val builder = TransactionBuilder().apply {
setTransInfo(param.transdate, param.transtime, it.transCode, it.sourceType)
* ============================================================================
* */
@PostMapping("/payrefund")
- fun payRefund(@RequestBody param: ConsumePayRefundParam): ResponseEntity<Any> {
+ fun payRefund(@Valid @RequestBody param: ConsumePayRefundParam): ResponseEntity<Any> {
consumePayService.getTransactionMainDtl(param.refno, param.billno, param.shopaccno)?.let {
val builder = TransactionBuilder().apply {
setTransInfo(param.transdate, param.transtime, it.transCode, it.sourceType)