将 Vaadin/SpringBoot 部署为 WAR

Posted

技术标签:

【中文标题】将 Vaadin/SpringBoot 部署为 WAR【英文标题】:Deploying Vaadin/SpringBoot as WAR 【发布时间】:2018-03-15 13:28:30 【问题描述】:

我正在尝试将最小的 Vaadin/SpringBoot 应用程序作为 WAR 文件部署到独立的 Tomcat 中。

如果我运行 gradle vaadinRun 并在 localhost:8080 下访问,一切正常,但是使用 gradle war 创建 WAR 文件,然后将其复制到我的 Tomcat 的 webapps 文件夹中会导致 404。不幸的是,Tomcat 日志不显示任何事物。尝试通过localhost:8080/hello-vaadin访问。

这是应用程序类本身:

package com.somecompany;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.boot.web.servlet.ServletComponentScan;
import com.vaadin.spring.annotation.EnableVaadin;

@ServletComponentScan
@SpringBootApplication
@EnableVaadin
public class Application extends SpringBootServletInitializer 

    public static void main(String[] args) throws Exception 
        configureApplication(new SpringApplicationBuilder()).run(args);
    

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) 
         return configureApplication(builder);
    

    private static SpringApplicationBuilder configureApplication(SpringApplicationBuilder builder) 
        return builder.sources(Application.class);
    


这是对应的 UI 类:

package com.somecompany;

import com.vaadin.annotations.Theme;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.UI;
import com.vaadin.ui.Grid;
import org.springframework.beans.factory.annotation.Autowired;
import com.vaadin.ui.Label;

@SpringUI
@Theme("valo")
public class HelloWorldUI extends UI 

    @Autowired
    public HelloWorldUI() 

    

    @Override
    protected void init(VaadinRequest request) 
        setContent(new Label("Hello World!"));
    


最后是我的 gradle 脚本:

plugins 
    id "java"
    id "com.devsoap.plugin.vaadin" version "1.2.4"
    id "org.springframework.boot" version "1.5.7.RELEASE"


jar 
    baseName = 'com.somecompany.hello-vaadin'
    version =  '0.0.1-SNAPSHOT'


apply plugin: 'war'

war 
    baseName = 'hello-vaadin'
    version =  '1.0'


springBoot 
    mainClass = 'com.somecompany.Application'


bootRepackage 
    mainClass = 'com.somecompany.Application'


repositories 
    jcenter()
    mavenCentral()
    maven  url "http://oss.sonatype.org/content/repositories/vaadin-snapshots/" 
    maven  url 'https://repo.spring.io/libs-release' 
    maven  url "https://repository.jboss.org/nexus/content/repositories/releases" 


dependencies 
    compile("org.springframework.boot:spring-boot-starter-web")
    providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")

在一个接一个的教程之后,一定有一些我忽略的东西。但是什么,我看不出问题出在哪里?

高度赞赏的任何提示!

【问题讨论】:

作为 maven 用户,我需要 spring-boot-maven-plugin,也许 gradle 也有等价物? @Jay 是的,我可以从经理页面看到该应用程序。 @mrkernelpanic 这应该在第四行 org.springframework.boot 插件中完成。 您应该明确地增加对您的 tomcat 的日志记录,以查看错误、未部署的原因或查看实际发生的情况以及战争现在出现的位置。其他一切都只是猜测。 @cfrick WAR 文件被正确部署,将被解包,显示在 tomcat 管理器中。但是请求返回 404。我会更高兴 50x 和日志中有用的东西,但是 404 是 404 ... 【参考方案1】:

最后,我设法让它工作了。方法如下:

MyApplication.java

package com.somecompany;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyApplication 
    public static void main(String[] args) throws Exception 
        SpringApplication.run(MyApplication.class, args);
    

MyServletInitializer.java

package com.somecompany;

import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.boot.builder.SpringApplicationBuilder;

public class MyServletInitializer extends SpringBootServletInitializer 
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) 
        return builder.sources(MyApplication.class);
    

MyConfiguration.java

package com.somecompany;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;

@Configuration
public class MyConfiguration 
    @Bean
    public String myLabelString() 
        return "Hello World Bean!";
    

HelloWorldUI.java

package com.somecompany;

import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.UI;
import org.springframework.beans.factory.annotation.Autowired;
import com.vaadin.ui.Label;

@SpringUI
public class HelloWorldUI extends UI 

    @Autowired
    String helloWorldString;

    @Override
    protected void init(VaadinRequest request) 
        if (helloWorldString != null) 
            setContent(new Label(helloWorldString));
         else 
            setContent(new Label("Injection does not work!"));
        
    

build.gradle

plugins 
    id 'com.devsoap.plugin.vaadin' version '1.2.1'
    id 'org.springframework.boot' version '1.5.3.RELEASE'


apply plugin: 'war'

war 
    baseName = 'hellovaadin'


springBoot 
    mainClass = 'com.somecompany.MyApplication'

然后使用gradle build 构建WAR 文件,然后将其复制到我的tomcat 实例的webapps 文件夹中。

我已经扩展了这个例子,还展示了如何注入/自动装配一个 bean。

【讨论】:

您甚至可以通过使用构造函数注入 iso 字段注入来改进您的代码。

以上是关于将 Vaadin/SpringBoot 部署为 WAR的主要内容,如果未能解决你的问题,请参考以下文章

tomcat 虚拟目录配置appBase和docBase的区别

作业 安装部署

React w/Kubernetes 部署的 API 给出了 cors 错误

将SpringBoot项目及vue项目分别打包部署到阿里云服务器

在 Tomcat 10.x 上部署 Spring 5.x

在 Tomcat 10.x 上部署 Spring 5.x