diff --git a/hutool-extra/pom.xml b/hutool-extra/pom.xml
index f732a9b95..90234912f 100644
--- a/hutool-extra/pom.xml
+++ b/hutool-extra/pom.xml
@@ -258,5 +258,20 @@
1.2.3
test
+
+ org.hibernate
+ hibernate-validator
+ 6.0.12.Final
+
+
+ javax.el
+ javax.el-api
+ 3.0.1-b01
+
+
+ org.glassfish.web
+ javax.el
+ 2.2.6
+
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/validation/BeanValidationResult.java b/hutool-extra/src/main/java/cn/hutool/extra/validation/BeanValidationResult.java
new file mode 100644
index 000000000..674da5149
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/validation/BeanValidationResult.java
@@ -0,0 +1,66 @@
+package cn.hutool.extra.validation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * bean 校验结果
+ *
+ * @author chengqiang
+ */
+
+public class BeanValidationResult {
+
+ /**
+ * 校验是否成功
+ */
+ private Boolean success = Boolean.TRUE;
+
+ /**
+ * 错误消息
+ */
+ private List errorMessages = new ArrayList<>();
+
+ public Boolean getSuccess() {
+ return success;
+ }
+
+ public void setSuccess(Boolean success) {
+ this.success = success;
+ }
+
+ public List getErrorMessages() {
+ return errorMessages;
+ }
+
+ public void setErrorMessages(List errorMessages) {
+ this.errorMessages = errorMessages;
+ }
+
+ public static class ErrorMessage {
+ /**
+ * 属性字段名称
+ */
+ private String propertyName;
+ /**
+ * 错误信息
+ */
+ private String message;
+
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ public void setPropertyName(String propertyName) {
+ this.propertyName = propertyName;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+ }
+}
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/validation/BeanValidationUtil.java b/hutool-extra/src/main/java/cn/hutool/extra/validation/BeanValidationUtil.java
new file mode 100644
index 000000000..d35abf93b
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/validation/BeanValidationUtil.java
@@ -0,0 +1,83 @@
+package cn.hutool.extra.validation;
+
+import cn.hutool.extra.validation.BeanValidationResult.ErrorMessage;
+import org.hibernate.validator.HibernateValidator;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import java.util.Set;
+
+
+/**
+ * java bean 校验工具类
+ *
+ * @author chengqiang
+ */
+public class BeanValidationUtil {
+
+ private static final Validator validator = Validation.byProvider(HibernateValidator.class).configure().failFast(false).buildValidatorFactory().getValidator();
+
+ /**
+ * 校验对象
+ *
+ * @param bean bean
+ * @param groups 校验组
+ * @return {@link Set}
+ */
+ public static Set> validate(T bean, Class>... groups) {
+ return validator.validate(bean, groups);
+ }
+
+ /**
+ * 校验对象
+ *
+ * @param bean bean
+ * @param groups 校验组
+ * @return {@link BeanValidationResult}
+ */
+ public static BeanValidationResult warpValidate(T bean, Class>... groups) {
+ return warpBeanValidationResult(validate(bean, groups));
+ }
+
+ /**
+ * 校验bean的某一个属性
+ *
+ * @param bean bean
+ * @param propertyName 属性名称
+ * @return {@link Set}
+ */
+ public static Set> validateProperty(T bean, String propertyName, Class>... groups) {
+ return validator.validateProperty(bean, propertyName, groups);
+ }
+
+ /**
+ * 校验bean的某一个属性
+ *
+ * @param bean bean
+ * @param propertyName 属性名称
+ * @return {@link BeanValidationResult}
+ */
+ public static BeanValidationResult warpValidateProperty(T bean, String propertyName, Class>... groups) {
+ return warpBeanValidationResult(validateProperty(bean, propertyName, groups));
+ }
+
+ /**
+ * 包装校验结果
+ *
+ * @param constraintViolations 校验结果集
+ * @return {@link BeanValidationResult}
+ */
+ private static BeanValidationResult warpBeanValidationResult(Set> constraintViolations) {
+ BeanValidationResult result = new BeanValidationResult();
+ for (ConstraintViolation constraintViolation : constraintViolations) {
+ result.setSuccess(Boolean.FALSE);
+ ErrorMessage errorMessage = new ErrorMessage();
+ errorMessage.setPropertyName(constraintViolation.getPropertyPath().toString());
+ errorMessage.setMessage(constraintViolation.getMessage());
+ result.getErrorMessages().add(errorMessage);
+ }
+ return result;
+ }
+
+}
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/validation/package-info.java b/hutool-extra/src/main/java/cn/hutool/extra/validation/package-info.java
new file mode 100644
index 000000000..286124201
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/validation/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * java bean 校验工具
+ *
+ * @author chengqiang
+ */
+package cn.hutool.extra.validation;
\ No newline at end of file
diff --git a/hutool-extra/src/test/java/cn/hutool/extra/validation/BeanValidatorUtilTest.java b/hutool-extra/src/test/java/cn/hutool/extra/validation/BeanValidatorUtilTest.java
new file mode 100644
index 000000000..b8a3cfdd0
--- /dev/null
+++ b/hutool-extra/src/test/java/cn/hutool/extra/validation/BeanValidatorUtilTest.java
@@ -0,0 +1,51 @@
+package cn.hutool.extra.validation;
+
+import cn.hutool.core.lang.Assert;
+import org.junit.Test;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * java bean 校验工具类单元测试
+ *
+ * @author chengqiang
+ */
+public class BeanValidatorUtilTest {
+
+ public static class TestClass {
+
+ @NotBlank(message = "姓名不能为空")
+ private String name;
+
+ @NotBlank(message = "地址不能为空")
+ private String address;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+ }
+
+ @Test
+ public void beanValidatorTest() {
+ BeanValidationResult result = BeanValidationUtil.warpValidate(new TestClass());
+ Assert.isTrue(result.getSuccess());
+ }
+
+ @Test
+ public void propertyValidatorTest() {
+ BeanValidationResult result = BeanValidationUtil.warpValidateProperty(new TestClass(), "name");
+ Assert.isTrue(result.getSuccess());
+ }
+}