es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Registración adicional de servlet en Spring Boot

Tengo una aplicación Spring Boot Web MVC que se encuentra en la raíz de la aplicación. Estoy tratando de añadir un servlet de terceros (conector CKFinder Java) a esta aplicación.

Lo he logrado con lo siguiente:

@Bean
public ServletRegistrationBean<ckfinderservlet> registerCkFinder() {
    ServletRegistrationBean<ckfinderservlet> bean =
            new ServletRegistrationBean<>(new CKFinderServlet(), "/ckfinder/*");
    bean.setLoadOnStartup(-1);
    bean.setInitParameters(
            Map.of("scan-path", "<nombre del="" paquete="">"));
    bean.setMultipartConfig(new MultipartConfigElement("/tmp/upload"));
    return bean;
}

El sitio web principal sigue funcionando correctamente, pero cuando intento llamar al servlet CKFinder, obtengo una serie de errores que indican problemas de inicialización al evaluar los parámetros de @Value(...) al inyectar automáticamente mis interceptores y controladores (no entiendo completamente por qué está construyendo los controladores).

Después de hacer algunas investigaciones, tengo la sensación de que tiene que ver con los contextos de la aplicación. Quiero compartir información de contexto (como la información de seguridad, usuario conectado, etc.), pero por lo demás realmente no necesito ninguna de las otras funcionalidades de Spring MVC mientras se ejecuta el servlet.

Mi pregunta es triple:

  1. ¿Tengo razón al pensar que tiene que ver con los contextos?
  2. ¿Cómo registro el servlet para que cuando sea llamado, se evalúen correctamente las anotaciones @Value() y demás funcionalidades de Spring?
    O
  3. ¿Cómo registro el servlet con un nuevo contexto para que no herede ni intente inicializar todos los componentes de Spring MVC?

También estoy considerando poner un envoltorio de controlador alrededor del servlet, pero eso parece excesivo para algo que debería “funcionar sin problemas”.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Solución para agregar el Servlet CKFinder a una aplicación Spring Boot Web MVC

    Problema:

    Tienes una aplicación Spring Boot Web MVC que se encuentra en la raíz de la aplicación. Estás intentando agregar un servlet de terceros (Conector CKFinder Java) a esta aplicación. Pero después de agregar el Servlet, estás teniendo problemas de inicialización al evaluar los parámetros @Value() al auto-cablear los interceptores y controladores. Esto se debe a los componentes heredados de Spring MVC por parte del Servlet.

    Solución:

    Enfoque 1:

    Para registrar el Servlet de manera que cuando se llame, los @Value() y otros elementos de Spring se evalúen correctamente, debes sobrescribir el método:

    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)
    

    en tu clase de configuración, y establecer el estado de manejo del servlet predeterminado como false. Esto evitará que el Servlet herede la configuración de Spring MVC.

    @Configuration
    @EnableWebMvc
    public class WebMvcConfig implements WebMvcConfigurer {
    
        @Override
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
            configurer.enable();
        }
    
        // otros métodos de configuración
    
    }
    

    Enfoque 2:

    Para registrar el Servlet con un nuevo contexto de manera que no herede y trate de inicializar todos los componentes de Spring MVC, debes crear un nuevo ServletRegistrationBean con un nuevo ApplicationContext. Así es cómo puedes hacerlo:

    @Configuration
    public class CKFinderConfiguration {
    
        @Bean
        public ServletRegistrationBean<ckfinderservlet> registerCkFinder() {
    
            AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
            context.register(CKFinderConfiguration.class);
    
            ServletRegistrationBean<ckfinderservlet> bean = new ServletRegistrationBean<>(
                    new CKFinderServlet(), "/ckfinder/*");
            bean.setMultipartConfig(new MultipartConfigElement("/tmp"));
    
            // Configurando el nuevo contexto para el Servlet
            bean.setApplicationContext(context);
            bean.setLoadOnStartup(1);
    
            return bean;
        }
    
        // Otras configuraciones para el nuevo contexto
    
    }
    

    Esto crea un nuevo ApplicationContext para el Servlet y no heredará ninguna configuración de Spring MVC del contexto padre.

    Enfoque 3:

    También puedes crear un envoltorio de controlador alrededor del Servlet, que manejará toda la funcionalidad de Spring MVC mientras ejecuta el Servlet. Pero, este enfoque parece excesivo para algo que debería “simplemente funcionar”.

Comments are closed.