Vaadin 22 web.xml 和 Spring
Vaadin 22 with web.xml and Spring
我有一个使用 web.xml 和 Spring 的 Vaadin 18 原型。
该原型适用于使用 web.xml 和 vanilla Spring 的大型网络应用程序的端口。
我想在不删除 web.xml 或使用 Spring Boot.
的情况下更新前端
它在 Vaadin 18.0.6 中运行良好,但在 Vaadin 22.0.0 中启动失败:
java.lang.IllegalStateException: The application Lookup instance is not found in the interface com.vaadin.flow.server.VaadinContext instance. It means that the container has not executed Lookup initialization code: so either the container is not Servlet 3.0 compatible or project configuration is broken.
at com.vaadin.flow.server.startup.ApplicationConfiguration.lambda$get[=12=] (ApplicationConfiguration.java:58)
at com.vaadin.flow.server.VaadinServletContext.getAttribute (VaadinServletContext.java:73)
at com.vaadin.flow.server.startup.ApplicationConfiguration.get (ApplicationConfiguration.java:50)
初步挖掘表明不再支持disable.automatic.servlet.registration上下文参数。
让原型在 Vaadin 22 中工作需要什么?
这里是 web.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="false">
<!-- NOTE: metadata-complete="false" is required, in order to invoke
ClassLoaderAwareServletContainerInitializer subclasses (DevModeInitializer etc) -->
<context-param>
<!-- disables registration of the VaadinServlet. This is required as it is registered via AppServlet -->
<param-name>disable.automatic.servlet.registration</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>AppServlet</servlet-name>
<servlet-class>org.example.AppServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AppServlet</servlet-name>
<url-pattern>/app</url-pattern>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
</web-app>
以及对应的servlet:
/**
* Servlet to wire Vaadin into web.xml.
*/
public class AppServlet extends HttpServlet {
private SpringServlet delegate;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
ServletContext servletContext = getServletContext();
WebApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
delegate = new SpringServlet(context, false);
delegate.init(config);
}
@Override
public void destroy() {
if (delegate != null) {
delegate.destroy();
}
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
delegate.service(request, response);
}
}
根据this comment,解决方案是添加一个com.vaadin.flow.spring.VaadinApplicationConfiguration bean到applicationContext.xml.
这需要 才能工作,例如:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<bean class="com.vaadin.flow.spring.VaadinApplicationConfiguration"/>
</beans>
如果你不想使用 , VaadinApplicationConfiguration创建可以直接添加:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="com.vaadin.flow.spring.SpringApplicationConfigurationFactory"/>
<bean class="com.vaadin.flow.spring.SpringLookupInitializer.SpringApplicationContextInit"/>
</beans>
不推荐这样做,因为 SpringApplicationContextInit 是 Vaadin 内部的。
这是我想出的一个变体。我想使用 web.xml
和 Vaadin Spring,但不想使用 Spring 引导或 Spring 安全。
在我的 applicationContext.xml
文件中,我使用 <context:component-scan>
查找所有各种 Vaadin Spring 配置 bean,但随后排除了特定于 [=24= 的那些配置 bean ] 引导和 Spring 安全:
<!-- Vaadin annotation-based config, but excluding Spring Boot and Spring Security -->
<context:component-scan base-package="com.vaadin.flow.spring">
<context:exclude-filter type="regex" expression="com\.vaadin\.flow\.spring\.security\..*"/>
<context:exclude-filter type="regex" expression="com\.vaadin\.flow\.spring\.SpringBootAutoConfiguration"/>
<context:exclude-filter type="regex" expression="com\.vaadin\.flow\.spring\.SpringSecurityAutoConfiguration"/>
</context:component-scan>
我 没有 在我的 web.xml
中有 metadata-complete="false"
因为我通过 XML 进行所有其他 Spring 配置(只是遗留物)。
我有一个使用 web.xml 和 Spring 的 Vaadin 18 原型。
该原型适用于使用 web.xml 和 vanilla Spring 的大型网络应用程序的端口。 我想在不删除 web.xml 或使用 Spring Boot.
的情况下更新前端它在 Vaadin 18.0.6 中运行良好,但在 Vaadin 22.0.0 中启动失败:
java.lang.IllegalStateException: The application Lookup instance is not found in the interface com.vaadin.flow.server.VaadinContext instance. It means that the container has not executed Lookup initialization code: so either the container is not Servlet 3.0 compatible or project configuration is broken.
at com.vaadin.flow.server.startup.ApplicationConfiguration.lambda$get[=12=] (ApplicationConfiguration.java:58)
at com.vaadin.flow.server.VaadinServletContext.getAttribute (VaadinServletContext.java:73)
at com.vaadin.flow.server.startup.ApplicationConfiguration.get (ApplicationConfiguration.java:50)
初步挖掘表明不再支持disable.automatic.servlet.registration上下文参数。
让原型在 Vaadin 22 中工作需要什么?
这里是 web.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="false">
<!-- NOTE: metadata-complete="false" is required, in order to invoke
ClassLoaderAwareServletContainerInitializer subclasses (DevModeInitializer etc) -->
<context-param>
<!-- disables registration of the VaadinServlet. This is required as it is registered via AppServlet -->
<param-name>disable.automatic.servlet.registration</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>AppServlet</servlet-name>
<servlet-class>org.example.AppServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AppServlet</servlet-name>
<url-pattern>/app</url-pattern>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
</web-app>
以及对应的servlet:
/**
* Servlet to wire Vaadin into web.xml.
*/
public class AppServlet extends HttpServlet {
private SpringServlet delegate;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
ServletContext servletContext = getServletContext();
WebApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
delegate = new SpringServlet(context, false);
delegate.init(config);
}
@Override
public void destroy() {
if (delegate != null) {
delegate.destroy();
}
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
delegate.service(request, response);
}
}
根据this comment,解决方案是添加一个com.vaadin.flow.spring.VaadinApplicationConfiguration bean到applicationContext.xml.
这需要
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<bean class="com.vaadin.flow.spring.VaadinApplicationConfiguration"/>
</beans>
如果你不想使用
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="com.vaadin.flow.spring.SpringApplicationConfigurationFactory"/>
<bean class="com.vaadin.flow.spring.SpringLookupInitializer.SpringApplicationContextInit"/>
</beans>
不推荐这样做,因为 SpringApplicationContextInit 是 Vaadin 内部的。
这是我想出的一个变体。我想使用 web.xml
和 Vaadin Spring,但不想使用 Spring 引导或 Spring 安全。
在我的 applicationContext.xml
文件中,我使用 <context:component-scan>
查找所有各种 Vaadin Spring 配置 bean,但随后排除了特定于 [=24= 的那些配置 bean ] 引导和 Spring 安全:
<!-- Vaadin annotation-based config, but excluding Spring Boot and Spring Security -->
<context:component-scan base-package="com.vaadin.flow.spring">
<context:exclude-filter type="regex" expression="com\.vaadin\.flow\.spring\.security\..*"/>
<context:exclude-filter type="regex" expression="com\.vaadin\.flow\.spring\.SpringBootAutoConfiguration"/>
<context:exclude-filter type="regex" expression="com\.vaadin\.flow\.spring\.SpringSecurityAutoConfiguration"/>
</context:component-scan>
我 没有 在我的 web.xml
中有 metadata-complete="false"
因为我通过 XML 进行所有其他 Spring 配置(只是遗留物)。