【问题标题】:How to bind subclass object in spring form submit as modelAttribute如何在spring表单中绑定子类对象提交为modelAttribute
【发布时间】:2016-10-02 02:31:18
【问题描述】:

我有

Class Shape {
      //Implementation
}
Class Round extends Shape{
      //Implementation
}

控制器 我有

@Requestmapping(value="/view/form")
public ModelAndView getForm(){
ModelAndView mav=new ModelAndView();
mav.addObject("shape",new Round());
}


@RequestMapping(value="/submit", method = RequestMethod.POST)    
public ModelAndView submitForm(@ModelAttribute("shape") Shape shape){
         if(shape instanceof Round){ //**Not giving positive result**

         }
    }

在 Jsp 中

<form:form action="/submit" commandName="shape" method="post">

//form tags

</form:form>

当我提交带有 Round 对象的表单时。在控制器端 ModelAttribute 没有给出 Round 的实例。它仅给出形状的实例。如何做到这一点

【问题讨论】:

  • 无论你做什么,静态类型都是Shape。这与 Spring 无关;这是静态/动态类型的问题。您可以强制转换或创建工厂/虚拟构造函数。
  • 为什么不能从表单提交Round
  • @Priyamal 每个形状都有更多的形状和相同的形状。

标签: java spring jsp spring-mvc spring-form


【解决方案1】:

这将永远无法工作

<form:form action="/submit" commandName="shape" method="post">

您正在从表单中提交 shape 并期待 shape 在控制器方法中

public ModelAndView submitForm(@ModelAttribute("shape") Shape shape)

它永远不会给你一个Round 对象。

只需从表单提交一个 Round 对象并使用它。

 <form:form action="/submit" commandName="round" method="post">
 public ModelAndView submitForm(@ModelAttribute("round") Round round)

已编辑:-

在表单中有一个hiddenInput 类型,它将告诉controller 它正在传递的Shape 的类型,您可以动态更改隐藏标记的值 应用户要求。

<input type="hidden" name="type" value="round">

获取contoller内部类型的值并将其用于castShape对象

     public ModelAndView submitForm(
     @ModelAttribute("shape") Shape shape,
     @RequestParam("type") String type)
     {
     if(type.equals("round")){
      //if type is a round you can cast the shape to a round
      Round round = (Round)shape; 
       }
    }

【讨论】:

    【解决方案2】:

    你不能这样做。因为这是两个不同的请求生命周期。

    @Requestmapping(value="/view/form")
    public ModelAndView getForm(){
    ModelAndView mav=new ModelAndView();
    mav.addObject("shape",new Round());
    }
    

    当上述请求执行时,即使您在mav 中添加了Round 对象,它也已转换为html 响应并发送回客户端。

    因此,当您提交表单时,当接下来出现以下请求时,这是一个完全独立的请求,spring 无法识别为先前请求添加的对象类型。

    @RequestMapping(value="/submit", method = RequestMethod.POST)    
    public ModelAndView submitForm(@ModelAttribute("shape") Shape shape){
             if(shape instanceof Round){ //**Not giving positive result**
    
             }
        }
    

    但是您可以尝试探索@SessionAttributes,使用它您可能能够在不同的请求中维护相同的对象

    【讨论】:

      【解决方案3】:

      可以指定需要绑定的子类。您必须在表单中添加一个附加参数(隐藏输入),指定需要绑定的类型。此字段必须与此案例形状中的模型属性具有相同的名称。然后,您需要实现一个转换器,将该字符串参数值转换为您需要绑定到的实际实例

      以下是您需要实施的更改

      1)在你的jsp中添加隐藏的输入

      <form:form action="/submit" commandName="shape" method="post">
         <input type="hidden" name="shape" value="round"/>
      //other form tags
      </form:form>
      

      2)实现一个Converter将String转换为Shape

      public class StringToShapeConverter implements Converter<String,Shape>{
      
         public Shape convert(String source){
            if("round".equalsIgnoreCase(source)){
                return new Round();
            }
            //other shapes
         }
      }
      

      3) 然后注册你的转换器,让 Spring MVC 知道它。如果您使用的是 Java 配置,则需要扩展 WebMvcConfigurerAdapter 并覆盖 addFormatters 方法

      @Configuration
      @EnableWebMvc
      public class WebConfig extends WebMvcConfigurerAdapter{
      
         @Override
         public void addFormatters(FormatterRegistry registry){
            registry.addConverter(new StringToShapeConverter());
         }
      }
      

      如果您使用 xml 配置,您可以使用 mvc:annotation-driven 元素来指定要使用的转换服务。然后使用 FormattingConversionSERviceFactoryBean 注册您的转换器

      <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:mvc="http://www.springframework.org/schema/mvc" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="
              http://www.springframework.org/schema/beans     
              http://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/context 
              http://www.springframework.org/schema/context/spring-context.xsd
              http://www.springframework.org/schema/mvc
              http://www.springframework.org/schema/mvc/spring-mvc.xsd">
      
          <mvc:annotation-driven conversion-service="conversionService"/>
      
          <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
             <property name="converters">
                 <set>
                    <bean class="some.package.StringToShapeConverter"/>
                 </set>
             </property>
          </bean>
      </beans>
      

      【讨论】:

        猜你喜欢
        • 2020-06-11
        • 1970-01-01
        • 2017-05-25
        • 1970-01-01
        • 2012-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-21
        相关资源
        最近更新 更多