2010-11-09 14 views
6

Esperaba un poco de ayuda con un problema que estoy teniendo con los archivos de propiedades en Spring. Por lo que la configuración que tengo es de esta manera:Recarga del archivo de propiedades que se carga usando setBundle

opto-mapping.properties - Esta se encuentra en mi carpeta src y contiene traducciones de mis recursos optimizados de este modo:

generic-min.css=4037119659.css 

Este archivo se actualiza Properies cada vez que se ejecuta la compilación 'optimizar'. Luego uso

<fmt:setBundle basename="opto-mapping" /> 

Para importar mi archivo de propiedades en mi jsp deseado. A continuación, haciendo referencia al contenido mediante:

<fmt:message key='generic-min.css' /> 

Todo esto funciona muy bien excepto que el archivo de propiedades requiere reiniciar un gato que ser recargada. No quiero tener que comenzar a quitar sitios cada vez que se actualiza un recurso. Me gustaría que el archivo de propiedades se vuelva a cargar automáticamente cada cierto tiempo.

Intenté actualizar un bean existente en mi spring-context.xml para volver a cargar este archivo de propiedades como hago con las traducciones, pero esto no funcionó, más que probablemente debido a la ubicación de los archivos opto-mapping.properties, pero ves que tiene que estar en esa ubicación para cargar utilizando fmt: setBundle.

<bean id="messageSource" 
     class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 
     <property name="cacheSeconds"> 
      <value>1</value> 
     </property> 
     <property name="basenames"> 
      <list> 
       <value>WEB-INF/translations/translations</value> 
       <value>WEB-INF/classes/opto-mapping</value> 
      </list> 
     </property> 
</bean> 

Cualquier ayuda o un punto en la dirección correcta sería muy apreciada en este momento difícil.

Espero que todo esto senese y muchas gracias de antemano!

G.

Respuesta

1

Hay algunas cosas que puedes probar.

<fmt:setBundle> eventualmente llamará a ResourceBundle.getBundle(String, Locale, ClassLoader), donde la cadena será su nombre base y el cargador de clases será Thread.currentThread().getContextClassLoader(). Si está utilizando JDK 1.6, puede intentar usar ResourceBundle.clearCache(ClassLoader) para borrar la memoria caché del paquete. Tendría sentido hacer esto en un filtro de servlet y combinarlo con alguna otra lógica para determinar cuándo se debe borrar la memoria caché.

Otro ángulo es tomar un control más directo sobre la carga del archivo de propiedades y la configuración de JSTL.Una vez más, haciendo uso de un filtro (ignorando el manejo de excepciones):

ClassLoader ctxLoader = Thread.currentThread().getContextClassLoader(); 
URL propsURL = ctxLoader.getResource("opto-mapping.properties"); 
URLConnection propsConn = propsURL.openConnection(); 
long propsLastModified = propsConn.getLastModified(); 
// decide if you want to reload... 
propsConn.setUseCaches(false); 
InputStream propsIn = propsConn.getInputStream(); 
ResourceBundle propsBundle = new PropertyResourceBundle(propsIn); 
propsIn.close(); 
LocalizationContext propsCtx = new LocalizationContext(propsBundle); 
ServletContext servletCtx = this.filterConfig.getServletContext(); 
Config.set(servletCtx, Config.FMT_LOCALIZATION_CONTEXT, propsCtx); 

continuación, sólo puede utilizar <fmt:message> en sus páginas. Puede encontrar los documentos para LocalizationContext y Config en el JSTL API. son posibles

Muchas otras variaciones, pero asegúrese de echar un vistazo a las adiciones más reciente ResourceBundle (incluyendo ResourceBundle.Control) a JDK 1.6, tenga en cuenta la funcionalidad del API "de bajo nivel" como URLConnection, y familiarizarse con los aspectos más programáticos de JSTL están disponibles a través de su API.

4

Tomcat no se volverá a cargar los recursos que se encuentran en la ruta de clase. Esto se afirma en el javadoc para ReloadableResourceBundleMessageSource:

Dado que los servidores de aplicaciones suelen almacenar en caché todos los archivos cargados desde la ruta de clases, es necesario recursos de almacenamiento en otro lugar (por ejemplo, en el directorio "WEB-INF" de un Web aplicación). De lo contrario, los cambios de archivos en el classpath no se reflejarán en la aplicación.

Tales ubicaciones de classpath incluyen WEB-INF/classes, y no serán lanzadas.

Intenta mover opto-mapping.properties en otro lugar (por ejemplo, WEB-INF/messages), y pruébalo entonces.

+0

Impresionante, muchas gracias por sus comentarios. Solo espero que esto no cause un problema con la forma en que estoy cargando mi archivo de propiedades (usando ). –

+0

Voy a probarlo mañana y publicar mis conclusiones aquí. ¡Gracias! –

5

Gracias a ambos por sus respuestas. Ahora lo tengo funcionando y pensé que compartiría la riqueza.

Por lo tanto, moví mi archivo de propiedades de la carpeta src a WEB-INF/properties.

He actualizado la siguiente frijol de cargar los archivos de propiedades:

<bean id="messageSource" 
     class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 
     <property name="cacheSeconds"> 
      <value>1</value> 
     </property> 
     <property name="basenames"> 
      <list> 
       <value>WEB-INF/translations/translations</value> 
       <value>WEB-INF/properties/opto-mapping</value> 
      </list> 
     </property> 
    </bean> 

Ahora, con anterioridad que estaba usando setBundle cargar en mis propiedades de archivo como este:

<fmt:setBundle basename="opto-mapping" /> 

pero he encontrado que obviamente mi archivo de propiedades ya no se estaba cargando porque lo había movido. Pero debido a mi configuración de beans, el nuevo archivo de propiedades se estaba cargando, pero mi setBundle estaba sobreescribiendo eso.

Entonces, la solución fue eliminar el setBundle y ahora mi archivo de propiedades se está recargando.

¡Gracias nuevamente!

Cuestiones relacionadas