Как привязать объект подкласса в весенней форме, отправить как modelAttribute

У меня есть

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>

когда я отправляю форму с круглым объектом. На стороне контроллера ModelAttribute не дает экземпляр Round . это дает только экземпляр формы. Как это сделать


person S.M.V.A    schedule 02.06.2016    source источник
comment
Статический тип — это Shape независимо от того, что вы делаете. Это не имеет ничего общего с Spring; это проблема со статической/динамической типизацией. Вы можете создать или создать фабрику/виртуальный конструктор.   -  person duffymo    schedule 02.06.2016
comment
почему вы не можете отправить Round из формы   -  person Priyamal    schedule 03.06.2016
comment
@Priyamal, для каждой формы есть больше форм и одна и та же форма.   -  person S.M.V.A    schedule 03.06.2016


Ответы (3)


Ты не сможешь это сделать. Потому что это два разных жизненных цикла запросов.

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

Когда вышеуказанный запрос выполняется, даже если вы добавили объект Round в mav, он был преобразован в ответ html и отправлен обратно клиенту.

Поэтому, когда нижеследующий запрос появляется следующим, когда вы отправляете форму, это совершенно отдельный запрос, и Spring не имеет возможности определить, какой тип объекта был добавлен для предыдущего запроса.

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

         }
    }

Но вы можете попробовать изучить @SessionAttributes, используя это, вы сможете поддерживать один и тот же объект в разных запросах.

person Amit.rk3    schedule 02.06.2016

это никогда не сработает

<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 и использовать его для cast объекта Shape

     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; 
       }
    }
person Priyamal    schedule 03.06.2016

Можно указать подкласс, к которому вам нужно привязаться. Вы должны добавить дополнительный параметр (скрытый ввод) в свою форму, который указывает тип, к которому необходимо привязаться. Это поле должно иметь то же имя, что и атрибут модели в этой форме дела. Затем вам нужно реализовать преобразователь, который преобразует это значение строкового параметра в фактический экземпляр, к которому вам нужно привязаться.

Ниже приведены изменения, которые необходимо реализовать.

1) В вашем jsp добавьте скрытый ввод внутри вашего

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

2) Реализовать конвертер для преобразования из строки в форму

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>
person ekem chitsiga    schedule 03.06.2016