Android and Hibernate Validator - it is possible to use together?

醉酒当歌 提交于 2021-01-28 00:03:51

问题


I wonder if it is possible to use Hibernate Validator on Android. I tried but it looks like some javax packages are missing on Android platform (javax.xml.stream.XMLInputFactory).

Here is my code, dependency and error:

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.access$800(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.access$800(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

回答1:


I managed to solve this. Due to lack of xml packages we have to disable this option in configuration. Here is my proposed solution.

    ValidatorFactory validatorFactory = Validation
            .byDefaultProvider()
            .configure()
            .ignoreXmlConfiguration()
            .buildValidatorFactory();

    Validator validator = validatorFactory.getValidator();

It's necessary to have following dependencies:

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'

For custom messages from strings resources, MessageInterpolator has to be implemented. First of all Application must be extended for access to global context all over project.

public class ApplicationContext extends Application {
    private static Application application;

    @Override
    public void onCreate() {
        super.onCreate();
        application = this;
    }

    public static Application getApplication() {
        return application;
    }
}

Configuration:

    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();

Example:

@NotEmpty(message = "error_empty")
private String foo;

<resources>
    <string name="error_empty">Cannot be empty</string>
</resources>


来源:https://stackoverflow.com/questions/29315472/android-and-hibernate-validator-it-is-possible-to-use-together

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!