Android 和 Hibernate Validator - 可以一起使用吗?
Android and Hibernate Validator - it is possible to use together?
我想知道是否可以在 Android 上使用 Hibernate Validator。我试过了,但看起来 Android 平台 (javax.xml.stream.XMLInputFactory) 上缺少一些 javax 包。
这是我的代码、依赖项和错误:
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
Validator validator = validatorFactory.getValidator();
compile 'org.hibernate:hibernate-validator:5.1.3.Final'
compile 'javax.el:javax.el-api:2.2.4'
compile 'org.glassfish.web:javax.el:2.2.4'
03-28 10:07:15.562 6477-6477/foo E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: foo, PID: 6477
java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/xml/stream/XMLInputFactory;
at org.hibernate.validator.internal.xml.XmlParserHelper.<init>(XmlParserHelper.java:66)
at org.hibernate.validator.internal.xml.ValidationXmlParser.<init>(ValidationXmlParser.java:60)
at org.hibernate.validator.internal.engine.ConfigurationImpl.getBootstrapConfiguration(ConfigurationImpl.java:287)
at org.hibernate.validator.internal.engine.ConfigurationImpl.parseValidationXml(ConfigurationImpl.java:361)
at org.hibernate.validator.internal.engine.ConfigurationImpl.buildValidatorFactory(ConfigurationImpl.java:214)
at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:110)
at foo.FooActivity.onCreate(FooActivity.java:35)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.ClassNotFoundException: Didn't find class "javax.xml.stream.XMLInputFactory" on path: DexPathList[[zip file "/data/app/foo-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at org.hibernate.validator.internal.xml.XmlParserHelper.<init>(XmlParserHelper.java:66)
at org.hibernate.validator.internal.xml.ValidationXmlParser.<init>(ValidationXmlParser.java:60)
at org.hibernate.validator.internal.engine.ConfigurationImpl.getBootstrapConfiguration(ConfigurationImpl.java:287)
at org.hibernate.validator.internal.engine.ConfigurationImpl.parseValidationXml(ConfigurationImpl.java:361)
at org.hibernate.validator.internal.engine.ConfigurationImpl.buildValidatorFactory(ConfigurationImpl.java:214)
at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:110)
at foo.FooActivity.onCreate(FooActivity.java:35)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Suppressed: java.lang.ClassNotFoundException: javax.xml.stream.XMLInputFactory
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 21 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
我设法解决了这个问题。由于缺少 xml 包,我们必须在配置中禁用此选项。这是我提出的解决方案。
ValidatorFactory validatorFactory = Validation
.byDefaultProvider()
.configure()
.ignoreXmlConfiguration()
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
需要有以下依赖:
compile 'org.hibernate:hibernate-validator:5.1.3.Final'
compile 'javax.el:javax.el-api:2.2.4'
compile 'org.glassfish.web:javax.el:2.2.4'
对于来自字符串资源的自定义消息,必须实现 MessageInterpolator。首先必须扩展应用程序以访问整个项目的全局上下文。
public class ApplicationContext extends Application {
private static Application application;
@Override
public void onCreate() {
super.onCreate();
application = this;
}
public static Application getApplication() {
return application;
}
}
配置:
ValidatorFactory validatorFactory = Validation
.byDefaultProvider()
.configure()
.ignoreXmlConfiguration()
.messageInterpolator(new MessageInterpolator() {
@Override
public String interpolate(String messageTemplate, Context context) {
int id = ApplicationContext.getApplication().getResources().getIdentifier(messageTemplate, "string", R.class.getPackage().getName());
return ApplicationContext.getApplication().getString(id);
}
@Override
public String interpolate(String messageTemplate, Context context, Locale locale) {
return interpolate(messageTemplate, context);
}
})
.buildValidatorFactory();
示例:
@NotEmpty(message = "error_empty")
private String foo;
<resources>
<string name="error_empty">Cannot be empty</string>
</resources>
我想知道是否可以在 Android 上使用 Hibernate Validator。我试过了,但看起来 Android 平台 (javax.xml.stream.XMLInputFactory) 上缺少一些 javax 包。
这是我的代码、依赖项和错误:
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
Validator validator = validatorFactory.getValidator();
compile 'org.hibernate:hibernate-validator:5.1.3.Final'
compile 'javax.el:javax.el-api:2.2.4'
compile 'org.glassfish.web:javax.el:2.2.4'
03-28 10:07:15.562 6477-6477/foo E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: foo, PID: 6477
java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/xml/stream/XMLInputFactory;
at org.hibernate.validator.internal.xml.XmlParserHelper.<init>(XmlParserHelper.java:66)
at org.hibernate.validator.internal.xml.ValidationXmlParser.<init>(ValidationXmlParser.java:60)
at org.hibernate.validator.internal.engine.ConfigurationImpl.getBootstrapConfiguration(ConfigurationImpl.java:287)
at org.hibernate.validator.internal.engine.ConfigurationImpl.parseValidationXml(ConfigurationImpl.java:361)
at org.hibernate.validator.internal.engine.ConfigurationImpl.buildValidatorFactory(ConfigurationImpl.java:214)
at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:110)
at foo.FooActivity.onCreate(FooActivity.java:35)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.ClassNotFoundException: Didn't find class "javax.xml.stream.XMLInputFactory" on path: DexPathList[[zip file "/data/app/foo-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at org.hibernate.validator.internal.xml.XmlParserHelper.<init>(XmlParserHelper.java:66)
at org.hibernate.validator.internal.xml.ValidationXmlParser.<init>(ValidationXmlParser.java:60)
at org.hibernate.validator.internal.engine.ConfigurationImpl.getBootstrapConfiguration(ConfigurationImpl.java:287)
at org.hibernate.validator.internal.engine.ConfigurationImpl.parseValidationXml(ConfigurationImpl.java:361)
at org.hibernate.validator.internal.engine.ConfigurationImpl.buildValidatorFactory(ConfigurationImpl.java:214)
at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:110)
at foo.FooActivity.onCreate(FooActivity.java:35)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Suppressed: java.lang.ClassNotFoundException: javax.xml.stream.XMLInputFactory
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 21 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
我设法解决了这个问题。由于缺少 xml 包,我们必须在配置中禁用此选项。这是我提出的解决方案。
ValidatorFactory validatorFactory = Validation
.byDefaultProvider()
.configure()
.ignoreXmlConfiguration()
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
需要有以下依赖:
compile 'org.hibernate:hibernate-validator:5.1.3.Final'
compile 'javax.el:javax.el-api:2.2.4'
compile 'org.glassfish.web:javax.el:2.2.4'
对于来自字符串资源的自定义消息,必须实现 MessageInterpolator。首先必须扩展应用程序以访问整个项目的全局上下文。
public class ApplicationContext extends Application {
private static Application application;
@Override
public void onCreate() {
super.onCreate();
application = this;
}
public static Application getApplication() {
return application;
}
}
配置:
ValidatorFactory validatorFactory = Validation
.byDefaultProvider()
.configure()
.ignoreXmlConfiguration()
.messageInterpolator(new MessageInterpolator() {
@Override
public String interpolate(String messageTemplate, Context context) {
int id = ApplicationContext.getApplication().getResources().getIdentifier(messageTemplate, "string", R.class.getPackage().getName());
return ApplicationContext.getApplication().getString(id);
}
@Override
public String interpolate(String messageTemplate, Context context, Locale locale) {
return interpolate(messageTemplate, context);
}
})
.buildValidatorFactory();
示例:
@NotEmpty(message = "error_empty")
private String foo;
<resources>
<string name="error_empty">Cannot be empty</string>
</resources>