java - 使用 Spring MVC 绑定(bind)表单对象 CGLIB 的动态表单

标签 java spring-mvc cglib jsr

我有一个动态模型,由 X 数字组成,每个 radio 、文本、选择、选择多。这基本上就像后端的 EAV 数据库。

我需要用总共 N 个字段来呈现这个动态表单,然后验证提交的动态模型对象,然后使用字段定义的正则表达式对其进行验证。我希望通过 JSR 303 注释执行此验证。

因此,我想使用典型的 Spring MVC 开发方式绑定(bind)表单对象,通过 ModelAttribute @Valid 特性等。唯一的区别是模型对象在运行时之前是未知的/未定义的。

我倾向于使用 CGLIB 或类似的东西在运行时生成类,并用特殊的标签库呈现它,然后使用反射以某种方式使用特殊验证来验证它。

这样的事情完全超出了可能性范围吗?同样,我想做常规的 Spring MVC Controller 和模型,但使用动态表单对象。

最佳答案

这是可能的,但不能使用 cglib。 Cglib 是一个代理库,只允许您覆盖现有方法,但不允许定义新的方法,以便将动态模型传递给 Spring 或任何其他 bean 验证库。

当然可以使用 Javassist 或 Byte Buddy 生成此类。 (披露:我是作者)允许您定义此类元数据。例如,使用 Byte Buddy,您可以定义一个动态类:

new ByteBuddy()
  .subclass(Object.class)
  .defineField("foo", String.class, Visibility.PUBLIC)
  .annotateField(AnnotationDescription.Builder.ofType(NotNull.class).build())
  .make();

使用这段代码,您可以加载类,为 “foo” 字段分配一个值,并将此 bean 对象呈现给 bean 验证库。

与此同时,我觉得这种方法设计过度了。如果您需要为无法重新实现的特定 JSR 303 validator 提供兼容性,我只会采用此解决方案。否则,您可能更愿意直接验证数据。

如果您的框架还需要 getter 和 setter,您可以通过以下方式添加它们:

builder = builder
  .defineMethod("getFoo", String.class, Visibility.PUBLIC)
    .intercept(FieldAccessor.ofField("foo"));
  .defineMethod("setFoo", void.class, Visibility.PUBLIC)
    .withParameters(String.class)
    .intercept(FieldAccessor.ofField("foo"));

关于java - 使用 Spring MVC 绑定(bind)表单对象 CGLIB 的动态表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40557116/

相关文章:

java - Spring创建单例的多个实例?

java - 如何查找 Eclipse kepler 上的 spring MVC/JDO 在运行时出现的错误确实是由于库丢失或程序错误

android - 如何从Android(Gradle)应用中排除cglib依赖项?

java - 具有匿名类的 CGLib 增强器

java - 检查 Activity JFrame 中的重叠

java - 如何交替二维数组中每隔一列的元素顺序

java - ReentrantLock 不起作用

spring-mvc - 由于 TestRestTemplate 和 apache SSL,Spring Boot Integration 无法启动

java - 如何在spring-mvc中的同一个jsp页面的同一个 Controller 上创建两个操作

java - spring aop FastClassBySpringCGLIB 与EnhancerBySpringCGLIB