65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Spring Boot、 JSP 和 WAR Archive 创建 MVC Web 应用程序

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2018 年 10 月 17 日

MIT

10分钟阅读

viewsIcon

13662

downloadIcon

167

在本文中,我将讨论如何设置一个 Spring Boot 应用程序,该应用程序被打包为 WAR 存档,并支持使用 JSP 作为视图的 Spring MVC。

引言

这将是我的第一个 Spring Boot 教程,其中我将讨论如何设置 Spring MVC 应用程序。为了使用 JSP 页面作为视图模板,一种方法是将应用程序打包为 WAR 存档。成品可以作为独立应用程序运行,并作为 MVC 应用程序处理用户请求。

Spring Boot 是一个非常棒的应用程序开发框架。该框架的唯一重点是创建可以作为独立应用程序运行的各种程序。我指的不仅仅是可以部署到 Tomcat、Jetty 或 Glassfish 等应用程序容器中的 Web 应用程序;还包括可以与 RabbitMQ 或 Kafka 等消息代理交互的应用程序;以及可以与 Quartz 调度程序一起运行的程序。我猜大多数人可能使用此框架来创建基于 Web 的应用程序——无论是 MVC 应用程序还是基于 RESTful API 的应用程序。这些应用程序可以部署到 Docker 容器中,作为微服务提供。

本教程将向您展示使用 Spring Boot 创建基于 Web 的应用程序是多么容易。该应用程序完成后是一个独立的 Java 应用程序。它有一个嵌入式 Tomcat 应用程序服务器。它可以处理 Web 请求和静态 Web 内容。正如我在过去的几篇文章中提到的,每个新项目最糟糕的部分是项目设置。Spring Boot 确实有一些困难。但与创建 Spring v3/v4 MVC 应用程序相比,它更容易使用。您会看到的。

文件结构

在我们深入了解示例项目的细节之前,我想展示一下项目的目录和文件结构。如下所示:

<base-dir>/src/main/java/org/hanbo/boot/app/controllers/HelloController.java
<base-dir>/src/main/java/org/hanbo/boot/app/App.java
<base-dir>/src/main/resources/application.properties
<base-dir>/src/main/resources/static/test.html
<base-dir>/src/main/resources/static/assets/css/index.css
<base-dir>/src/main/resources/static/assets/js/test.js
<base-dir>/src/main/webapp/WEB-INF/jsp/testme.jsp

我们有各种各样的文件。它们是:

  • 两个 Java 文件。一个是程序执行入口。另一个是 MVC 控制器。
  • 一个属性文件,其中包含一些配置值。
  • 三个静态文件,可以在请求时直接提供给用户。
  • 一个 JSP 文件,用作 MVC 应用程序的视图模板。

如您所见,设置 Spring MVC 应用程序既快速又简单。如果您知道旧的 Web 应用程序设置方法,您将需要至少两个 XML 文件进行配置。或者,如果您使用 Java 注解来配置 Spring 应用程序,那么您需要知道如何将 XML 配置中的配置转换为使用 Java 注解。如果您在本教程中扩展示例应用程序,您将不得不使用 Java 注解进行配置。它将类似于 XML 配置的工作方式,但对于入门应用程序来说,这已经尽可能简单了。

POM XML 文件

让我们从 POM XML 文件开始。POM XML 文件用于 Maven 构建。它指定了项目如何编译和打包。这是此文件的内容:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
	http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<artifactId>boot-war</artifactId>
	<packaging>war</packaging>
	<name>Hanbo Boot War Sample App</name>
	<description>An example of Spring Boot, JSP and WAR</description>
	<version>1.0.0</version>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.5.RELEASE</version>
	</parent>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.tomcat.embed</groupId>
			<artifactId>tomcat-embed-jasper</artifactId>
			<scope>provided</scope>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

此 POM 文件有几个重要之处。首先是指定 Maven 构建将创建 WAR 存档的行:

<packaging>war</packaging>

其次是 POM 文件具有父 POM 依赖项。这允许下载许多 Spring 和非 Spring 依赖项并将其链接到此项目中:

<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>2.0.5.RELEASE</version>
</parent>

第三是属性定义,它将 Java 编译设置为使用 JDK 1.8:

<properties>
   <java.version>1.8</java.version>
</properties>

最后是使用 Spring Boot Maven 插件进行编译和打包:

<build>
   <plugins>
      <plugin>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
   </plugins>
</build>

依赖项部分定义了此应用程序所需的额外依赖项。我需要 Spring MVC,并作为 J2EE Web 应用程序运行。添加的依赖项用于编译 JSP 视图和运行嵌入式应用程序服务器。

主入口

接下来,我将向您展示程序入口。与在应用程序容器中运行的基于 Spring 的 Web 应用程序不同,基于 Spring Boot 的 Web 应用程序是自托管的。每个此类程序都有一个静态主入口。以下是包含主入口的类的完整源代码:

package org.hanbo.boot.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class App extends SpringBootServletInitializer
{
	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder appBuilder)
   {
		return appBuilder.sources(App.class);
	}

	public static void main(String[] args) throws Exception
   {
		SpringApplication.run(App.class, args);
	}
}

该类名为 App,它继承自 SpringBootServletInitializer 类。这允许 Spring 框架识别 App 类可以像传统的 WAR 包一样进行初始化和执行。它还告诉 Spring 框架将有 WEB-INF 文件夹及其中的资源可供使用。

App 类中,有一个名为 configure() 的保护方法。它用于指定任何应用程序特定的配置。它只有一行,它获取 App 类的类型并创建一个 SpringApplicationBuilder 对象并返回。它的作用是,创建的 SpringApplicationBuilder 对象将自动扫描 App 类、它所在的包以及子包中所有带有注解的类和包含 Spring 配置的注解。然后它将根据这些配置构建一个 Spring 应用程序。这是通过约定集成的一个经典示例。所有内容都通过依赖注入耦合在一起。

static main 方法只有一行,它将 App 类的类型和任何附加的命令行参数传递给 SpringApplication.run()。在幕后,这个类做了很多工作。它将隐式地对当前包和所有子包进行组件扫描。如果需要,开发人员还可以指定其他包进行组件扫描。开发人员可以为任何其他需要的配置添加额外的注解。对于这个简单的程序,只有一个 MVC 控制器类可以处理用户对页面的请求。

MVC 控制器类

我想展示的下一个类是 MVC 控制器类。它是一个非常简单的类,只有一个方法处理来自用户的 HTTP GET 请求,带有一些查询参数。它通过使用 JSP 页面作为视图来响应。

源代码如下:

package org.hanbo.boot.app.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HelloController
{
	@RequestMapping(value="/meow", method = RequestMethod.GET)
	public ModelAndView hello(
	   @RequestParam("sayit")
	   String sayit
	)
   {
		ModelAndView retVal = new ModelAndView();
		retVal.setViewName("testme");
		retVal.addObject("mymessage", sayit);
		return retVal;
	}
}

这个类没有新的惊喜。也就是说,这个控制器类的定义与任何在应用程序容器中运行的应用程序的 Spring MVC 控制器相同。让我总结一下实现:

  • 该类用 @Controller 注解。
  • 该类只有一个方法处理 HTTP GET 请求。它用 @RequestMapping 注解。该注解定义了请求的子路径以及它可以处理的 HTTP 方法,即 GET 请求。
  • 该方法创建一个 ModelAndView 对象并返回。视图页面名为“testme”。数据模型只是一个将在页面上显示的 string
  • 该方法接受一个参数,该参数从名为“sayit”的查询参数中获取。

简单来说,当用户尝试导航到:

https://:8080/meow?sayit=This+is+pretty+crazy

然后用户点击回车,浏览器将显示以下内容:

What did you say?

I said: "This is pretty crazy."

为了使这个控制器按预期工作,需要一些额外的配置。这在 application.properties 文件中完成。

Application.properties 文件

我需要一个 application.properties 文件的原因是,我需要指定视图模板文件的前缀和后缀。如果您从旧时代就知道,有一个创建和配置类型为 org.springframework.web.servlet.view.InternalResourceViewResolver 的对象的步骤。在这种情况下,我们只需要在 application.properties 中添加两行:

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

此配置的作用是将应用程序设置为在“WEB-INF/jsp/”文件夹中查找视图模板。文件扩展名为“.jsp”。现在我们已经看到了主入口、控制器类以及内部资源视图解析器的设置。拼图的最后一块是视图模板。

JSP 视图模板

本教程的视图模板非常简单,只有一个 JSP 文件,演示了如何显示来自视图模型的数据:

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html lang="en">
<head>
	<c:url value="/assets/css/index.css" var="jstlCss" />
	<link href="${jstlCss}" rel="stylesheet" />
</head>
<body>
   <p>What did you say?</p>
   <p>I said: <span class="text-underline">"${mymessage}."</span></p>
   <script type="text/javascript" src="/assets/js/test.js">
   </script>
</body>
</html>

在此 JSP 文件中,有三件事:

  • 有一个级联样式表文件。它是一个静态文件,通过 JSTL 标签添加。这表明 JSTL 库已正确合并到项目中。
  • 视图模型只有一个元素,并通过 ${mymessage} 添加到视图中。
  • 有一个 JavaScript 文件添加到 HTML 内容的末尾,它会在加载后执行。这是为了演示在此项目中静态文件的使用。

由示例应用程序提供静态内容非常重要。它提供了超越 Spring MVC 的方法——静态页面和 JavaScript 可以用于单页 Web 应用程序。使用 Spring Boot 提供静态内容非常容易,这将在接下来解释。

提供静态内容

Spring Boot 提供了许多便利,以便开发人员可以快速开发。这种便利是通过约定实现的。在 Web 应用程序中提供静态内容就是一个很好的例子。当您将使用 Spring Boot 开发的应用程序指定为基于 Web 的应用程序时,您只需在 src/main/resources 下创建一个名为“static”的文件夹。在这个“static”文件夹内,只需添加您想要的任何子文件夹,并将任何静态内容文件放入其中,然后您就可以提供它们。

以示例应用程序为例,我有三个文件被指定为静态内容:

  • 一个级联样式表文件—— src/resources/static/assets/css/index.css
  • 一个 JavaScript 文件,它没有任何有用的功能,只是在 JavaScript 输出控制台上打印一行—— src/resources/static/assets/js/test.js
  • 一个 HTML 文件,仅仅是为了演示您在基于 Spring Boot 的 Web 应用程序中不需要 JSP—— src/resources/static/test.html

那么,用户如何通过浏览器访问这些 static 内容呢?这很简单。假设应用程序正在运行,并且假设应用程序运行的网站的 URL 是 https://:8080/(没有特定的应用程序上下文),那么用户可以通过以下 URL 查看这些静态内容文件的实际内容:

  • https://:8080/assets/js/test.js - 您看到 JS 文件的实际内容。
  • https://:8080/assets/css/index.css - 您看到级联样式表文件的实际内容。
  • https://:8080/assets/test.html - 您看到一个网页。

有多种方法可以配置 Spring Boot 应用程序以在其他位置查找静态内容文件,WEB-INF 和 JSP 位置也是如此,以及应用程序如何初始化,以及 Spring Boot 应用程序行为的许多其他方面。这些不是本教程的讨论主题,但是如果您对 Spring Boot 有足够的了解,它们是微不足道的。我可能会在以后的文章中介绍其中一些。

如何构建和运行应用程序

在构建项目之前,请转到 src/main/resources/static/assets/js 文件夹并将文件“test.sj”重命名为“test.js”。

要构建此应用程序,请在命令行控制台中运行以下命令:

mvn clean install

当您第一次运行它时,它将下载构建此应用程序所需的所有依赖项,这可能需要一些时间。之后,随后的构建将花费更少的时间。

要运行 Web 应用程序,您也可以通过命令行控制台完成:

java -jar target\boot-war-1.0.0.war

如果一切顺利并且您可以构建应用程序,执行将在最后输出类似以下内容:

<small>
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.5.RELEASE)

2018-10-14 22:51:11.356  INFO 6124 --- [           main] org.hanbo.boot.app.App                   : Starting App v1.0.0 on U3DTEST-PC with PID 6124 (C:\Users\u3dadmin\workspace-mars8\SpringBootJspWar\target\boot-war-1.0.0.war started by u3dadmin in C:\Users\u3dadmin\workspace-mars8\SpringBootJspWar)

....
....
....

2018-10-14 22:51:28.730  INFO 6124 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2018-10-14 22:51:28.745  INFO 6124 --- [           main] org.hanbo.boot.app.App                   : Started App in 20.84 seconds (JVM running for 23.398)
</small>

关注点

正如我之前提到的,使用 Spring Boot 创建 Web 应用程序非常简单方便。这种便利的重点是消除所有混乱的配置,以便人们可以专注于开发过程中最重要的部分,即设计符合最终产品愿景的东西。除此之外,Spring Boot 的一个很酷的地方是它可以快速部署到 Docker VM 中。因此,它非常适合开发微服务。

我的下一步将是编写一个更复杂的 Spring Boot 教程,其中包括数据访问、身份验证和授权。敬请期待。

历史

  • 2018/10/14:初稿
© . All rights reserved.