精华内容
下载资源
问答
  • Dubbo参数验证

    千次阅读 2019-09-02 16:10:43
    参数验证功能 [备注1]是基于 JSR303 实现的,用户只需标识 JSR303 标准的验证 annotation,并通过声明 filter 来实现验证 [备注2]。 Maven 依赖 <dependency> <groupId>javax.validation</...

    参数验证功能 [备注1] 是基于 JSR303 实现的,用户只需标识 JSR303 标准的验证 annotation,并通过声明 filter 来实现验证 [备注2] 。

    Maven 依赖

    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>1.0.0.GA</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>4.2.0.Final</version>
    </dependency>
    

     

    示例

    参数标注示例

    import java.io.Serializable;
    import java.util.Date;
     
    import javax.validation.constraints.Future;
    import javax.validation.constraints.Max;
    import javax.validation.constraints.Min;
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Past;
    import javax.validation.constraints.Pattern;
    import javax.validation.constraints.Size;
     
    public class ValidationParameter implements Serializable {
        private static final long serialVersionUID = 7158911668568000392L;
     
        @NotNull // 不允许为空
        @Size(min = 1, max = 20) // 长度或大小范围
        private String name;
     
        @NotNull(groups = ValidationService.Save.class) // 保存时不允许为空,更新时允许为空 ,表示不更新该字段
        @Pattern(regexp = "^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$")
        private String email;
     
        @Min(18) // 最小值
        @Max(100) // 最大值
        private int age;
     
        @Past // 必须为一个过去的时间
        private Date loginDate;
     
        @Future // 必须为一个未来的时间
        private Date expiryDate;
     
        。。。getter setter
    }
    

    分组验证示例

    public interface ValidationService { // 缺省可按服务接口区分验证场景,如:@NotNull(groups = ValidationService.class)   
        @interface Save{} // 与方法同名接口,首字母大写,用于区分验证场景,如:@NotNull(groups = ValidationService.Save.class),可选
        void save(ValidationParameter parameter);
        void update(ValidationParameter parameter);
    }
    

    关联验证示例

    import javax.validation.GroupSequence;
     
    public interface ValidationService {   
        @GroupSequence(Update.class) // 同时验证Update组规则
        @interface Save{}
        void save(ValidationParameter parameter);
     
        @interface Update{} 
        void update(ValidationParameter parameter);
    }
    

    参数验证示例

    import javax.validation.constraints.Min;
    import javax.validation.constraints.NotNull;
     
    public interface ValidationService {
        void save(@NotNull ValidationParameter parameter); // 验证参数不为空
        void delete(@Min(1) int id); // 直接对基本类型参数验证
    }
    

    配置

    在客户端验证参数

    <dubbo:reference id="validationService" interface="org.apache.dubbo.examples.validation.api.ValidationService" validation="true" />
    

    在服务器端验证参数

    <dubbo:service interface="org.apache.dubbo.examples.validation.api.ValidationService" ref="validationService" validation="true" />
    

    验证异常信息

    import javax.validation.ConstraintViolationException;
    import javax.validation.ConstraintViolationException;
     
    import org.springframework.context.support.ClassPathXmlApplicationContext;
     
    import org.apache.dubbo.examples.validation.api.ValidationParameter;
    import org.apache.dubbo.examples.validation.api.ValidationService;
    import org.apache.dubbo.rpc.RpcException;
     
    public class ValidationConsumer {   
        public static void main(String[] args) throws Exception {
            String config = ValidationConsumer.class.getPackage().getName().replace('.', '/') + "/validation-consumer.xml";
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(config);
            context.start();
            ValidationService validationService = (ValidationService)context.getBean("validationService");
            // Error
            try {
                parameter = new ValidationParameter();
                validationService.save(parameter);
                System.out.println("Validation ERROR");
            } catch (RpcException e) { // 抛出的是RpcException
                ConstraintViolationException ve = (ConstraintViolationException) e.getCause(); // 里面嵌了一个ConstraintViolationException
                Set<ConstraintViolation<?>> violations = ve.getConstraintViolations(); // 可以拿到一个验证错误详细信息的集合
                System.out.println(violations);
            }
        } 
    }
    

     

    备注

    1. 自 2.1.0 版本开始支持, 如何使用可以参考 dubbo 项目中的示例代码 ↩︎

    2. 验证方式可扩展,扩展方式参见开发者手册中的验证扩展 ↩︎

     

    展开全文
  • SpringBoot里参数校验/参数验证

    万次阅读 多人点赞 2019-05-08 13:47:56
    不方便的地方是,不能通过捕获异常的方式,向前端返回统一的、自定义格式的响应参数。 3、方法参数校验 @GetMapping("/validate1") @ResponseBody public String validate1( @Size(min = 1,max = 10,message = ...

    1、前言

    在控制器类的方法里自己写校验逻辑代码当然也可以,只是代码比较丑陋,有点“low”。业界有更好的处理方法,分别阐述如下。

    2、PathVariable校验

    @GetMapping("/path/{group:[a-zA-Z0-9_]+}/{userid}")
    @ResponseBody
    public String path(@PathVariable("group") String group, @PathVariable("userid") Integer userid) {
        return group + ":" + userid;
    }
    

    用法是:路径变量:正则表达式。当请求URI不满足正则表达式时,客户端将收到404错误码。不方便的地方是,不能通过捕获异常的方式,向前端返回统一的、自定义格式的响应参数。

    3、方法参数校验

    @GetMapping("/validate1")
    @ResponseBody
    public String validate1(
            @Size(min = 1,max = 10,message = "姓名长度必须为1到10")@RequestParam("name") String name,
            @Min(value = 10,message = "年龄最小为10")@Max(value = 100,message = "年龄最大为100") @RequestParam("age") Integer age) {
        return "validate1";
    }
    

    如果前端传递的参数不满足规则,则抛出异常。注解Size、Min、Max来自validation-api.jar,更多注解参见相关标准小节。

    4、表单对象/VO对象校验

    当参数是VO时,可以在VO类的属性上添加校验注解。

    public class User {
        @Size(min = 1,max = 10,message = "姓名长度必须为1到10")
        private String name;
    
        @NotEmpty
        private String firstName;
    
        @Min(value = 10,message = "年龄最小为10")@Max(value = 100,message = "年龄最大为100")
        private Integer age;
    
        @Future
        @JSONField(format="yyyy-MM-dd HH:mm:ss")
        private Date birth;
        。。。
    }
    

    其中,Future注解要求必须是相对当前时间来讲“未来的”某个时间。

    @PostMapping("/validate2")
    @ResponseBody
    public User validate2(@Valid @RequestBody User user){
        return user;
    }
    

    5、自定义校验规则

    5.1 自定义注解校验

    需要自定义一个注解类和一个校验类。

    import javax.validation.Constraint;
    import javax.validation.Payload;
    import java.lang.annotation.*;
    
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.PARAMETER,ElementType.FIELD})
    @Constraint(validatedBy = FlagValidatorClass.class)
    public @interface FlagValidator {
        // flag的有效值,多个使用,隔开
        String values();
    
        // flag无效时的提示内容
        String message() default "flag必须是预定义的那几个值,不能随便写";
    
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    }
    
    import javax.validation.ConstraintValidator;
    import javax.validation.ConstraintValidatorContext;
    
    public class FlagValidatorClass implements ConstraintValidator<FlagValidator,Object> {
        /**
         * FlagValidator注解规定的那些有效值
         */
        private String values;
    
        @Override
        public void initialize(FlagValidator flagValidator) {
            this.values = flagValidator.values();
        }
    
        /**
         * 用户输入的值,必须是FlagValidator注解规定的那些值其中之一。
         * 否则,校验不通过。
         * @param value 用户输入的值,如从前端传入的某个值
         */
        @Override
        public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
            // 切割获取值
            String[] value_array = values.split(",");
            Boolean isFlag = false;
    
            for (int i = 0; i < value_array.length; i++){
                // 存在一致就跳出循环
                if (value_array[i] .equals(value)){
                    isFlag = true; break;
                }
            }
    
            return isFlag;
        }
    }
    

    使用我们自定义的注解:

    public class User {
        // 前端传入的flag值必须是1或2或3,否则校验失败
        @FlagValidator(values = "1,2,3")
        private String flag ;
        。。。
    }
    

    5.2 分组校验

    import org.hibernate.validator.constraints.Length;
    import javax.validation.constraints.Min;
    import javax.validation.constraints.NotNull;
    
    public class Resume {
        public interface Default {
        }
    
        public interface Update {
        }
    
        @NotNull(message = "id不能为空", groups = Update.class)
        private Long id;
    
        @NotNull(message = "名字不能为空", groups = Default.class)
        @Length(min = 4, max = 10, message = "name 长度必须在 {min} - {max} 之间", groups = Default.class)
        private String name;
    
        @NotNull(message = "年龄不能为空", groups = Default.class)
        @Min(value = 18, message = "年龄不能小于18岁", groups = Default.class)
        private Integer age;
        。。。
    }
    
        /**
         * 使用Defaul分组进行验证
         * @param resume
         * @return
         */
        @PostMapping("/validate5")
        public String addUser(@Validated(value = Resume.Default.class) @RequestBody Resume resume) {
            return "validate5";
        }
    
        /**
         * 使用Default、Update分组进行验证
         * @param resume
         * @return
         */
        @PutMapping("/validate6")
        public String updateUser(@Validated(value = {Resume.Update.class, Resume.Default.class}) @RequestBody Resume resume) {
            return "validate6";
        }
    

    建立了两个分组,名称分别为Default、Update。POST方法提交时使用Defaut分组的校验规则,PUT方法提交时同时使用两个分组规则。

    6、异常拦截器

    通过设置全局异常处理器,统一向前端返回校验失败信息。

    import com.scj.springbootdemo.WebResult;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.util.CollectionUtils;
    import org.springframework.validation.ObjectError;
    import org.springframework.web.bind.MethodArgumentNotValidException;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.validation.ConstraintViolation;
    import javax.validation.ConstraintViolationException;
    import java.util.List;
    import java.util.Set;
    
    /**
     * 全局异常处理器
     */
    @ControllerAdvice
    public class GlobalExceptionHandler {
    
        private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    
        /**
         * 用来处理bean validation异常
         * @param ex
         * @return
         */
        @ExceptionHandler(ConstraintViolationException.class)
        @ResponseBody
        public  WebResult resolveConstraintViolationException(ConstraintViolationException ex){
            WebResult errorWebResult = new WebResult(WebResult.FAILED);
            Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
            if(!CollectionUtils.isEmpty(constraintViolations)){
                StringBuilder msgBuilder = new StringBuilder();
                for(ConstraintViolation constraintViolation :constraintViolations){
                    msgBuilder.append(constraintViolation.getMessage()).append(",");
                }
                String errorMessage = msgBuilder.toString();
                if(errorMessage.length()>1){
                    errorMessage = errorMessage.substring(0,errorMessage.length()-1);
                }
                errorWebResult.setInfo(errorMessage);
                return errorWebResult;
            }
            errorWebResult.setInfo(ex.getMessage());
            return errorWebResult;
        }
    
        @ExceptionHandler(MethodArgumentNotValidException.class)
        @ResponseBody
        public WebResult resolveMethodArgumentNotValidException(MethodArgumentNotValidException ex){
            WebResult errorWebResult = new WebResult(WebResult.FAILED);
            List<ObjectError>  objectErrors = ex.getBindingResult().getAllErrors();
            if(!CollectionUtils.isEmpty(objectErrors)) {
                StringBuilder msgBuilder = new StringBuilder();
                for (ObjectError objectError : objectErrors) {
                    msgBuilder.append(objectError.getDefaultMessage()).append(",");
                }
                String errorMessage = msgBuilder.toString();
                if (errorMessage.length() > 1) {
                    errorMessage = errorMessage.substring(0, errorMessage.length() - 1);
                }
                errorWebResult.setInfo(errorMessage);
                return errorWebResult;
            }
            errorWebResult.setInfo(ex.getMessage());
            return errorWebResult;
        }
    }
    
    

    7、相关标准

    JSR 303 是Bean验证的规范 ,Hibernate Validator 是该规范的参考实现,它除了实现规范要求的注解外,还额外实现了一些注解。
    validation-api-1.1.0.jar 包括如下约束注解:

    约束注解说明
    @AssertFalse被注释的元素必须为 false
    @AssertTrue被注释的元素必须为 true
    @DecimalMax(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
    @DecimalMin(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
    @Digits (integer, fraction)被注释的元素必须是一个数字,其值必须在可接受的范围内
    @Null被注释的元素必须为 null
    @NotNull被注释的元素必须不为 null
    @Min(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
    @Max(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
    @Size(max, min)被注释的元素的大小必须在指定的范围内
    @Past被注释的元素必须是一个过去的日期
    @Future被注释的元素必须是一个将来的日期
    @Pattern(value)被注释的元素必须符合指定的正则表达式

    hibernate-validator-5.3.6.jar 包括如下约束注解:

    约束注解说明
    @Email被注释的元素必须是电子邮箱地址
    @Length被注释的字符串的大小必须在指定的范围内
    @NotBlank被注释的字符串的必须非空
    @NotEmpty被注释的字符串、集合、Map、数组必须非空
    @Range被注释的元素必须在合适的范围内
    @SafeHtml被注释的元素必须是安全Html
    @URL被注释的元素必须是有效URL

    8、参数校验原理

    这篇文章 写得比较深入,我没有太理解。

    9、本文源码

    公司不让上传源码到GitHub,可以参加这篇文章

    10、同时校验2个或更多个字段/参数

    常见的场景之一是,查询某信息时要输入开始时间和结束时间。显然,结束时间要≥开始时间。可以在查询VO类上使用自定义注解,下面的例子来自这里。划重点:@ValidAddress使用在类上。

    @ValidAddress
    public class Address {
    
        @NotNull
        @Size(max = 50)
        private String street1;
    
        @Size(max = 50)
        private String street2;
    
        @NotNull
        @Size(max = 10)
        private String zipCode;
    
        @NotNull
        @Size(max = 20)
        private String city;
    
        @Valid
        @NotNull
        private Country country;
    
        // Getters and setters
    }
    
    public class Country {
    
        @NotNull
        @Size(min = 2, max = 2)
        private String iso2;
    
        // Getters and setters
    }
    
    @Documented
    @Target(TYPE)
    @Retention(RUNTIME)
    @Constraint(validatedBy = { MultiCountryAddressValidator.class })
    public @interface ValidAddress {
    
        String message() default "{com.example.validation.ValidAddress.message}";
    
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    }
    
    public class MultiCountryAddressValidator 
           implements ConstraintValidator<ValidAddress, Address> {
    
        public void initialize(ValidAddress constraintAnnotation) {
    
        }
    
        @Override
        public boolean isValid(Address address, 
                               ConstraintValidatorContext constraintValidatorContext) {
    
            Country country = address.getCountry();
            if (country == null || country.getIso2() == null || address.getZipCode() == null) {
                return true;
            }
    
            switch (country.getIso2()) {
                case "FR":
                    return // Check if address.getZipCode() is valid for France
                case "GR":
                    return // Check if address.getZipCode() is valid for Greece
                default:
                    return true;
            }
        }
    }
    
    展开全文
  • webapi 源码 版本控制 压缩 参数验证

    热门讨论 2016-04-10 15:54:33
    webapi 源码 版本控制 压缩 参数验证
  • context.ModelState.IsValid) {//传入参数验证 string erro = ""; foreach (var modelState in context.ModelState.Values) { foreach (var error in modelState.Errors) { erro = error.ErrorMessage; if (erro == ...

     

    上代码,根据具体情况进行修改。

    public class WebFilterAttribute : Attribute, IAuthorizationFilter, IActionFilter, IExceptionFilter
        {
            static private log4net.ILog log = log4net.LogManager.GetLogger(typeof(WebFilterAttribute));
    
            /// <summary>
            /// 身份验证过滤
            /// </summary>
            /// <param name="context"></param>
            public void OnAuthorization(AuthorizationFilterContext context)
            {
                var actionDesc = context.ActionDescriptor;
                var routeData = new RouteData(context);
    
                //if (UserDataHelper.User == null)
                //{//开发阶段自动登录
                //    UserDataHelper.User = new LoginUser
                //    {
                //        user_name = "admin",
                //        company_uuid = "9ba95e6e-6dc1-46db-9055-944a9eabe428",
                //        tel_phone = "131"
                //    };
                //}
    
                if (actionDesc.FilterDescriptors.Any(s => s.Filter.ToString() == typeof(NoLoginAttribute).ToString()))
                {//如果不用验证登录 直接返回
                    return;
                }
    
                if (UserDataHelper.CheckLogin() == false)
                {//登录验证 : 没有登录
                    var result = new ResultBase { Code = ResultCode.NoLogin, Message = "没有登录" };
                    context.Result = new JsonResult(result);
                    log.Info("[" + routeData.ApiPath + "] 提示:" + result.Message);
                    return;
                }
    
                if (actionDesc.FilterDescriptors.Any(s => s.Filter.ToString() == typeof(NoPermissAttribute).ToString()))
                {//如果不用验证权限 直接返回
                    return;
                }
    
    
                if (UserDataHelper.CheckPermissions(routeData.ActionName, routeData.ControllerName) == false)
                {//验证 权限
                    var result = new ResultBase { Code = ResultCode.NoPermission, Message = "没有授权" };
                    context.Result = new JsonResult(result);
                    log.Info("[" + routeData.ApiPath + "] 提示:" + result.Message);
                    return;
                }
            }
    
            /// <summary>
            /// 异常返回
            /// 程序发生异常后 返回统一格式
            /// </summary>
            /// <param name="actionContext"></param>
            public void OnException(ExceptionContext context)
            {
                var routeData = new RouteData(context);
    
                var ex = context.Exception;
                if (ex.InnerException != null)
                {
                    ex = ex.GetBaseException();
                }
    
                var exceptionResult = new ResultBase();
                exceptionResult.Code = ResultCode.Failed;
                exceptionResult.Message = ex.Message;
                context.Result = new JsonResult(exceptionResult);
    
                log.Info("[" + routeData.ApiPath + "] 返回:" + JsonConvert.SerializeObject(exceptionResult));
                log.Error("[" + routeData.ApiPath + "] 异常:" + ex.ToString());
            }
    
    
            /// <summary>
            /// api调用后执行 
            /// </summary>
            /// <param name="context"></param>
            public void OnActionExecuted(ActionExecutedContext context)
            {
                if (context.Result != null)
                {
                    var routeData = new RouteData(context);
                    if (context.Result is ObjectResult)
                    {
                        log.Info("[" + routeData.ApiPath + "] 返回:" + JsonConvert.SerializeObject(((ObjectResult)context.Result).Value));
                    }
                    if (context.Result is JsonResult)
                    {
                        log.Info("[" + routeData.ApiPath + "] 返回:" + JsonConvert.SerializeObject(((JsonResult)context.Result).Value));
                    }
                }
            }
    
            /// <summary>
            /// api 调用前执行 用来验证参数
            /// </summary>
            /// <param name="context"></param>
            public void OnActionExecuting(ActionExecutingContext context)
            {
                var routeData = new RouteData(context);
    
                string log_str = "";//打印接收参数
                foreach (var item in context.ActionArguments)
                {
                    log_str += item.Key + " = " + JsonConvert.SerializeObject(item.Value) + "    |   ";
                }
                log_str = (log_str == "" ? "无参数" : log_str);
                log.Info("[" + routeData.ApiPath + "] 接收:" + log_str);
    
    
                if (!context.ModelState.IsValid)
                {//传入参数验证
                    string erro = "";
                    foreach (var modelState in context.ModelState.Values)
                    {
                        foreach (var error in modelState.Errors)
                        {
                            erro = error.ErrorMessage;
                            if (erro == "") erro = error.Exception == null ? "" : error.Exception.Message;
                            //  LogHelper.Warn(actionContext.Request.RequestUri.LocalPath + " 传参错误:" + (error.Exception == null ? erro : error.Exception.ToString()));
                            break;
                        }
                    }
    
                    var ret = new ResultBase { Code = ResultCode.ParameterError };
                    ret.Message = (!string.IsNullOrWhiteSpace(erro)) ? erro : "参数错误";
                    if (ret.Message != "")
                    {
                        context.Result = new JsonResult(ret);
                    }
                }
            }
    
    
            /// <summary>
            /// 内部类 路由信息
            /// </summary>
            private class RouteData
            {
                /// <summary>
                /// action名称
                /// </summary>
                public string ActionName { get; set; }
    
                /// <summary>
                /// 控制器名称
                /// </summary>
                public string ControllerName { get; set; }
    
                /// <summary>
                /// Api路径
                /// </summary>
                public string ApiPath { get; set; }
    
                public RouteData(ActionContext context)
                {
                    var desc = context.ActionDescriptor;
                    ActionName = desc.RouteValues["action"].ToLower();
                    ControllerName = desc.RouteValues["controller"].ToLower();
                    ApiPath = ControllerName + "/" + ActionName;
                }
    
            }
    
        }

    用户登录信息类:

     public class UserDataHelper
        {
            static RoleBLL roleBLL = new RoleBLL();
            /// <summary>
            /// 保存当前登录用户信息
            /// </summary>
            public static LoginUser User
            {
                get
                {
                    StringValues SessionKey = "";
                    if (HttpContext.Current.Request.Headers.TryGetValue("SessionKey", out SessionKey) == false)
                    {
                        SessionKey = HttpContext.Current.Request.Cookies["SessionKey"];
                    }
                    if (!string.IsNullOrEmpty(SessionKey))
                    {
                        int expireAt = int.Parse(ConfigurationManager.AppSettings["expire_entry_at"]);
    
                        var ret = CacheManage.GetUser(SessionKey, expireAt);
    
                        string testSessionKey = "88888888";
                        if (ret == null && SessionKey == testSessionKey)
                        {
                            AccountBLL accountBLL = new AccountBLL();
                            var user = accountBLL.Login("admin");
                            user.SessionKey = testSessionKey;
    
                            CacheManage.SaveUser(testSessionKey, user, expireAt);
    
                            ret = CacheManage.GetUser(testSessionKey, expireAt);
                        }
                        return ret;
                    }
                    return null;
                }
                set
                {
                    int expireAt = int.Parse(ConfigurationManager.AppSettings["expire_entry_at"]);
                    CacheManage.SaveUser(value.SessionKey, value, expireAt);
                }
            }
    
            public static LoginUser GetLoginUser(string SessionKey)
            {
                int expireAt = int.Parse(ConfigurationManager.AppSettings["expire_entry_at"]);
                return CacheManage.GetUser(SessionKey, expireAt);
            }
    
    
    
            /// <summary>
            /// 检测是否有登录
            /// </summary>
            /// <returns>是否登录</returns>
            public static bool CheckLogin()
            {
                if (UserDataHelper.User == null)
                {
                    return false;
                }
                return true;
            }
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="action">action名称</param>
            /// <param name="control">控制器名称</param>
            /// <returns>是否有权限</returns>
            public static bool CheckPermissions(string actionName, string controlName)
            {
                string apiStr = roleBLL.GetAPIRoleByRole(UserDataHelper.User.role_uuid).ToLower();//实现原理为 存储对应的API路径到数据库 这里不做具体实现
                if (apiStr.Contains("/" + controlName.Trim() + "/" + actionName.Trim()))
                {
                    return true;
                }
                else if (controlName.Trim() == "areaticketcountandticket"|| controlName.Trim() == "servicecountbymonthweek" || controlName.Trim() == "taskcountbyweekmonth") { return true; }
                else return false;
                //TODO 暂未开发
                //return true;
            }
    
            /// <summary>
            /// 保存数据
            /// </summary>
            /// <param name="key">key</param>
            /// <param name="obj">数据</param>
            public static void SaveValue(string key, object obj)
            {
                string str = JsonConvert.SerializeObject(obj);
                var value = System.Text.Encoding.UTF8.GetBytes(str);
                // CacheManage.SaveCache<LoginUser>(key, obj);
                HttpContext.Current.Session.Set(key, value);
            }
    
            /// <summary>
            /// 获取数据
            /// </summary>
            /// <typeparam name="T">数据格式</typeparam>
            /// <param name="key">key</param>
            /// <returns>保存的数据</returns>
            public static T GetValue<T>(string key)
            {
                byte[] b;
                var d = HttpContext.Current.Session.TryGetValue(key, out b);
                if (d == false) return default(T);
                try
                {
                    string str = System.Text.Encoding.UTF8.GetString(b);
                    return JsonConvert.DeserializeObject<T>(str);
                }
                catch// (Exception ex)
                {
                    //   LogHelper.Error(ex);
                    return default(T);
                }
            }
    
            // public const string DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
    
            //  public const string DateTimeFormat2 = "yyyy-MM-dd";
    
        }
     //全局拦截
                services.AddMvc(options =>
                {
                    options.Filters.Add(typeof(ActionAttribute));
                })

    部分控制器不进行拦截

    /// <summary>
        /// 不需要登陆的地方加个这个空的拦截器
        /// </summary>
        public class NoSignAttribute : ActionFilterAttribute { }
     /// <summary>
            /// 不需要登录使用这个[NoSign] 拦截器
            /// </summary>
            /// <returns></returns>
            [NoSign]
            public IActionResult Privacy()
            {
                return View();
            }

     

     

     

    展开全文
  • 文章目录普通验证代码... // dataName是请求参数data的属性之一 @NotBlank(message = "名称(dataName)不能为空") @ApiModelProperty(value = "数据集名称", required = true) private String dataName; 分析 一

    v1.0.1

    普通验证

    普通验证另可查看本人另一篇验证文档

    代码节选

    // controller入口
    saveOrUpdate(@RequestBody @Valid UserDataDO data)
    	
    	// dataName是请求参数data的属性之一
     	@NotBlank(message = "名称(dataName)不能为空")
        @ApiModelProperty(value = "数据集名称", required = true)
        private String dataName;
    

    分析

    一般来说,这种写法可以满足需求,但是如果请求参数包含【嵌套对象】就不行了,比如下述例子:

    	// userDataColList是data的属性之一
    	@NotEmpty(message = "数据内容(colList)不能为空")
        @ApiModelProperty(value = "数据内容", required = true)
        private List<UserDataColDO> userDataColList;
    

    这样写,只能验证userDataColList是否为空,因为加了 @NotEmpty注解。

    嵌套验证

    在对象的字段上再加@Valid注解,写法:

    	// userDataColList是data的属性之一
    	@Valid
    	@NotEmpty(message = "数据内容(colList)不能为空")
        @ApiModelProperty(value = "数据内容", required = true)
        private List<UserDataColDO> userDataColList;
    

    list如何注解验证

    1)输入参数那里,使用ValidList替代List作为传入数组,文末附上ValidList.java

    ... ...
    saveOrUpdateBatch(@RequestBody @Valid ValidList<XxxDO> list)
    ... ...
    

    2)List<Teacher>作为E对象的属性,在它前面加上List<@Valid Teacher>
    ps:请严格按照示例代码配置

    附录

    ValidList.java

    package com.jxmpc.web.controller.tool;
    
    import javax.validation.Valid;
    import java.util.*;
    
    /**
     * 功能:嵌套验证List
     *
     * @author: cc
     * @qq: 8416837
     * @date: 2020/8/21 15:37
     */
    public class ValidList<E> implements List<E> {
    
        @Valid
        private List<E> list = new ArrayList<>();
    
        @Override
        public int size() {
            return list.size();
        }
    
        @Override
        public boolean isEmpty() {
            return list.isEmpty();
        }
    
        @Override
        public boolean contains(Object o) {
            return list.contains(o);
        }
    
        @Override
        public Iterator<E> iterator() {
            return list.iterator();
        }
    
        @Override
        public Object[] toArray() {
            return list.toArray();
        }
    
        @Override
        public <T> T[] toArray(T[] a) {
            return list.toArray(a);
        }
    
        @Override
        public boolean add(E e) {
            return list.add(e);
        }
    
        @Override
        public boolean remove(Object o) {
            return list.remove(o);
        }
    
        @Override
        public boolean containsAll(Collection<?> c) {
            return list.containsAll(c);
        }
    
        @Override
        public boolean addAll(Collection<? extends E> c) {
            return list.addAll(c);
        }
    
        @Override
        public boolean addAll(int index, Collection<? extends E> c) {
            return list.addAll(index, c);
        }
    
        @Override
        public boolean removeAll(Collection<?> c) {
            return list.removeAll(c);
        }
    
        @Override
        public boolean retainAll(Collection<?> c) {
            return list.retainAll(c);
        }
    
        @Override
        public void clear() {
            list.clear();
        }
    
        @Override
        public E get(int index) {
            return list.get(index);
        }
    
        @Override
        public E set(int index, E element) {
            return list.set(index, element);
        }
    
        @Override
        public void add(int index, E element) {
            list.add(index, element);
        }
    
        @Override
        public E remove(int index) {
            return list.remove(index);
        }
    
        @Override
        public int indexOf(Object o) {
            return list.indexOf(o);
        }
    
        @Override
        public int lastIndexOf(Object o) {
            return list.lastIndexOf(o);
        }
    
        @Override
        public ListIterator<E> listIterator() {
            return list.listIterator();
        }
    
        @Override
        public ListIterator<E> listIterator(int index) {
            return list.listIterator(index);
        }
    
        @Override
        public List<E> subList(int fromIndex, int toIndex) {
            return list.subList(fromIndex, toIndex);
        }
    
        public List<E> getList() {
            return list;
        }
    
        public void setList(List<E> list) {
            this.list = list;
        }
    
    }
    

    待续

    展开全文
  • Dubbo参数验证(五)

    千次阅读 2019-06-03 18:38:07
    1、参考 ...Dubbo中的参数验证基于JSR-303,它是JAVA EE 6中的一项子规范,通过注解的方式用来对 Java Bean中字段的值进行简单验证。Consumer端要调用Provider端的接口,调用接口的话就会有参数...
  • WebGeeker-Validation: 一个强大的参数验证工具(PHP) 项目地址: github 码云 主要用于对API请求的参数取值进行合法性验证。 在实现服务端的API接口时,对于每一个接口的每一个参数,都应该验证其取值是否合法,以免...
  • Flask_RESTful之参数验证

    千次阅读 2020-01-15 22:47:44
    参数验证 也叫参数解析。 Flask-Restful插件提供了类似WTForms来验证提交的数据是否合法的包,叫做reqparse。 基本用法 借助于测试工程师 常用的接口测试工具postman来检验。 from flask import Flask,url_for,...
  • 总结篇-后台参数验证的几种方式

    万次阅读 2018-08-05 15:24:46
    参数验证是一个常见的问题,无论是前端还是后台,都需对用户输入进行验证,以此来保证系统数据的正确性。对于web来说,有些人可能理所当然的想在前端验证就行了,但这样是非常错误的做法,前端代码对于用户来说是...
  • SpringBoot Controller参数验证

    千次阅读 2018-05-27 13:13:34
    SpringBoot已经将校验器集成,不需要自己配置校验器,直接就可以拿来用首先在实体类中进行配置校验规则:使用的是javax.validation.constraints包下的注解,有@Not...然后再controller参数中进行配置:public Str...
  • govalidator golang 参数验证

    千次阅读 2019-04-06 18:29:28
    https://github.com/asaskevich/govalidator 好用。星数也高。 基于validator.js
  • vue.js 表单参数验证方法

    千次阅读 2017-11-28 11:36:17
    vue.js 编写验证表单参数是否为空,为空返回null,否则返回表单参数值 一、util.jsvar utils = { // 校验表单是否为空 validate: function (data, except) { for (var item in data) { // 校验表单,except为排除...
  • Java 必填参数验证

    千次阅读 2018-09-21 11:06:00
    在接口拦截器中,执行 /** * ... * @param obj 待验证的requestDTO * @param originMap 必填参数Map * @return map :isSuccess=true 成功 * isSuccess=false 失败 */ public ...
  • 阅读了官方文档(http://alibaba.github.io/dubbo-doc-static/User+Guide-zh.htm#UserGuide-zh-%E5%8F%82%E6%95%B0%E9%AA%8C%E8%AF%81),对于服务端开启参数验证,我的理解是需要做两步工作: 1.在api的参数类里,...
  • Flask学习系列9.1—普通参数验证

    千次阅读 2019-01-17 19:35:33
    一.普通表单验证 目的:实现一个简单的表单的验证的逻辑处理 1.路由需要get和post两种请求方式,需要判断请求方式 2.获取请求的参数 3.判断参数是否正确 register.py文件 浏览器运行结果 ...
  • 这里写自定义目录标题dotNET Core WebAPI 统一处理(返回值、参数验证、异常)环境文档安装配置运行效果参数验证简单实现重构返回值结果实体类过滤器类Startup 配置添加示例接口方法运行效果继续重构参数验证异常...
  • golang的参数验证

    千次阅读 2016-07-24 15:29:51
    golang_validator可以自由定制的golang参数验证器关于该组件: 本组件是可高度定制的验证,例子如下:type testValidator struct { ItemNum int `valid:"PosNO" name:"items" ` // 验证是否是正数 IsCount int `...
  • 关于spring web应用中关于如何使用 Bean Validation API和hibernate-validator的文章已经很多,本文就不再重复叙述,今天要介绍的重点是在SpringBoot restful服务中如何根据不同验证错误响应不同的自定义错误码。...
  • JAVA中Validation进行参数验证

    千次阅读 2019-04-10 16:48:54
    1.maven中引入hibernate-validator对应的jar: ...@Email 验证是否是邮件地址,如果为null,不进行验证,算通过验证。 @ScriptAssert(lang= ,script=, alias=) @URL(protocol=,host=, port=,regexp=, flags=)
  • 使用@Valid注解进行参数验证编写实体类后台接收参数测试结果 编写实体类 在使用@Valid注解对于对象进行验证时,需要在对象需要验证的属性上方通过注解来标注。 import javax.validation.constraints.*; public ...
  • * @param bindingResult 参数验证的绑定结果 * @return 验证结果 */ public static String getErrorMessage(BindingResult bindingResult) { if (bindingResult.hasErrors()) { StringBuilder sb = new ...
  • 有些时候一个参数会在多个场景使用,不同场景对该参数的校验需求不同,即有些场景不对该参数进行校验。 比如注册时,我们要填写出生日期参数,但是登录时并不需要该参数 这里可以用到校验分组groups public class...
  • 接口参数加密+时效性验证+私钥+Https
  • New-ADUser : 无法对参数“Path”执行参数验证。参数为 Null 或空。请提供一个不为 Null 或空的参数,然后重试该命令。 所在位置 行:5 字符: 148 + … . n a m e − P a t h _.name -Path _.Path -...
  • 一、同步返回参数和同步响应参数的区别    1.同步返回的参数是指在接口的请求参数中传入return_url参数,在支付成功后在return_url地址后面返回的如: https://m.alipay.com/Gk8NF23?total_amount=9.00&...
  • mockito验证参数_Mockito验证

    千次阅读 2020-06-23 20:05:52
    mockito验证参数 本文是我们名为“ 用Mockito测试 ”的学院课程的一部分。 在本课程中,您将深入了解Mockito的魔力。 您将了解有关“模拟”,“间谍”和“部分模拟”的信息,以及它们相应的存根行为。 您还将看到...
  • Springboot之自定义参数验证

    千次阅读 2019-01-26 18:38:51
    针对表单提交时,我们需要对参数进行校验,然而验证的种类不能符合我们的需求,需要自定义参数验证。 自定义参数验证依赖注解实现,所有我们需要自定义一个自己的注解 手机号的验证注解 import javax.validation....
  • Dubbox中的参数验证失败返回信息的格式问题 在使用dubbox进行实际项目开发的过程中,对输入的参数进行验证是一个很常见的问题,所以在Dubbo中提供了参数化验证的机制。但是,在具体项目实施的过程中,发现当参数...
  • 前一段时间我们项目组也开始使用webapi来开发接口,开发之初发现设计了很多输入参数验证规则(不适用,不好用并且还不能满足需求),然后我们在写业务的方法还的调用参数验证方法, 所以开发是很郁闷的,bug
  • jeesite 参数验证失败

    千次阅读 2016-11-07 15:24:08
    服务器参数验证失败

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,197,396
精华内容 478,958
关键字:

参数验证