Java Bean验证基础

这篇文章总结了一些简单易用的示例,这些示例说明了您想使用Java Beans Validation API(JSR 349,JSR 303)进行的最常见操作。 记住,Beans Validation独立于Java EE。 尽管它是作为Java EE兼容服务器的一部分内置的,但该API也可以在Java SE应用程序中轻松使用。 所有这些示例都使用Java SE。

要求

我使用以下主要技术完成了本文的所有工作。 您可能可以使用不同的技术或版本来做相同的事情,但不能保证。

  • Java 1.8.0_65_x64
  • NetBeans 8.2
  • Maven 3.0.5(与NetBeans捆绑在一起)
<dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>1.1.0.Final</version>
</dependency>
<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>5.1.2.Final</version>
</dependency>
<dependency><groupId>javax.el</groupId><artifactId>javax.el-api</artifactId><version>2.2.4</version>
</dependency>
<dependency><groupId>org.glassfish.web</groupId><artifactId>javax.el</artifactId><version>2.2.4</version>
</dependency>
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope>
</dependency>

下载

访问我的GitHub页面https://github.com/mjremijan以查看我所有的开源项目。 这篇文章的代码位于: https : //github.com/mjremijan/thoth-beanvalidation

基本

此示例显示了使用内置的标准约束和内置的标准验证器进行Bean验证的基础。

清单1.1 –验证的Bean

package org.thoth.beanvalidation.basics;import javax.validation.constraints.NotNull;public class Widget {@NotNullprotected String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}

清单1.2 –如何验证

package org.thoth.beanvalidation.basics;import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;public class WidgetTest {protected Validator validator;@Beforepublic void before() {validator = Validation.buildDefaultValidatorFactory().getValidator();}@Testpublic void violations_size() {// setupWidget w = new Widget();// actionSet<ConstraintViolation<Widget>> violations= validator.validate(w);// assertAssert.assertEquals(1, violations.size());}@Testpublic void violation_message() {// setupWidget w = new Widget();// actionSet<ConstraintViolation<Widget>> violations= validator.validate(w);// assertConstraintViolation<Widget> v= violations.stream().findFirst().get();Assert.assertEquals("may not be null", v.getMessage());}@Testpublic void violation_messageTemplate() {// setupWidget w = new Widget();// actionSet<ConstraintViolation<Widget>> violations= validator.validate(w);// assertConstraintViolation<Widget> v= violations.stream().findFirst().get();Assert.assertEquals("{javax.validation.constraints.NotNull.message}", v.getMessageTemplate());}@Testpublic void violation_propertyPath() {// setupWidget w = new Widget();// actionSet<ConstraintViolation<Widget>> violations= validator.validate(w);// assertConstraintViolation<Widget> v= violations.stream().findFirst().get();Assert.assertEquals("name", v.getPropertyPath().toString());}
}

自定义消息模板

本示例说明了如何使用自定义错误消息而不是使用内置标准错误消息来定制内置标准约束。

清单2.1 – ValidationMessages.properties

Candy.name.NotNull=A candy name is required.

清单2.2 –验证的Bean

package org.thoth.beanvalidation.custommessage;import javax.validation.constraints.NotNull;public class Candy {@NotNull(message = "{Candy.name.NotNull}")protected String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}

清单2.3 –如何验证

package org.thoth.beanvalidation.custommessage;import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;public class CandyTest {protected static Validator validator;@BeforeClasspublic static void before() {validator = Validation.buildDefaultValidatorFactory().getValidator();}@Testpublic void notnull_violation_message() {// setupCandy candy = new Candy();// actionSet<ConstraintViolation<Candy>> violations= validator.validate(candy);// assertConstraintViolation<Candy> v= violations.stream().findFirst().get();Assert.assertEquals("A candy name is required.", v.getMessage());}@Testpublic void notnull_violation_messageTemplate() {// setupCandy candy = new Candy();// actionSet<ConstraintViolation<Candy>> violations= validator.validate(candy);// assertConstraintViolation<Candy> v= violations.stream().findFirst().get();Assert.assertEquals("{Candy.name.NotNull}", v.getMessageTemplate());}
}

具有可变替换的自定义消息模板

此示例说明如何使用自定义错误消息配置内置的标准约束,该消息中包含变量值,该变量值在运行时由Bean验证替换。 可以替换的变量示例包括已验证的实际值以及@Size约束的min和max属性。

清单3.1 – ValidationMessages.properties

Candy.name.Size.message=The candy name "${validatedValue}" is invalid. It must be between {min} and {max} characters long

清单3.2 –验证的Bean

package org.thoth.beanvalidation.variablereplacement;import javax.validation.constraints.Size;public class Candy {private String name;@Size(message = "{Candy.name.Size.message}", min=5, max=10)public String getName() {return name;}public void setName(String name) {this.name = name;}
}

清单3.3 –如何验证

package org.thoth.beanvalidation.variablereplacement;import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.thoth.beanvalidation.variablereplacement.Candy;public class CandyTest {protected static Validator validator;@BeforeClasspublic static void before() {validator = Validation.buildDefaultValidatorFactory().getValidator();}@Testpublic void does_the_constraint_have_the_correct_messageTemplate() {// setupCandy candy = new Candy();candy.setName("");// actionSet<ConstraintViolation<Candy>> violations= validator.validate(candy);// assertConstraintViolation<Candy> v= violations.stream().findFirst().get();Assert.assertEquals("{Candy.name.Size.message}", v.getMessageTemplate());}@Testpublic void is_the_message_correct_if_size_is_too_small() {// setupCandy candy = new Candy();candy.setName("foo");// actionSet<ConstraintViolation<Candy>> violations= validator.validate(candy);// assertConstraintViolation<Candy> v= violations.stream().findFirst().get();Assert.assertEquals("The candy name \"foo\" is invalid. It must be between 5 and 10 characters long", v.getMessage());}@Testpublic void is_the_message_correct_if_size_is_too_big() {// setupCandy candy = new Candy();candy.setName("123456789|1");// actionSet<ConstraintViolation<Candy>> violations= validator.validate(candy);// assertConstraintViolation<Candy> v= violations.stream().findFirst().get();Assert.assertEquals("The candy name \"123456789|1\" is invalid. It must be between 5 and 10 characters long", v.getMessage());}
}

自定义属性验证器

本示例说明如何为类的属性创建您自己的约束和您自己的验证器。

清单4.1 – ValidationMessages.properties

org.thoth.beanvalidation.propertyvalidator.Excludes.message=The value "${validatedValue}" is one of {value} which is forbidden.

清单4.2 –约束注释

package org.thoth.beanvalidation.propertyvalidator;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {ExcludesValidator.class})
@Documented
public @interface Excludes {String message() default "{org.thoth.beanvalidation.propertyvalidator.Excludes.message}";Class[] groups() default {};Class[] payload() default {};String[] value() default {};
}

清单4.3 –约束验证器

package org.thoth.beanvalidation.propertyvalidator;import java.util.Arrays;
import java.util.List;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;public class ExcludesValidatorimplements ConstraintValidator< Excludes, String> {private List<String> excludeTheseValues;@Overridepublic void initialize(Excludes arg) {String[] strarr = arg.value();if (strarr == null) {strarr = new String[]{};}excludeTheseValues = Arrays.asList(strarr);}@Overridepublic boolean isValid(String value, ConstraintValidatorContext cvc) {if (excludeTheseValues.contains(value)) {return false;} else {return true;}}
}

清单4.4 –验证的Bean

package org.thoth.beanvalidation.propertyvalidator;public class Candy {private String name;public Candy(String name) {this.name = name;}@Excludes({"foo", "bar", "shrubbery"})public String getName() {return name;}
}

清单4.5 –如何验证

package org.thoth.beanvalidation.propertyvalidator;import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import static org.junit.Assert.assertEquals;
import org.junit.BeforeClass;
import org.junit.Test;public class CandyTest {protected static Validator validator;@BeforeClasspublic static void before() {validator = Validation.buildDefaultValidatorFactory().getValidator();}@Testpublic void a_non_excludeded_name_should_not_give_you_a_constraint_violation() {// setupCandy candy = new Candy("hershey");// actionSet<ConstraintViolation<Candy>> violations= validator.validate(candy);// assertassertEquals(0, violations.size());}@Testpublic void do_you_get_a_constraint_violation_if_you_use_excluded_name_foo() {// setupCandy candy = new Candy("foo");// actionConstraintViolation<Candy> violation= validator.validate(candy).iterator().next();// assertassertEquals("{org.thoth.beanvalidation.propertyvalidator.Excludes.message}", violation.getMessageTemplate());assertEquals("The value \"foo\" is one of [foo, bar, shrubbery] which is forbidden.", violation.getMessage());}@Testpublic void do_you_get_a_constraint_violation_if_you_use_excluded_name_bar() {// setupCandy candy = new Candy("bar");// actionConstraintViolation<Candy> violation= validator.validate(candy).iterator().next();// assertassertEquals("{org.thoth.beanvalidation.propertyvalidator.Excludes.message}", violation.getMessageTemplate());assertEquals("The value \"bar\" is one of [foo, bar, shrubbery] which is forbidden.", violation.getMessage());}@Testpublic void do_you_get_a_constraint_violation_if_you_use_excluded_name_shrubbery() {// setupCandy candy = new Candy("shrubbery");// actionConstraintViolation<Candy> violation= validator.validate(candy).iterator().next();// assertassertEquals("{org.thoth.beanvalidation.propertyvalidator.Excludes.message}", violation.getMessageTemplate());assertEquals("The value \"shrubbery\" is one of [foo, bar, shrubbery] which is forbidden.", violation.getMessage());}
}

自定义类验证器

本示例说明如何创建适用于整个的约束和验证器。

清单5.1 – ValidationMessages.properties

org.thoth.beanvalidation.classvalidator.IdentificationExists.message=At least one of social security number, drivers license number, or passport number must exist.

清单5.2 –约束注释

package org.thoth.beanvalidation.classvalidator;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {IdentificationExistsValidator.class})
@Documented
public @interface IdentificationExists {String message() default "{org.thoth.beanvalidation.classvalidator.IdentificationExists.message}";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};
}

清单5.3 –约束验证器

package org.thoth.beanvalidation.classvalidator;import java.util.Objects;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;public class IdentificationExistsValidator implements ConstraintValidator<IdentificationExists, Identification> {@Overridepublic void initialize(IdentificationExists a) {}@Overridepublic boolean isValid(Identification t, ConstraintValidatorContext cvc) {boolean invalid =Objects.equals(t.getDriversLicenseNumber(), null)&&Objects.equals(t.getPassportNumber(), null)&&Objects.equals(t.getSocialSecurityNumber(), null);return !invalid;}
}

清单5.4 –验证的Bean

package org.thoth.beanvalidation.classvalidator;@IdentificationExists
public class Identification {protected String socialSecurityNumber;protected String driversLicenseNumber;protected String passportNumber;public String getSocialSecurityNumber() {return socialSecurityNumber;}public void setSocialSecurityNumber(String socialSecurityNumber) {this.socialSecurityNumber = socialSecurityNumber;}public String getDriversLicenseNumber() {return driversLicenseNumber;}public void setDriversLicenseNumber(String driversLicenseNumber) {this.driversLicenseNumber = driversLicenseNumber;}public String getPassportNumber() {return passportNumber;}public void setPassportNumber(String passportNumber) {this.passportNumber = passportNumber;}
}

清单5.5 –如何验证

package org.thoth.beanvalidation.classvalidator;import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;public class IdentificationTest {protected Validator validator;@Beforepublic void before() {validator = Validation.buildDefaultValidatorFactory().getValidator();}@Testpublic void violation_if_all_are_missing() {// setupIdentification id = new Identification();// actionSet<ConstraintViolation<Identification>> violations= validator.validate(id);// assertConstraintViolation<Identification> v= violations.stream().findFirst().get();Assert.assertEquals("At least one of social security number, drivers license number, or passport number must exist.", v.getMessage());}@Testpublic void no_violation_if_social_security_number_exists() {// setupIdentification id = new Identification();id.setSocialSecurityNumber("a");// actionSet<ConstraintViolation<Identification>> violations= validator.validate(id);// assertAssert.assertEquals(0, violations.size());}@Testpublic void no_violation_if_drivers_license_number_exists() {// setupIdentification id = new Identification();id.setDriversLicenseNumber("a");// actionSet<ConstraintViolation<Identification>> violations= validator.validate(id);// assertAssert.assertEquals(0, violations.size());}@Testpublic void no_violation_if_passport_number_exists() {// setupIdentification id = new Identification();id.setPassportNumber("a");// actionSet<ConstraintViolation<Identification>> violations= validator.validate(id);// assertAssert.assertEquals(0, violations.size());}
}

组序列(短路)

本示例说明了在进行验证时如何使用@GroupSequence作为短路。 这意味着,如果第一轮验证未通过,则验证“短路”,并且不会执行第二轮验证。

默认情况下,所有bean验证约束都放入“默认”组序列中。 但是,通过将@GroupSequence放在类上(如下所示),仅针对该类重新定义“默认”组序列。 在下面的类上使用@GroupSequence ,其基本功能是在bean验证期间,第一个操作是验证该类中未专门分配组的所有约束。 首先是@NotNull约束。 如果所有这些都OK,那么第二个操作是验证Second.class组中的所有约束。 那就是@Size约束。 如果所有这些都OK,那么第三Third.class操作将验证Third.class组中的所有约束。 那就是@Pattern约束。 如果某个小组在任何时候都无法通过验证,则验证将“短路”,并且验证不再进行。

清单6.1 –验证的Bean

package org.thoth.beanvalidation.groupsequence;import javax.validation.GroupSequence;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;@GroupSequence({Candy.class, Candy.Second.class, Candy.Third.class})
public class Candy {protected interface Second {}protected interface Third {}private String name;@NotNull()@Size(min=4, max=10, groups = Second.class )@Pattern(regexp = "[a-z]", groups = Third.class)public String getName() {return name;}public void setName(String name) {this.name = name;}
}

清单6.2 –如何验证

package org.thoth.beanvalidation.groupsequence;import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;public class CandyTest {private Validator validator;@Beforepublic void before() {validator = Validation.buildDefaultValidatorFactory().getValidator();}@Testpublic void short_circuits_first_if_null() {// setupCandy w = new Candy();// actionSet<ConstraintViolation<Candy>> violations//= validator.validate(w, CheckGroupSequence.class);= validator.validate(w);// assertassertEquals(1, violations.size());assertEquals("may not be null", violations.iterator().next().getMessage());}@Testpublic void short_circut_if_size_is_in_violation() {// setupCandy w = new Candy();w.setName("foo");// actionSet<ConstraintViolation<Candy>> violations= validator.validate(w);// assertassertEquals(1, violations.size());assertEquals("size must be between 4 and 10", violations.iterator().next().getMessage());}@Testpublic void short_circuit_if_pattern_is_in_violation() {// setupCandy w = new Candy();w.setName("SHRUBBERY");// actionSet<ConstraintViolation<Candy>> violations= validator.validate(w);// assertassertEquals(1, violations.size());assertEquals("must match \"[a-z]\"", violations.iterator().next().getMessage());}
}

摘要

Bean验证是一种功能强大的API,尤其是因为它可以在Java EE服务器或独立的Java SE应用程序中使用。 这只是Bean验证API基础知识的简短摘要,但是通常它足以涵盖开发人员有关如何使用它的大多数问题。

翻译自: https://www.javacodegeeks.com/2017/07/java-bean-validation-basics.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/349596.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NOIP模拟测试「简单的区间·简单的玄学·简单的填数·简单的序列」

简单的区间 $update$ 终于$AC$了 找到$(sum[r]sum[l](sum表示以中间点为基准的sum)-mx)\%k0$的点 注意这里$sum$表示是以$mid$为基准点,(即$sum[l]$为后缀和,$sum[r]$为前缀和) 回忆$(sum[r]-sum[l])\%k0$这个经典问题做法(入阵曲简化版),开桶,桶里维护$sum[l]\%k$,那么$r$贡献…

苹果手机变卡了怎么解决_iOS 变卡怎么解决?一招搞定!无需刷机

iOSiOS 因为其优秀的底层交互逻辑&#xff0c;能让一部 iPhone 在不跨版本更新系统的前提下&#xff0c;至少保证 2 年内如新机般流畅。两年之后呢&#xff1f;你是否为手中的老将渐衰而苦恼过&#xff1f;本人对手机的流畅度十分敏感&#xff0c;可以说到了极致。付款时&#…

NOIP模拟测试38「金·斯诺·赤」

金 辗转相减见祖宗 高精 #include<bits/stdc.h> using namespace std; #define A 2000 #define P 1 #define N 10 #define ll long long ll n,T; char sjdfj[A]; struct bignum {ll n[A],l;bignum(){l1,memset(n,0,sizeof(n));}void clear(){while(l>1&&!n[l-…

什么是JSON处理(JSON-P API)?

Java EE中的JSON-P简介 JSON处理1.0&#xff08; JSR 353 &#xff09;的Java API是一个低级&#xff0c;轻量级的JSON解析器和生成器&#xff0c;它提供了在属性和值级别上操作JSON数据的能力。 JSR 353提供了两种JSON处理模型&#xff1a; 对象模型和流模型。 两种模型都可以…

电视机原理图_电工电气,如何看电气原理图和接线图,如何设计图纸?

电气图纸一般可分为两大类&#xff0c;一类为电力电气图&#xff0c;它主要是表述电能的传输、分配和转换&#xff0c;如电网电气图、电厂电气控制图等。另一类为电子电气图&#xff0c;它主要表述电子信息的传递、处理&#xff1b;如电视机电气原理图。本文主要谈电力电气图的…

NOIP模拟测试39,思维禁锢专场「工业题·玄学题·卡常题」

工业题 题解 抱歉,题解没时间写了 代码 #include<bits/stdc.h> using namespace std; #define ll long long #define A 6666666 #define mod 998244353 ll jie[A],ni[A],acnt[A],bcnt[A]; ll fheng[A],fshu[A]; ll n,m,a,b; ll meng(ll x,ll k){ll ans1;for(;k;k>>…

ubuntu 如何登录远程服务器_VSCode远程登录云服务器、树莓派实现在线调试代码...

在PyCon2019大会上&#xff0c;微软发布了VSCode Remote&#xff0c;开启了远程开发的新时代&#xff01;Remote可以帮助开发者在容器、物理机器或虚拟机&#xff0c;以及WSL上实现无缝的远程开发。通过安装Remote Development Extension Pack&#xff0c;开发者可以快速上手远…

macosx jdk_MacOSX环境上的多个Java JDK

macosx jdk同样&#xff0c;这是在Mac&#xff08;OSX 10.8.x &#xff09;上配置Java开发环境的一个小技巧。 如果您现在真的开始&#xff0c;我建议您阅读我以前的文章之一 &#xff0c;这是一种快速干净的方法&#xff08;我想&#xff09;来设置环境变量并开始Java编码。 今…

屏幕方向读取与锁定:Screen Orientation API(转)

什么是 Screen Orientation API Screen Orientation API 为 Web 应用提供了读取设备当前屏幕方向、旋转角度、锁定旋转方向、获取方向改变事件的能力。使得特定应用在屏幕方向方面增强用户体验&#xff0c;如视频和游戏。该标准目前处于工作组草案状态&#xff0c;最近一个修改…

scenebuilder各控件属性介绍_Flutter 全栈式——基础控件

在Flutter中&#xff0c;UI小控件有两种设计风格&#xff0c;一种是Material设计&#xff0c;这是安卓的官方设计风格&#xff0c;另一种则是Cupertino风格&#xff0c;是iOS的官方设计风格。因此&#xff0c;当遇到带有这两个单词开头的控件时&#xff0c;我们应该明确他们表达…

正义联盟的Spring靴

正义联盟的黑暗时代已经来临&#xff0c;强大的Darkseid即将征服人类。 蝙蝠侠在《神力女超人》的帮助下&#xff0c;努力使联盟与一个关键方面失联。 适当的正义联盟成员管理系统。 由于时间不在他们身边&#xff0c;他们不想经历繁琐的过程&#xff0c;从头开始用他们需要的所…

Fetch

fetch是一种HTTP数据请求的方式&#xff0c;是XMLHttpRequest的一种替代方案。fetch不是ajax的进一步封装&#xff0c;而是原生js。Fetch函数就是原生js&#xff0c;没有使用XMLHttpRequest对象。 ajax 使用步骤1.创建XmlHttpRequest对象2.调用open方法设置基本请求信息3.设置发…

boost安装_Centos安装MySQL

安装MySQLMySQL 各版本介绍视频观看:https://www.bilibili.com/video/BV1ap4y1i75jMySQL 官网:https://www.mysql.com/cn/MySQL Community Server社区版本&#xff0c;开源免费&#xff0c;但不提供官方技术支持。MySQL Enterprise Edition 企业版本&#xff0c;需付费&#xf…

选择Java加密算法第3部分–公钥/私钥非对称加密

抽象 这是涵盖Java加密算法的三部分博客系列的第3部分。 本系列介绍如何实现以下目标&#xff1a; 使用SHA–512散列 使用AES–256的单密钥对称加密 RSA–4096 这第三篇文章详细介绍了如何实现非对称的RSA-4096公/私钥加密。 让我们开始吧。 免责声明 这篇文章仅供参考。 …

Error: Cannot find module '@babel/core'

官方默认babel-loader需要搭配最新版本babel 更新到最高版本: npm install -D babel-loader babel/core babel/preset-env webpack 转载于:https://www.cnblogs.com/nocry/p/11493363.html

javabeans_膨胀的JavaBeans –不要在您的API中添加“ Getters”

javabeans我已经最近在博客的想法的JavaBeans™如何可以扩展以减少在Java世界中&#xff0c;这被广泛接受的公约设立的膨胀。 该文章在DZone上重新发布&#xff0c;并在这里获得了颇具争议的反馈&#xff08;例如&#xff0c;大多数试图将一些新想法带入Java世界的想法&#xf…

uniapp 子组件 props拿不到数据_来吧!一文彻底搞定Vue组件!

点击蓝色 “达达前端小酒馆” 关注我哦!加个 “星标” &#xff0c;每天一篇文章&#xff0c;一起学编程作者 | Jeskson来源 | 达达前端小酒馆Vue组件的概述组件是什么呢&#xff0c;了解组件对象的分析&#xff0c;Vue组件中的data属性&#xff0c;props传递数据的原理到底是…

csp-s模拟测试41「夜莺与玫瑰·玫瑰花精·影子」

夜莺与玫瑰 题解 联赛$T1$莫比乌斯$\%\%\%$ $dead$ $line$是直线 首先横竖就是$nm$这比较显然 枚举方向向量 首先我们枚举方向向量时只枚举右下方向,显然贡献$*2$就是所有斜着的直线 $i,j$表示当自己向右$i$个单位长度,向下$j$单位长度 我们相同斜率下只算最短的线贡献,(因为其…

春天重试,因为冬天来了

好的&#xff0c;这实际上与冬天无关&#xff0c;众所周知&#xff0c;冬天已经到了 。 它是关于Spring Retry的&#xff0c;Spring是一个小的Spring框架库&#xff0c;它使我们可以将重试功能添加到应可重试的任何任务中。 这里有一个很好的教程 &#xff0c;解释了如何设置简…

python做些什么项目_Python 的练手项目有哪些值得推荐

1 Web方向的练手项目 这个其实是肯定不用多少的了。Python的练手项目就是可以做一个网站了。我们可以做一个属于自己的博客。在做博客的时候&#xff0c;我们可以巩固的知识点是 HtmlCSSJS的基础知识&#xff0c;以及熟练的运用Python的Web开发框架&#xff08;例如Django或者F…