DragonCave

一个没有黄段子的无聊小站

从零开始构建 Spring Web 项目

前言

为啥我建个最简单的 SpringMVC 项目都到处踩坑?

本文将记录如何使用 IDEA 从一个空的 Maven 工程构建一个基本的基于注解的 Spring Web项目。

基本步骤参照《 Spring in action(第4版)》第 5 章。

创建空 Maven 项目

启动 IDEA ,创建 Maven 工程,不勾选原型(archetype)。

《从零开始构建 Spring Web 项目》

一路 Next 完善项目信息后 Finish完成创建。

此时的项目文件结构如下:

《从零开始构建 Spring Web 项目》

为项目添加 Web 模块

在 src/main 目录下建立 webapp 文件夹,作为 Web 文件的根目录,并建立 WEB-INF 子文件夹。

《从零开始构建 Spring Web 项目》

打开 File -> Project Structure -> Modules,右键项目点击 Add 或直接点 + 号,选择添加一个 Web 模块。

《从零开始构建 Spring Web 项目》

修改 Deployment Descriptor 路径,将其设为  项目路径/webapp/WEB-INF/web.xml webapp和WEB-INF 文件夹即为刚刚创建的那个,web.xml 不用提前创建,补在选择好的路径之后即可。

修改下方的 Web Resoure Directories 路径,将其设为 项目路径/webapp

《从零开始构建 Spring Web 项目》

点击 OK,会发现 WEB-INF 文件夹中自动创建好了 web.xml 。

《从零开始构建 Spring Web 项目》

为项目添加 Spring Web 相关依赖

首先,在 pom.xml 文件中添加打包方式为 war

<packaging>war</packaging>

配置项目 Java 版本为 1.8 :

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

添加相关依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.2.0.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.2.0.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.0.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>5.2.0.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.0.RELEASE</version>
    </dependency>
    
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

配置 SpringMVC(基于注解)

根据需要在 /src/main/java 下建包,在 config 中创建类 WebConfig:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "me.loong.springTest.web")
public class WebConfig implements WebMvcConfigurer {

    @Bean
    public ViewResolver viewResolver(){
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        resolver.setExposeContextBeansAsAttributes(true);
        return  resolver;
    }

    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}

这个类使用 @EnableWebMvc 注解启用 SpringMVC,使用 @ComponentScan 自动扫描添加指定包中的组件。viewResolver() 配置了一个简单的 JSP 视图解析器,configureDefaultServletHandling() 则将静态资源转发到容器中默认 Servlet 处理,而不使用DispatcherServlet 本身处理。

注意

书中本类是继承 WebMvcConfigurerAdapter。WebMvcConfigurerAdapter 在 Spring 5.0 和 SpringBoot 2.0 被废弃,因此不应该再使用过时的写法。根据官方文档,应采用实现 WebMvcConfigurer 的方式。

在 config 中创建类 RootConfig:

@Configuration
@ComponentScan(basePackages = "me.loong.springTest", excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class))
public class RootConfig {
}

在 Spring Web 项目中一般有两个应用上下文,分别由 DispatcherServlet 和 ContextLoaderListener 创建。一般希望 DispatcherServlet 加载 Web 组件的相关 bean, ContextLoaderListener 加载其它 bean。WebConfig 类中配置包扫描添加了 web 相关的组件,而本类负责扫描添加 WebConfig 类中没有添加的其它组件。

在 config 中创建类 WebAppInitializer :

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{RootConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

本类继承了 AbstractAnnotationConfigDispatcherServletInitializer 类从而自动配置 DispatcherServlet 和 Spring 应用上下文。重写 getServletMappings() 将根路径映射到 DispatcherServlet 上,表明这是应用默认 Servlet。其余两个方法分别引入上文两个配置类,以配置 应用上下文。

实现基本的控制器和 JSP 视图

在 web.controller 中创建类 HomeController:

@Controller
public class HomeController {

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String home(){
        return "home";
    }
}

本控制器负责在收到对根路径的 HTTP GET 请求时交给逻辑视图 home 处理。根据上文 WebConfig 中的配置,实际的视图为 /WEB-INF/views/home.jsp 。

在 webapp/WEB-INF 中创建 views 文件夹,在其中 创建 home.jsp。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Home</title>
</head>
<body>
<h1>Hello Spring!</h1>
</body>
</html>

为项目配置运行方式

此时的项目还没有配置 Run/Debug Configurations,因此无法运行。点击右上方 Add Configuration… ,打开配置页面。

点击 +  号,选择添加 Tomcat Server -> Local。

《从零开始构建 Spring Web 项目》

在 Application Server 一行点击 Configure 按钮在 Tomcat Home 中选择本地 Tomcat 的位置,点击 OK 完成配置。

切换到 Deployment 一栏,首先点击最下方 + 号,选择 build artifact -> SpringTest:war exploded。

《从零开始构建 Spring Web 项目》

然后点击右侧 + 号,添加 Artifact -> SpringTest:war exploded。

下方 Application Context 为项目起始路径,为了方便可以将其改为 / 。

《从零开始构建 Spring Web 项目》

启动项目

至此一个最基本的 Spring Web 项目就建好了。此时完整的项目结构为:

《从零开始构建 Spring Web 项目》

点击运行待服务启动后可以访问了。

《从零开始构建 Spring Web 项目》

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据