简体   繁体   English

如何以spring形式绑定子类对象提交为modelAttribute

[英]How to bind subclass object in spring form submit as modelAttribute

I Have 我有

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

Controller I Have 控制器我有

@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**

         }
    }

in Jsp 在Jsp

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

//form tags

</form:form>

when I submit the form with Round object. 当我用Round对象提交表单时。 At controller side ModelAttribute is not giving instance of Round . 在控制器端,ModelAttribute没有给出Round的实例。 its giving instance of shape only. 它只给出形状的例子。 How to do this 这该怎么做

this will never work 这永远不会奏效

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

you are submitting a shape from the form and expecting a shape in the controller method 您正在从表单中提交shape并期望控制器方法中的shape

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

which will never give you an Round object. 永远不会给你一个Round对象。

simply submit a Round object from the form and use that. 只需从表单中提交一个Round对象并使用它。

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

edited :- 编辑: -

have a hiddenInput type in the form which will tell controller the type of Shape it is passing, you can change the value of hidden tag dynamically upon user request. 在表单中有一个hiddenInput类型,告诉controller它传递的Shape类型,你可以根据用户请求动态更改隐藏标签的值。

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

get the value of the type inside contoller and use it to cast the Shape object 进去类型的值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; 
       }
    }

You cannot do this. 你不能做这个。 Because those are two different request lifecycles. 因为这是两个不同的请求生命周期。

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

When above request executes, even if you added Round object in mav , it has been converted into html response and sent back to client. 当执行上述请求时,即使您在mav添加了Round对象,它也已转换为html响应并发送回客户端。

So when below request comes next when you submit the form, it's a totally separate request and spring has no way to identify which object type was added for previous request. 因此,当您提交表单时接下来请求时,它是一个完全独立的请求,并且spring无法识别为先前的请求添加了哪个对象类型。

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

         }
    }

But you can try exploring @SessionAttributes , using this you might be able to maintain the same object across different requests 但是你可以尝试探索@SessionAttributes ,使用它可以在不同的请求中维护相同的对象

Its possible to specify the subclass that you need to bind to. 可以指定需要绑定的子类。 You have to add an additional parameter (hidden input) in your form which specify the type that needs to be bound to. 您必须在表单中添加一个附加参数(隐藏输入),指定需要绑定的类型。 This field must have the same name as the model attribute in this case shape. 此字段必须与此案例形状中的模型属性具有相同的名称。 You then need to implement a converter that converts this string parameter value to the actual instance that you need to bind to 然后,您需要实现一个转换器,将此字符串参数值转换为您需要绑定到的实际实例

The following are the changes that you need to implement 以下是您需要实施的更改

1)In your jsp add the hidden input inside your 1)在你的jsp中添加隐藏的输入

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

2)Implement a Converter to convert from String to a Shape 2)实现转换器以从String转换为Shape

public class StringToShapeConverter implements Converter<String,Shape>{

   public Shape convert(String source){
      if("round".equalsIgnoreCase(source)){
          return new Round();
      }
      //other shapes
   }
}

3) Then register your converter so that Spring MVC knows about it. 3)然后注册您的转换器,以便Spring MVC知道它。 If you are using Java config you need to extends WebMvcConfigurerAdapter and override the addFormatters method 如果您使用的是Java配置,则需要扩展WebMvcConfigurerAdapter并覆盖addFormatters方法

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter{

   @Override
   public void addFormatters(FormatterRegistry registry){
      registry.addConverter(new StringToShapeConverter());
   }
}

If you are using xml configuration you can use the mvc:annotation-driven element to specify the conversion-service to use. 如果您使用的是xml配置,则可以使用mvc:annotation-driven元素指定要使用的转换服务。 Then register your converter using the FormattingConversionSErviceFactoryBean 然后使用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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM