Using <form:select> and <form:option> with converter but conversion does not happens, why? - spring

I have this form for creating an Enrichment:
<form:form method="post" action="..." modelAttribute="enrichment">
...
<form:select path="tag">
<form:options items="${tagList}" itemValue="id" itemLabel="label" />
</form:select>
...
The Enrichment class has a Tag attribute. So when th user has selected a tag in the Tag list, tag.id (wich is a String) is sent throught the form. I don't think I could directly send a tag object am I wright? So I wrote a Converter to convert a String to a Tag, according to http://static.springsource.org/spring/docs/current/spring-framework-reference/html/validation.html#core-convert-Converter-API. So I did this :
public class IdToTagConverter implements Converter<String, Tag> {
#Autowired
TagService tagService;
public Tag convert(String id) {
return tagService.findTagById(Integer.parseInt(id));
}
}
And I created the bean :
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="exemple.IdToTagConverter"/>
</list>
</property>
</bean>
And I thought it would do the convertion automatically. But the error message is still here :
[Failed to convert property value of type 'java.lang.String' to
required type 'exemple.Tag' for property 'tag'; nested exception is
java.lang.IllegalStateException: Cannot convert value of type
[java.lang.String] to required type [exemple.Tag] for property 'tag':
no matching editors or conversion strategy found]
What did I miss?

Found the solution here :
http://forum.springsource.org/showthread.php?84003-Converters-no-matching-editors-or-conversion-strategy-found
I just replaced
<mvc:annotation-driven />
by
<mvc:annotation-driven conversion-service="conversionService" />
and it worked. Why? Spring MVC Voodoo.

Looks like Spring is not aware of your converter, or Conversion Service. Follow this part of the documentation to register your custom converter - > http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/validation.html#format-configuring-FormattingConversionService

Related

Spring id-reference not working as expected

I'm working my way through the Spring Framework reference documentation with some very basic application code. So far, I've created an ApplicationContext from an XML file and loaded some beans. I believe I understand this process pretty well. I've loaded some basic beans with attributes based on fundamental types and found that straight-forward.
I'm now working on a composite bean with other beans as its attributes. So far, I've been able to set these attributes using a direct reference to a bean and an inner bean. However, when I try to get the idref element to work (see http://docs.spring.io/spring/docs/3.2.4.RELEASE/spring-framework-reference/html/beans.html#beans-idref-element) I get the following exception:
java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.example.BasicBean] for property 'idRef': no matching editors or conversion strategy found
Code snippets below:
Application Context XML
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<bean id="id-bean" class="com.example.BasicBean" scope="singleton">
<property name="value" value="31"/>
</bean>
<bean id="ref-bean" class="com.example.BasicBean" scope="singleton">
<property name="value" value="37"/>
</bean>
<bean id="cb" class="com.example.CompositeBean" scope="singleton">
<property name="id" ref="id-bean"/> <!-- works -->
<property name="inner"> <!-- works -->
<bean class="com.example.BasicBean">
<property name="value" value="43"/>
</bean>
</property>
<property name="idRef"> <!-- exception thrown -->
<idref bean="ref-bean"/>
</property>
</bean>
</beans>
Java App Code
public void main()
{
context = new ClassPathXmlApplicationContext("beans.xml");
CompositeBean cb = context.getBean("cb", CompositeBean.class);
}
Java Bean Code
public class CompositeBean
{
private BasicBean id;
private BasicBean idRef;
private BasicBean inner;
// Default constructor exists
// Setters, getters for each attribute exist
...
}
public class BasicBean
{
private int value;
// Default constructor exists
// Setters, getters for each attribute exist
...
}
Version info: I'm using Eclipse IDE (Kepler), Maven 3.1, Java 7 (1.7.45), Spring 3.2.4
Any thoughts on what I'm doing wrong?
Thanks #Farid for pointing out that I was mis-using the idref attribute in this instance. As the Spring doco points out (which I'd read several times and still missed this) it's designed for passing the id of a bean around a container and not the actual bean. So, stick to the first two means above (ref and inner bean) for passing a bean around.

char[] to String Conversion in Spring configuration

I have bean A that returns an attribute as char[] and another bean that expects an attribute as String and I would like to inject the attribute from bean A to bean B.
When I do this:
<bean id="B" class="....">
<property name="password" value="#{A.password}" />
</bean>
<bean id="A" class="...">
</bean>
The error I'm getting is:
Cannot convert value of type [char[]] to required type [java.lang.String] for property 'password': no matching editors or conversion strategy found
Any idea how to resolve this?
Perhaps by using an expression language syntax?
Perhaps by registering some sort of a converter like org.springframework.beans.propertyeditors.CharArrayPropertyEditor in the configuration before injecting the char[] attribute?
Looks like this will work:
<property name="password" value="#{new java.lang.String(A.password)}" />

spring 3.0 MVC seems to be ignoring messages.properties

Spring 3.0 MVC
First of all, I haven't found any documentation regarding messages.properties # springsource Everything I've found about overriding error messages has been on various forums. If anyone has a reference to where messages.properties is documented that'd be fantastic. Maybe messages.properties comes not from spring but a java spec?
I have tried following the advice on
JSR-303 Type Checking Before Binding My goal is to replace some type mismatch error messages with my own user friendly error messages
My situation is as follows:
Model
public class Test {
private int numberbomb;
public int getNumberbomb() {
return numberbomb;
}
public void setNumberbomb(int numberbomb) {
this.numberbomb = numberbomb;
}
}
myservlet.xml
<mvc:annotation-driven/>
jsp
<form:form id="test" method="post" modelAttribute="test">
<form:errors path="*"/>
<form:label path="numberbomb">numberbomb</form:label>
<form:input path="numberbomb"/>
</form:form>
classes\messages.properties
typeMismatch=bad value you bad bad person
test.numberbomb=you are driving me crazy with these bad inputs
Output from the form
Failed to convert property value of type java.lang.String to required type int for property numberbomb; nested exception is org.springframework.core.convert.ConversionFailedException: Unable to convert value "three" from type java.lang.String to type int; nested exception is java.lang.NumberFormatException: For input string: "three"
BindingResult.toString() within my controller
Field error in object 'test' on field 'numberbomb': rejected value [three]; codes [typeMismatch.test.numberbomb,typeMismatch.numberbomb,typeMismatch.int,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [test.numberbomb,numberbomb]; arguments []; default message [numberbomb]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'int' for property 'numberbomb'; nested exception is org.springframework.core.convert.ConversionFailedException: Unable to convert value "three" from type 'java.lang.String' to type 'int'; nested exception is java.lang.NumberFormatException: For input string: "three"]
Is displaying the error messages with <form:errors> the wrong way display custom error messages? Do I need to add something to spring config files to tell it to look at messages.properties? Spring seems to be ignoring my messages.properties file (which is located in the WEB-INF\classes folder)
Thanks for any ideas!
An associate of mine pointed me in the right direction. I changed the messageSource bean in myservlet.xml
from
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="messages" />
<property name="cacheSeconds" value="1" />
</bean>
to
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages"/>
</bean>
For whatever reason this solved the problem. Thanks associate! :)

Spring validation: can't convert from String to Date

I'm doing some spring form validation, however I'm getting:
Failed to convert property value of type 'java.lang.String' to required type 'ja
va.util.Date' for property 'birthdate'; nested exception is java.lang.Illega
lStateException: Cannot convert value of type [java.lang.String] to required typ
e [java.util.Date] for property 'birthdate': no matching editors or conversi
on strategy found
However, in my modelAttribute form I have:
#NotNull
#Past
#DateTimeFormat(style="S-")
private Date birthdate;
I thought the DateTimeFormat was responsible for this?
I'm using the hibernate-validator 4.0.
Theres a chance you'll have to use register a CustomDateEditor in your controller(s) to convert from a String to a Date. The example method below goes in your controller, but you'll have to change the date format to match whatever you're using.
#InitBinder
public void initBinder(WebDataBinder binder) {
CustomDateEditor editor = new CustomDateEditor(new SimpleDateFormat("MM/dd/yyyy"), true);
binder.registerCustomEditor(Date.class, editor);
}
In order to use #DateTimeFormat you need to install FormattingConversionServiceFactoryBean. <mvc:annotation-driven> does it implicitly, but if you cannot use it you need something like this:
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />
<bean id="annotationMethodHandlerAdapter"
class="org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="webBindingInitializer">
<bean id="configurableWebBindingInitializer"
class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="validator"><ref bean="validator"/>
<proeprty name = "conversionService" ref = "conversionService" />
</bean>
</property>
</bean>

BeanInstantiationException:Cannot convert type from java.lang.String to required type --- idref tag

I am new to spring and trying to understand the functionality of the idref tag
My config file is pasted here:
<bean id="AudioSystembean" class="com.springexample.AudioSystem">
<property name="price" value="200"/>
</bean>
<bean id="Vehicle1" class="com.SpringExample.Vehicle1">
<property name="vehicleType" value="CAR" />
<property name="audioSystem" >
<idref bean = "AudioSystembean" />
</property>
</bean>
When I am executing the code I am getting the error as : "BeanInstantiationException:Cannot convert type from java.lang.String to required type :com.SpringExampl.AudioSystem" [I dont remember the exact exception - I have the code at home]
If I use ref instead of idref it is working fine.
I tried google to understand about idref but could not get much information..
What am I doing wrong here?
In a Spring context, <idref> is used to pass the name of the referenced bean, rather than the bean itself (which is what <ref> does). So in your example:
<property name="audioSystem" >
<idref bean = "AudioSystembean" />
</property>
The audioSystem system property will be injected with the name of the AudioSystembean, i.e. the String "AudioSystembean".
This is not what you need here, though, you need the <ref> element, which passes a reference to the bean itself.

Resources