绑定Spring Webflow中的选择列表对象

huangapple go评论59阅读模式
英文:

Binding Select List Objects in Spring Webflow

问题

以下是您要翻译的内容:

我有一个绑定到Java POJO的选择列表,位于thymeleaf表单上。我想要使用从此列表中选择的对象填充模型。

当使用Spring Boot控制器和将species对象绑定到animal模型时,下面的表单运行得非常好。但是,当我使用Spring Boot WebFlow时,出现了问题,对象无法绑定。

表单如下所示:

<form id="registration-form" th:object="${animal}"
	th:action="${flowExecutionUrl}" method="post">
	<div class="row"><div class="col">
		<label for="species">Species</label> 
		<select th:value="*{species}" id="species" name="species" class="form-control">
			<option selected disabled value="">-Choose-</option>
  			<option th:each="species : ${speciess}" 
				th:value="${species.id}" 
          		th:text="${species.description}">
			</option>
		</select>
	</div></div>
	<div class="form-group row"><div class="col-sm-10">
		<button type="submit" class="btn btn-primary" name="_eventId_next">Next
		&raquo;</button>

	</div></div>
</form>

我的Flow映射如下:

<on-start>
	<evaluate expression="animalServiceImpl.init()" result="flowScope.animal"/>
</on-start>

<view-state id="start" view="my/animal/new" model="flowScope.animal">
	<on-render>
    	<evaluate expression="holdingServiceImpl.findAll()" result="requestScope.holdings"/>
    	<evaluate expression="colorServiceImpl.findAll()" result="requestScope.colors"/>
    	<evaluate expression="genderServiceImpl.findAll()" result="requestScope.genders"/>
    	<evaluate expression="arrivalTypeServiceImpl.findAll()" result="requestScope.arrivalTypes"/>
    	<evaluate expression="speciesServiceImpl.findAll()" result="requestScope.speciess"/>
    	<evaluate expression="baitsTagsServiceImpl.findAll()" result="requestScope.baitsTags"/>
    	<evaluate expression="customTagServiceImpl.findAll()" result="requestScope.customTags"/>
    	<evaluate expression="breedServiceImpl.findAll()" result="requestScope.breeds"/>
    </on-render>
    <transition on="next" to="confirmation"/>
    <transition on="cancel" to="registrationCancelled" validate="false" bind="false" /> 
</view-state>

<view-state id="confirmation" view="my/animal/confirm" model="flowScope.animal">
    <transition on="back" to="start" />
    <transition on="submit" to="submitRegistration"/>
    <transition on="cancel" to="registrationCancelled" />
</view-state> 

当提交表单时,我收到以下错误消息:

[TargetAccessError@ecf873b mapping = parameter:'species' -> species, code = 'typeMismatch', error = true, errorCause = org.springframework.binding.expression.ValueCoercionException: Value could not be converted to target class; is a suitable type converter registered?, originalValue = 'bd8e962f-b334-4599-af69-d10352399b50', mappedValue = [null]]

Species对象的ID是UUID。

请帮助我解决这个问题。

我尝试将选择选项的th::value更改为"species"如下所示,但结果是下面的错误:

<option th:each="species : ${speciess}" 
	th:value="${species}" 
	th:text="${species.description}">
</option>

, code = 'propertyNotFound', error = true, errorCause = org.springframework.binding.expression.PropertyNotFoundException: Property not found, originalValue = [null], mappedValue = [null]], [TargetAccessError@1745e0fe mapping = parameter:'species' -> species, code = 'typeMismatch', error = true, errorCause = org.springframework.binding.expression.ValueCoercionException: Value could not be converted to target class; is a suitable type converter registered?, originalValue = 'Species{id=bd8e962f-b334-4599-af69-d10352399b50, description='Sheep'}', mappedValue = [null]]


<details>
<summary>英文:</summary>

I have a select list bound to Java POJOs on a thymeleaf form. I want to populate the model with the object selected from this list.

The form below works perfectly fine when using spring boot controllers and the species object is bound to the animal model. The problem arises when I use Spring Boot WebFlow. The object fails to bind.

```html
&lt;form id=&quot;registration-form&quot; th:object=&quot;${animal}&quot;
	th:action=&quot;${flowExecutionUrl}&quot; method=&quot;post&quot;&gt;
	&lt;div class=&quot;row&quot;&gt;&lt;div class=&quot;col&quot;&gt;
		&lt;label for=&quot;species&quot;&gt;Species&lt;/label&gt; 
		&lt;select  th:value=&quot;*{species}&quot; id=&quot;species&quot; name=&quot;species&quot; class=&quot;form-control&quot;&gt;
			&lt;option selected disabled value=&quot;&quot;&gt;-Choose-&lt;/option&gt;
  			&lt;option th:each=&quot;species : ${speciess}&quot; 
				th:value=&quot;${species.id}&quot; 
          		th:text=&quot;${species.description}&quot;&gt;
			&lt;/option&gt;
		&lt;/select&gt;
	&lt;/div&gt;&lt;/div&gt;
	&lt;div class=&quot;form-group row&quot;&gt;&lt;div class=&quot;col-sm-10&quot;&gt;
		&lt;button type=&quot;submit&quot; class=&quot;btn btn-primary&quot; name=&quot;_eventId_next&quot;&gt;Next
		&amp;raquo;&lt;/button&gt;

	&lt;/div&gt;&lt;/div&gt;
&lt;/form&gt;

My Flow mapping is as follows:

&lt;on-start&gt;
	&lt;evaluate expression=&quot;animalServiceImpl.init()&quot; result=&quot;flowScope.animal&quot;/&gt;
&lt;/on-start&gt;

&lt;view-state id=&quot;start&quot; view=&quot;my/animal/new&quot; model=&quot;flowScope.animal&quot;&gt;
	&lt;on-render&gt;
    	&lt;evaluate expression=&quot;holdingServiceImpl.findAll()&quot; result=&quot;requestScope.holdings&quot;/&gt;
    	&lt;evaluate expression=&quot;colorServiceImpl.findAll()&quot; result=&quot;requestScope.colors&quot;/&gt;
    	&lt;evaluate expression=&quot;genderServiceImpl.findAll()&quot; result=&quot;requestScope.genders&quot;/&gt;
    	&lt;evaluate expression=&quot;arrivalTypeServiceImpl.findAll()&quot; result=&quot;requestScope.arrivalTypes&quot;/&gt;
    	&lt;evaluate expression=&quot;speciesServiceImpl.findAll()&quot; result=&quot;requestScope.speciess&quot;/&gt;
    	&lt;evaluate expression=&quot;baitsTagsServiceImpl.findAll()&quot; result=&quot;requestScope.baitsTags&quot;/&gt;
    	&lt;evaluate expression=&quot;customTagServiceImpl.findAll()&quot; result=&quot;requestScope.customTags&quot;/&gt;
    	&lt;evaluate expression=&quot;breedServiceImpl.findAll()&quot; result=&quot;requestScope.breeds&quot;/&gt;
    &lt;/on-render&gt;
    &lt;transition on=&quot;next&quot; to=&quot;confirmation&quot;/&gt;
    &lt;transition on=&quot;cancel&quot; to=&quot;registrationCancelled&quot; validate=&quot;false&quot; bind=&quot;false&quot; /&gt; 
&lt;/view-state&gt;

&lt;view-state id=&quot;confirmation&quot; view=&quot;my/animal/confirm&quot; model=&quot;flowScope.animal&quot;&gt;
    &lt;transition on=&quot;back&quot; to=&quot;start&quot; /&gt;
    &lt;transition on=&quot;submit&quot; to=&quot;submitRegistration&quot;/&gt;
    &lt;transition on=&quot;cancel&quot; to=&quot;registrationCancelled&quot; /&gt;
&lt;/view-state&gt; 

I get the following error when submitting the form:

[TargetAccessError@ecf873b mapping = parameter:&#39;species&#39; -&gt; species, code = &#39;typeMismatch&#39;, error = true, errorCause = org.springframework.binding.expression.ValueCoercionException: Value could not be converted to target class; is a suitable type converter registered?, originalValue = &#39;bd8e962f-b334-4599-af69-d10352399b50&#39;, mappedValue = [null]]

The id of the Species object is UUID.

Please assist on what I can do to resolve this problem.

I tried changing the select option th::value to "species" as below but that resulted in the error below:

  			&lt;option th:each=&quot;species : ${speciess}&quot; 
				th:value=&quot;${species}&quot; 
          		th:text=&quot;${species.description}&quot;&gt;
			&lt;/option&gt;

, code = &#39;propertyNotFound&#39;, error = true, errorCause = org.springframework.binding.expression.PropertyNotFoundException: Property not found, originalValue = [null], mappedValue = [null]], [TargetAccessError@1745e0fe mapping = parameter:&#39;species&#39; -&gt; species, code = &#39;typeMismatch&#39;, error = true, errorCause = org.springframework.binding.expression.ValueCoercionException: Value could not be converted to target class; is a suitable type converter registered?, originalValue = &#39;Species{id=bd8e962f-b334-4599-af69-d10352399b50, description=&#39;Sheep&#39;}&#39;, mappedValue = [null]],

答案1

得分: 1

我通过在查看了Spring WebFlow引擎源代码后,使用以下代码解决了这个问题:

    @Bean(name="conversionService")
    GenericConversionService conversionService() {
    	GenericConversionService generic=new GenericConversionService();
    	generic.addConverter("StringToSpecies", new StringToSpeciesConverter());
		return generic;
    }
	@Bean
    FlowBuilderServices flowBuilderServices() {
    	
        return getFlowBuilderServicesBuilder() //
        		.setConversionService(this.conversionService())
                .setViewFactoryCreator(this.mvcViewFactoryCreator()) // 重要!
                .setValidator(this.localValidatorFacotryBean).build();
    }

我希望这个代码能为其他人解决问题。请注意,您正在实现的转换器应该是org.springframework.binding.convert.converters.Converter类型,并且与之保持一致。

英文:

I solved this problem by using the following code after going through the Spring WebFlow engine source code:

    @Bean(name=&quot;conversionService&quot;)
    GenericConversionService conversionService() {
    	GenericConversionService generic=new GenericConversionService();
    	generic.addConverter(&quot;StringToSpecies&quot;, new StringToSpeciesConverter());
		return generic;
    }
	@Bean
    FlowBuilderServices flowBuilderServices() {
    	
        return getFlowBuilderServicesBuilder() //
        		.setConversionService(this.conversionService())
                .setViewFactoryCreator(this.mvcViewFactoryCreator()) // Important!
                .setValidator(this.localValidatorFacotryBean).build();
    }

I hope this neatly solves the problem for others. Please note that the Converter you are implementing should be of type org.springframework.binding.convert.converters.Converter and be consistent with that.

huangapple
  • 本文由 发表于 2023年7月6日 15:44:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76626580.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定