facebook

Registering and using multiple resources

  1. MyEclipse IDE
  2.  > 
  3. Spring Development
Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #318262 Reply

    Hi, I’d like to know if there’s a way to register multiple resources automatically, as done with the tag

    <context:component-scan base-package="this.is.my.package.web" />

    Similarly I would like to do something like

    <context:component-scan base-package="resources/bundles/*" />

    I scaffolded with MyEclipse for Spring from a db with around 50 tables, and it generated a resource file for every entity:

    resources/bundles/application-resources.properties
    resources/bundles/user-resources.properties
    resources/bundles/generaldata-resources.properties
    resources/bundles/log-resources.properties

    and so on.
    Now I’m implementing validation for the various web forms, so I need to access to the various properties files. Do I have to put every resource file in MyApplication-web-context.xml, with a structure like this:

    
    <bean id="messageSource"
            class="org.springframework.context.support.ResourceBundleMessageSource">
            <property name="basename" value="this/is/my/package/resources/bundles/user" />
        </bean>
    

    ?

    I’ve seen various examples in the using of resources to store error strings, so I tried using my resource file in my validator in this way:

    
    generated/delidete/validator/SoggettiWebValidator.java
    public void validate(Object target, Errors errors) 
    {
    .....
    errors.rejectValue("soggettiCodiceFiscale", "required.soggettiCodiceFiscale", "default4");
    ...
    }
    

    This is what’s in my resource:

    
    /bundles/soggetti-resources.properties
    ....
    required.soggettiCodiceFiscale=Il codice fiscale non e' corretto
    ....
    

    My bean:

    
    generated/delidete/webdomain/SoggettiWeb.java
    
    public class SoggettiWeb implements Serializable {
        ...
            ...
            String soggettiCodiceFiscale;
            ...        
            ...
            public void setSoggettiCodiceFiscale(String soggettiCodiceFiscale) {
            this.soggettiCodiceFiscale = soggettiCodiceFiscale;
        }
    
        public String getSoggettiCodiceFiscale() {
            return this.soggettiCodiceFiscale;
        }
    }
    

    My jsps correctly see resources, thanks to the imports

    <fmt:setBundle basename="bundles.soggetti-resources"/>

    ,
    I don’t know how to use the same messages in my validators.
    Please shed some light on me 😀
    Thanks in advance!!

    #318265 Reply

    jayperkins
    Member

    There is a spring class called org.springframework.context.support.ReloadableResourceBundleMessageSource which supports the classpath: prefix, but I don’t believe it supports wildcards. Plus I believe there may be some overhead because it is reloadable.

    You can create a custom MessageSource implementation that handles pattern matching and the classpath prefix.

    Here is the class I used to test it:
    import java.io.IOException;
    import java.util.HashSet;
    import java.util.Set;

    import org.apache.commons.lang.StringUtils;
    import org.springframework.context.support.ResourceBundleMessageSource;
    import org.springframework.core.io.Resource;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

    public class PatternMatchingResourceBundleMessageSource extends ResourceBundleMessageSource {
    public void setBasenames(String[] basenames){
    PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(getBundleClassLoader());;
    Set<Resource> allResources = new HashSet<Resource>();
    Resource[] resources = null;

    for (String baseName : basenames){
    try {
    resources = resolver.getResources(baseName);
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    if (resources != null){
    for (Resource resource : resources){
    allResources.add(resource);
    }
    }
    }

    basenames = new String[allResources.size()];
    String resourceURI;
    int bundlesIndex;
    int index = 0;
    for (Resource resource : allResources){
    try {
    resourceURI = resource.getURI().toString();
    bundlesIndex = resourceURI.indexOf(“bundles”);
    if (bundlesIndex > -1){
    resourceURI = resourceURI.substring(bundlesIndex);
    resourceURI = StringUtils.substringBeforeLast(resourceURI, “.”);
    }

    basenames[index++] = resourceURI;
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }

    super.setBasenames(basenames);
    }
    }

    And the config entry is as follows:
    <bean id=”messageSource”
    class=”org.test.util.PatternMatchingResourceBundleMessageSource”>
    <property name=”basename” value=”classpath*:bundles/*-resources.properties” />
    </bean>

    HTH,

    Jay

    #318294 Reply

    first of all thank you for your kind help.
    Now, I created your class and registered the bean. How should I access the various messages?
    Suppose I’m in the class SoggettiValidator.java (it’s the validator for the class Soggetti).
    In the method validate(), how should I access soggetti-resources.properties to get the message for a rejected field?

    Now my code is as following:

    
    errors.rejectValue("soggettiCodiceFiscale", "required.soggettiCodiceFiscale", "default4");
    

    where errors is the Error field, “soggettiCodiceFiscale” is the property of the Soggetti bean, “required.soggettiCodiceFiscale” is the message code in the file soggetti-resources.properties and “default4” is the fallback message.
    I tried printing out errors variable, and this is what I get:

    
    Field error in object 'soggetti' on field 'soggettiCodiceFiscale': rejected value []; codes [required.soggettiCodiceFiscale.soggetti.soggettiCodiceFiscale,required.soggettiCodiceFiscale.soggettiCodiceFiscale,required.soggettiCodiceFiscale.java.lang.String,required.soggettiCodiceFiscale]; arguments []; default message [default4]
    

    EDIT: while I was writing I decided to give it a try BEFORE trying anything else, leaving my code as is, just to try if I had initialized everything correctly. The surprising thing is (for me of course) that it works without me doing anything else! In the jsp it shows the correct message, not the fallback one.

    A very big thank you Jay!

Viewing 3 posts - 1 through 3 (of 3 total)
Reply To: Registering and using multiple resources

You must be logged in to post in the forum log in