Announcement Announcement Module
Collapse
No announcement yet.
Custom Converter Example Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    How can I customize the error message shown to the user, when a conversion exception is thrown?

    Comment


    • #17
      I'm having the same problem as you, as i cannot validate german date patterns. Could you resolve your problem?

      Btw. my CustomConversionService is loaded while booting spring but not used at all. If i use bindings i get an error that spring doesn't know anything about that converter.

      Originally posted by psliwa View Post
      I'm having a similar problem to desank above where I cannot get my custom converter to work. What I'm trying to accomplish is provide a different pattern for the StringToDate converter that comes with webflow 2.0.3. I don't know if there is a way to do this other than what is mentioned above.

      What I've done is create a custom conversion service with an addDefaultConverters() method of:
      Code:
          protected void addDefaultConverters() 
          {
              super.addDefaultConverters();
              StringToDate myStringToDate = new StringToDate();
              myStringToDate.setPattern("yyyyMMdd");
              addConverter(myStringToDate);
          }
      I register it in my config files like in this thread's earlier posts, but the DefaultConversionService is always run after my custom conversion service, so my "customized" string to date converter is overwritten.

      Can anyone tell me how to change the pattern that StringToDate uses, either following this path or another one? I really don't want to add a bunch of "<binder>" entries for my view-states because many of my pages have a lot of fields to bind and this wouldn't support maintenance really well.

      Comment


      • #18
        I can not find Money class in the book-mvc example project.

        I would like to know how to write Money.valueOf(string) method.

        Comment


        • #19
          Hello Everyone,

          I'm using a custom conversion service in Webflow 2.0.5 and I have a bit of an issue.

          I want my converter (StringToCountry) to use a spring managed service to lookup the country. Unfortunately as the addDefaultConverters() method requires that I pass it an object there doesn't seem to be a neat spring like method of doing this. Things that I have tried;

          (1) My first thought was to pass the services into my custom converted service and then pass them into my converters through their constructors. Unfortunately the addDefaultConverters() method is called before spring injects the services into the converter service so they are unavailable.
          (2) Grab the service from spring directly in the converter (yuk).
          (3) Directly call the setService method on the converter as it is set by spring in the custom conversion service.

          Currently I am using method 3 although it looks like it will become a pain to maintain and I am looking for more options.

          It seems to me that if you can't access your data services from the converter then there is very little you can do with them. Am I correct in thinking they are only really intended for converting when all the information required to create the object is contained in the string passed from the form?

          These converters seem very neat and I hope they aren't limited like this.

          Comment


          • #20
            Converters should definitely be capable of being injected with dependencies managed by Spring. They're stateless, thread-safe, good candidates to hold references to other stateless objects if that is what they need to do.

            I see your point about the DefaultConversionService limitation. I would suggest creating a subclass of DefaultConversionService that supports injection of your services, implements InitializingBean, and on the afterPropertiesSet() init callback registers your converters. I would also suggest opening an improvement JIRA to make this easier in a future SWF release--please reference your forum post!

            Keith

            Comment


            • #21
              Thanks Keith, your suggestion worked like a charm and improved my method in just a few minutes.

              I've opened a Jira issue here if anyone else is interested in tracking this.

              Regards,

              Ben

              Comment


              • #22
                Like several of the posters before, I'm trying to set up a converter to be used for explicit conversion to SelectItem lists. I'm using SWF 2.0.3, and am attempting to follow the instructions offered at the beginning of the thread. From some of the replies, I was anticipating running into a wall, but I seem to have hit it much sooner than expected.

                I don't think SWF recognizes the alias to my converter. Here's what I've got:

                SelectItemsConverter.java
                Code:
                public class SelectItemsConverter implements Converter {
                
                  public Class getSourceClass() {
                    return Object.class;
                  }
                
                  public Class getTargetClass() {
                    return SelectItem.class;
                  }
                
                  public Object convertSourceToTargetClass(Object source, 
                                                           Class targetClass) throws Exception {
                    if (source instanceof List) {
                      List<SelectItem> result = new ArrayList<SelectItem>();
                      List sourceList = (List)source;
                      for (Object next: sourceList) {
                        if (next != null) {
                          result.add(new SelectItem(next, next.toString()));
                        }
                      }
                      return result;
                    } else {
                      return null;
                    }
                  }
                }

                SelectItemsConversionService.java
                Code:
                public class SelectItemsConversionService extends DefaultConversionService {
                  @Override
                  protected void addDefaultConverters() {
                    super.addDefaultConverters();
                
                    // registers a custom converter reference-able by id and applied when requested
                    addConverter("selectItems", new SelectItemsConverter());
                  }
                }

                webflow-config.xml snippet
                Code:
                <bean id="selectItemsConversionService" class="package.of.my.converters.SelectItemsConversionService"/>
                    
                    <faces:flow-builder-services id="facesFlowBuilderServices"
                            expression-parser="expressionParser" conversion-service="selectItemsConversionService"/>
                            
                    <bean id="expressionParser" 
                        class="org.springframework.webflow.expression.WebFlowOgnlExpressionParser">
                      <property name="conversionService" ref="selectItemsConversionService"/>
                    </bean>

                In a view state in a flow
                Code:
                <on-render>
                      <evaluate expression="myObject.getMyList()" result="viewScope.mySelectItemsList"
                          result-type="selectItems"/>
                    </on-render>

                When I try to run my app, I get an error 500 when the flow containing the view state with the above snippet launches:

                Code:
                java.lang.IllegalArgumentException: Unable to load class 'selectItems'	at org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder.toClass(FlowModelFlowBuilder.java:953)
                I'm fairly certain this is a simple bug in the configuration I'm overlooking, but I can't seem to see it. Any help?

                Comment


                • #23
                  Problem with converter in JSF integration

                  Hello,

                  It's a newbie here, so if the question is stupid please disregard. I have tried to create a small CRUD prototype using WebFlow 2.0.5, JSF, Hibernate and MySQL. I'm planning to add Spring Security to this prototype but I haven't been able to reach that point yet since I'm having several other problems with the flow.

                  The flow model includes a main flow with a view rendering a datatable consisting of an object type called company:

                  Code:
                  <view-state id="list">
                  		<on-render>
                  			<evaluate expression="org_service.getList('Company')" result="flowScope.orgs" result-type="dataModel" />
                  		</on-render>
                  		<transition on="edit" to="doEdit">
                  ...
                  And I have a couple of subflows, one for edit each company object properties and one for persisting a new object. As soon as the subflows views render only primitive type properties of the object, everything works like a charm. Edits are persisted in the database, and displayed when the subflows complete and return back to the main flow. As soon as an object property of the company object is added to the form, the post transition stalls. By looking at the logs, I have been driven to the issue of converters and binding non-default types:

                  Code:
                  ...with root cause [org.springframework.binding.convert.ConversionExecutorNotFoundException:
                   No ConversionExecutor found for converting
                  from sourceClass [com.balkan.party.util.Email] to target class [java.lang.String]]
                  After reading carefully the instructions at the first page of this post, I set out to creating a custom converter for my Email type:

                  Code:
                  public class StringToEmail extends StringToObject {
                  	  
                  	public StringToEmail() {
                  	        super(Email.class);
                  	    }
                  
                  	    @SuppressWarnings("unchecked")
                  	    @Override
                  		protected Object toObject(String string, Class objectClass) {
                  	        Email email = new Email(string);
                  	    	return email;
                  	    }
                  
                  	    @Override
                  	    protected String toString(Object object) {
                  	        Email email = (Email) object;
                  	    	return email.toString();
                  	    }
                  	}
                  and extending the DefaultConversionService to include my new converter:

                  Code:
                  @Component("conversionService")
                  public class ApplicationConversionService extends DefaultConversionService {
                  
                  	    @Override
                  	    protected void addDefaultConverters() {
                  	        super.addDefaultConverters();
                  	        addConverter(new StringToEmail());
                  	    }
                  }
                  Now unlike the suggested course of action, my config like booking.faces sample includes:

                  Code:
                  <faces:flow-builder-services id="facesFlowBuilderServices" conversion-service="conversionService" />
                  Since, I'm using 2.0.5 the workaround with the expressionParser is not needed (or so I have understood). When I load the application, I receive the following error:

                  Code:
                  java.lang.IllegalArgumentException: Unable to load class 'dataModel'
                  Which if I understand correctly means that I have managed to overwrite the default conversion of the datatable to dataModel, and my main flow list does not get displayed.

                  After all this lengthy text I can pose my question. Have I done something wrong with the custom converter or has the problem anything to do with the facesFlowBuilderServices?

                  Thank you.

                  Comment


                  • #24
                    Where are you attempting to have these converters be used? At this time, with the JSF integration, Web Flow type Converters cannot be used by JSF templates -- you'll need to register standard JSF converters for conversion to work at the view layer. In the next major release we're working on adapting registered Converters to work with JSF automatically...

                    Keith

                    Comment


                    • #25
                      I'm trying to use this converter explicitly in my flow definition in the on-render of a view-state to convert a list of strings into a list of SelectItems:

                      Code:
                      <on-render>
                            <evaluate expression="myObject.getMyList()" result="viewScope.mySelectItemsList"
                                result-type="selectItems"/>
                      </on-render>
                      I'm not using this converter in any JSF element or on any xhtml page.

                      Comment


                      • #26
                        You'll need to make sure your Converter is registered with an alias of "selectItems" when you register your custom ConversionService. For the dataModel conversions to work with your custom service, you'll also need to make sure the DataModelConverter converter is registered as well. See the custom FacesConversionService in the spring-faces example for how this converter is registered.

                        Comment


                        • #27
                          Thanks, Keith,

                          I extended FacesConversionService and added the aliases. To force the conversion in cases of List to List conversions (due to erasure in generics), I had to make my own empty ArrayList subclasses as the type when registering the aliases.

                          Comment


                          • #28
                            OK, I still can't override the default date format to be "dd MMM yy"

                            Am using Spring 2.5.6, Webflow 2.0.5 and have done the following.

                            1. Created my own conversionService which extends DefaultConversionService

                            Code:
                            @Override
                            	protected void addDefaultConverters() {
                            
                            		super.addDefaultConverters();
                            		StringToDate sToD = new StringToDate();
                            		sToD.setPattern("dd MMM yy");
                            		addConverter(sToD);
                            	}
                            I've tried putting super.addDefaultConverters(); as the first and last statement and neither approach works.

                            2. Wired my conversionService up into the webflow config.

                            Code:
                            <webflow:flow-builder-services id="flowBuilderServices" development="true"
                            	conversion-service="conversionService"
                            />
                            	
                            <bean id="conversionService" class=mypackage.ConversionService"/>
                            	
                            <bean id="expressionParser" class="org.springframework.webflow.expression.WebFlowOgnlExpressionParser">
                            	<property name="conversionService" ref="conversionService"/>
                            </bean>
                            3. Using the Spring form tag library, e.g. <form:input path="someCommandDatePath"/> and expecting this to cause the underlying date to be formatted as "dd MMM yy". The date shows up in the input field, it's just in the wrong format.

                            I would have thought overriding the standard date format, or installing a converted which could try to parse a range of date formats entered by the (ab)user would be a good example to include in the doco.

                            Comment


                            • #29
                              Hi,

                              it would really be great if we could *easily* use webflow Converters with spring:bind, spring:transform and form:input. Especially spring:transform as that would give us a generic displaying/formatting tag (even for pure views, no form submissions).

                              right now, it works a bit randomly: sometimes conversion is applied, sometimes it doesn't. For example, if I have a special Long<->String converter, submit my form then come back to my form view because some data is missing, conversion is not applied but if I refresh my view, it is...

                              Comment


                              • #30
                                Xavier,

                                This is something we're working on for Spring Framework and Spring Web Flow 3.0 right now. Will keep you posted.

                                Keith

                                Comment

                                Working...
                                X