Results 1 to 6 of 6

Thread: Translating PropertyEditor exceptions to messages

  1. #1

    Default Translating PropertyEditor exceptions to messages

    My PropertyEditor class resolves "id strings" (essentially primary keys) to domain objects of some specific class.
    A manager class (could be a Dao or higher level service) is injected for this purpose.

    These are three possible failure points in the setAsText method execution:

    1) The string representation being converted is not of the correct format.(NumberFormatException)
    2) No object can be found for the supplied id.(ObjectNotFoundException thrown by manager)
    3) The object exists, but is not authorized for use by the current user.(SecurityException thrown by manager)

    Code:
    public class FoobarPropertyEditor extends PropertyEditorSupport
    {
        private FoobarManager manager;
    		
    	public FoobarPropertyEditor(FoobarManager manager)
    	{
    		this.manager = manager;
    	}
    	
    	public String getAsText()
        {
            Foobar foobar = (Foobar)getValue();
            if(foobar == null) return "";
            else return String.valueOf(foobar.getId());
        }
    
        public void setAsText(String text) throws IllegalArgumentException
        {
    		try
    		{
    			int id = Integer.parseInt(text);
    			foobar = manager.find(id);
    			setValue(foobar);
    		}
    		catch(NumberFormatException nfe)
    		{
    			throw new IllegalArgumentException("Invalid value", nfe);
    		}
    		catch(EntityNotFoundException enfe)
    		{
    			throw new IllegalArgumentException("Foobar not found", enfe)
    		}
    		catch(SecurityException se)
    		{
    			throw new IllegalArgumentException("Access to foobar denied", se)
    		}
        }
    }
    I can't find much information in the reference docs or the sample apps on how to handle exceptions from custom PropertyEditors.
    How do I customize the translation from various IllegalArgumentExceptions to user-friendly messages?

    Some piece of code should examine the IllegalArgumentException, retrieve the nested cause, and work with that. But how do I inject such logic into the DataBinder?

  2. #2

    Default

    I've explored the DataBinder and BeanWrapper source a bit...

    Unfortunately the current implementation of the DataBinder swallows the original exception cause coming from a PropertyEditor (through the BeanWrapper).

    The relevant source snippet is quoted below (spring 1.1.2):
    (DataBinder.java, lines 312-326)
    Code:
    try {
    	// bind request parameters onto params, ignoring unknown properties
    	this.errors.getBeanWrapper().setPropertyValues(pvs, true);
    }
    catch (PropertyAccessExceptionsException ex) {
    	PropertyAccessException[] exs = ex.getPropertyAccessExceptions();
    	for &#40;int i = 0; i < exs.length; i++&#41; &#123;
    		// create field with the exceptions's code, e.g. "typeMismatch"
    		String field = exs&#91;i&#93;.getPropertyChangeEvent&#40;&#41;.getPropertyName&#40;&#41;;
    		this.errors.addError&#40;
    				new FieldError&#40;this.errors.getObjectName&#40;&#41;, field, exs&#91;i&#93;.getPropertyChangeEvent&#40;&#41;.getNewValue&#40;&#41;, true,
    				this.errors.resolveMessageCodes&#40;exs&#91;i&#93;.getErrorCode&#40;&#41;, field&#41;,
    				getArgumentsForBindingError&#40;field&#41;, exs&#91;i&#93;.getLocalizedMessage&#40;&#41;&#41;&#41;;
    	&#125;
    &#125;
    The PropertyAccessExceptions coming from the BeanWrapper have a cause property (derived form Throwable).
    However, this piece of information is not stored in the FieldError instance created.
    All FieldErrors caused by PropertyEditor exceptions are coded as "typeMismatch", since BeanWrapperImpl#doTypeConversionIfNecessary() translates all IllegalArgumentExceptions to TypeMismatchExceptions.

    I'm quite curious how Spring's claim of being able to "do away with ActionForms and bind to your domain model" works out for others.
    Having built quite a number of enterprise applications, I know that there are quite a number of failure paths for translating an String id to a live domain object instance.

    How can I bind to a rich domain model other then by using PropertyEditors?
    How can I use PropertyEditors if I can't differentiate between various, distinct, potential failures?

  3. #3
    Join Date
    Oct 2004
    Location
    NYC, USA
    Posts
    13

    Default

    you might want to take a look at the Validator interface (org.springframework.validation)....

    you simply implement a validator and register it with your controller

    in the validate() method of your validator, you simply complete all of your tests, and set appropriate errors.. .which are then displayed by the status.errorMessage part of your spring:bind tags

  4. #4

    Default

    Validation takes place after binding.

    Since the binding failure for the field hides the reason for the failure, there's no data for the validation phase to work with.

  5. #5
    Join Date
    Nov 2004
    Location
    London ON, Canada
    Posts
    5

    Default user-friendly messages

    In order to customize the translation from various IllegalArgumentExceptions to user-friendly messages you could take a look at "DefaultMessageCodesResolver"


    E.g. in case of code "typeMismatch", object name "user", field "age":

    try "typeMismatch.user.age"

  6. #6

    Default Re: user-friendly messages

    Quote Originally Posted by njayalath
    In order to customize the translation from various IllegalArgumentExceptions to user-friendly messages you could take a look at "DefaultMessageCodesResolver"


    E.g. in case of code "typeMismatch", object name "user", field "age":

    try "typeMismatch.user.age"
    The problem with above work-around is that the nondescriptive typeMismatch.user.age could be caused by different domain exceptions.

    I want to be able to distinguish between
    -object not found
    -security failure
    -some domain specific logic preventing the user from obtaining the entity instance
    -perhaps an actual type mismatch (e.g. user filled in nonsense input)

    By the time my message translator gets a chance, the relevant information has already been dropped by the databinder.

    To summarize, the functionality I'm after is a strategy interface to let the binding infrastructure translate IllegalArgumentExceptions (actually the nested cause) thrown by a PropertyEditor to custom message codes.

Similar Threads

  1. Newbie: logging acegi messages
    By cwong in forum Security
    Replies: 2
    Last Post: Sep 28th, 2007, 05:47 PM
  2. Replies: 4
    Last Post: May 12th, 2006, 02:50 AM
  3. getting messages from the message source
    By derrickhackman in forum Web
    Replies: 10
    Last Post: Sep 27th, 2005, 04:27 PM
  4. Replies: 7
    Last Post: Aug 1st, 2005, 01:38 AM
  5. Custom Error Messages in Login JSP
    By kbaum in forum Security
    Replies: 2
    Last Post: Dec 9th, 2004, 03:28 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •