将春季应用程序部署到Tomcat


自从Servlet 3规范以来,web.xml不再需要用于配置web应用程序,并且已被注释所取代。在本文中,我们将了解如何部署一个简单的基于Spring的应用程序,而不需要web.xml到Tomcat 8.5.x。

创建空应用程序

使用以下命令,使用Maven webapp原型创建一个空的web应用程序:

mvn archetype:generate -DgroupId=info.sanaulla -DartifactId=spring-tomcat-sample 
   -Dversion=1.0 -DarchetypeArtifactId=maven-archetype-webapp


删除web.xml创建于src\main\webapp\WEB-INF。然后,我们需要更新maven-war-plugin不要失败,如果web.xml不见了。这可以通过更新build标签如下所示:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <id>default-war</id>
            <phase>prepare-package</phase>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
            </configuration>
        </execution>
    </executions>
</plugin>


设置相关性

我们需要将以下依赖项添加到pom.xml

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.0</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
    <version>${thymeleaf.version}</version>
</dependency>
<dependency>
    <groupId>nz.net.ultraq.thymeleaf</groupId>
    <artifactId>thymeleaf-layout-dialect</artifactId>
    <version>${thymeleaf-layout-dialect.version}</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson.version}</version>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>${h2.version}</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
    <version>${lombok.version}</version>
</dependency>


它们相应的版本属性如下:

<properties>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
    <java.version>1.8</java.version>
    <apache.commons.version>3.6</apache.commons.version>
    <h2.version>1.4.196</h2.version>
    <jackson.version>2.9.2</jackson.version>
    <lombok.version>1.16.18</lombok.version>
    <spring.version>5.0.0.RELEASE</spring.version>
    <thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
    <thymeleaf-layout-dialect.version>2.2.1</thymeleaf-layout-dialect.version>
</properties>


配置我们的H2嵌入式数据库

让我们创建一个配置bean来配置我们的DataSource,这是一个嵌入式H2,并创建一个Bean类型的NamedParameterJdbcTemplate

@Configuration
public class DBConfiguration {

    @Bean
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
            .generateUniqueName(false)
            .setName("testdb")
            .setType(EmbeddedDatabaseType.H2)
            .addDefaultScripts()
            .setScriptEncoding("UTF-8")
            .ignoreFailedDrops(true)
            .build();
    }

    @Bean
    public NamedParameterJdbcTemplate namedParamJdbcTemplate() {
        NamedParameterJdbcTemplate namedParamJdbcTemplate =
            new NamedParameterJdbcTemplate(dataSource());
        return namedParamJdbcTemplate;
    }
}


然后我们需要一个SQL脚本schema.sql这将在data.sql每次运行应用程序时,将为它们播种数据。让我们在src/main/resources

-- schema.sql
DROP TABLE IF EXISTS person;

CREATE TABLE person(
  id NUMERIC IDENTITY PRIMARY KEY,
  first_name VARCHAR(512) NOT NULL,
  last_name VARCHAR(512) NOT NULL,
  date_of_birth TIMESTAMP NOT NULL,
  place_of_birth VARCHAR(512)
);

-- data.sql
INSERT INTO person(first_name, last_name, date_of_birth, place_of_birth) 
VALUES ('First', 'Last', DATE '1990-02-21', 'Bangalore');
INSERT INTO person(first_name, last_name, date_of_birth, place_of_birth) 
VALUES ('First2', 'Last2', DATE '1987-02-21', 'Mumbai');
INSERT INTO person(first_name, last_name, date_of_birth, place_of_birth) 
VALUES ('First3', 'Last3', DATE '1996-02-21', 'Chennai');
INSERT INTO person(first_name, last_name, date_of_birth, place_of_birth) 
VALUES ('First4', 'Last4', DATE '1978-02-21', 'Delhi');


创建应用编程接口控制器

让我们创建一个模型类Person

@Data
public class Person {
    private Integer id;
    private String firstName;
    private String lastName;
    private Date dateOfBirth;
    private String placeOfBirth;
}


和相应的DAO类PersonDAO

@Service
public class PersonDAO {

    @Autowired NamedParameterJdbcTemplate jdbcTemplate;

    public List < Person > getPersons() {
        return jdbcTemplate.query("SELECT * FROM person",
            (ResultSet rs, int rowNum) - > {
                Person p = new Person();
                p.setId(rs.getInt("id"));
                p.setFirstName(rs.getString("first_name"));
                p.setLastName(rs.getString("last_name"));
                p.setDateOfBirth(rs.getDate("date_of_birth"));
                p.setPlaceOfBirth(rs.getString("place_of_birth"));
                return p;
            });
    }
}


应用编程接口控制器如下所示:

@RestController
@RequestMapping("/api/persons")
public class ApiController {

    @Autowired PersonDAO personDao;

    @GetMapping
    public ResponseEntity << ? > getPersons() {
        return ResponseEntity.ok(personDao.getPersons());
    }
}


将我们的应用部署到Tomcat

我假设您已经下载了Tomcat并将其提取到您的文件系统中。出于开发目的,我更喜欢更新server.xml配置上下文并指向分解的WAR目录,如下所示:

<Context path="/sample" reloadable="true" docBase="G:\samples\spring-tomcat-sample\target\spring-tomcat-sample" />


对于与生产相关的部署,您可以将WAR上传到服务器。

所以一旦你启动了服务器,你可以通过访问应用程序接口网址来验证应用程序是否已经被正确部署http://localhost:8080/sample/api/persons在浏览器中获取如下所示的数据:

配置百里香叶

现在让我们配置Thymeleaf作为我们的模板引擎,为我们的应用程序提供用户界面。配置它需要以下bean定义:

  • 解析模板的技术。有许多可能性,我们将使用基于类路径的模板解析器

  • 创建的实例SpringTemplateEngine并设置模板解析器技术

  • 安装弹簧ViewResolver使用SpringTemplateEngine

@Configuration
public class ViewConfiguration {

    @Bean
    public ClassLoaderTemplateResolver templateResolver() {
        ClassLoaderTemplateResolver templateResolver =
            new ClassLoaderTemplateResolver();
        templateResolver.setPrefix("templates/");
        templateResolver.setSuffix(".html");
        templateResolver.setTemplateMode(TemplateMode.HTML);
        templateResolver.setCacheable(false);
        return templateResolver;
    }

    @Bean
    public SpringTemplateEngine templateEngine() {
        SpringTemplateEngine templateEngine =
            new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver());
        templateEngine.addDialect(new LayoutDialect());
        return templateEngine;
    }

    @Bean
    public ViewResolver viewResolver() {
        ThymeleafViewResolver viewResolver =
            new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(templateEngine());
        viewResolver.setCharacterEncoding("UTF-8");
        return viewResolver;
    }

}


创建视图控制器

让我们创建一个简单的控制器来服务于我们的用户界面模板:

@Controller
@RequestMapping("/")
public class ViewController {

    @Autowired PersonDAO personDao;

    @GetMapping
    public String index(Model model) {
        model.addAttribute("persons", personDao.getPersons());
        return "index";
    }
}


创建基于百里香叶的模板

我们需要创建一个模板index.html,它是从上面的控制器返回的:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <head>
        <link rel="stylesheet" href="https://bootswatch.com/4/cerulean/bootstrap.min.css" />
    </head>
    <body>
        <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
            <a class="navbar-brand" href="#">Spring on Tomcat</a>
        </nav>
        <div class="container">
            <div class="page-header">
                <h1>Spring on Tomcat</h1>
            </div>
            <div class="row">
                <div class="col">
                    <ul class="list-group">
                        <li class="list-group-item" th:each="p : ${persons}">
            [[${p.firstName}]] [[${p.lastName}]], 
            Date Of Birth: [[${#dates.format(p.dateOfBirth, 'dd/MMM/yyyy')}]]
            Place: [[${p.placeOfBirth}]]
            </li>
                    </ul>
                </div>
            </div>
        </div>
        <script src="https://bootswatch.com/_vendor/jquery/dist/jquery.min.js"></script>
        <script src="https://bootswatch.com/_vendor/popper.js/dist/umd/popper.min.js"></script>
        <script src="https://bootswatch.com/_vendor/bootstrap/dist/js/bootstrap.min.js"></script>
    </body>
</html>


结论

在本文中,我们研究了在没有web.xml(不使用Spring Boot)并将其部署到Tomcat。我们还配置了Thymeleaf呈现我们的用户界面模板。这方面的完整代码可以找到here