blog/使用Maven创建SpringMVC项目.md

227 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

---
title: 使用 Maven 创建 Spring MVC 项目
date: 2020-11-11 15:52:52
tags:
- Spring
- Spring MVC
- Maven
categories:
- Spring
---
> Maven 可以用来创建 Java 项目,并管理依赖,创建出来的项目不依赖于特定的 IDE可以用 Eclipse、IDEA 社区版、IDEA 旗舰版,甚至 VSCode 来开发。_具体 VSCode 怎么配置 Java 开发环境这里不再赘述_
> Maven 创建项目时,需要从国外的服务器上下载项目的依赖、插件等,速度会很慢,甚至导致创建项目失败,具体如何配置,请参考我的另一篇博客 [Maven 的相关配置](http://zhouxy.xyz/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Maven-%E7%9A%84%E7%9B%B8%E5%85%B3%E9%85%8D%E7%BD%AE/)。
## 一、创建 Java Web 项目
### 1. 使用 maven 创建 Java Web 项目
启动开发环境,用 Maven 创建项目从原型中选择“maven-archetype-webapp”再依次指定 groupId、artifactId 等信息,不同的 IDE 创建 Maven 项目的过程略有不同,但大同小异。
### 2. 完善目录结构
`main` 文件夹中创建 `java``resources` 两个文件夹;在 `src` 文件夹中创建 `test` 文件夹,并中其中也创建 `java``resources` 两个文件夹。
- ${basedir}/src/main/java 文件夹中创建 Java 包和类;
- ${basedir}/src/main/resources 文件夹中存放静态文件;
- ${basedir}/src/test/java 文件夹中创建项目的测试类,比如说 Junit 代码;
- ${basedir}/src/test/resources 存放测试用的资源。
> 在 IDEA 中新建目录时,会有几个提示,因为 IDEA 通过 pom.xml 文件知道这是个 maven 项目,猜测并帮助你创建标准的 maven 项目骨架。这时候按住 shift 键,并按住下方向键,可将其全部选中,再按回车,即可一次性创建好所有文件夹并标记好,这样就不用一个一个创建并标记了。在 VSCode 中并不会对项目中的文件夹进行标记VSCode 的一些图标可能会根据文件名进行猜测),所以一个一个创建文件夹就完事了。
初始的项目路径如下:
![初始项目结构](http://zhouxy.xyz/img/163635_48fc6498_6543055.png)
我们需要完善其目录结构:
![完善后的目录结构](http://zhouxy.xyz/img/164009_81ccdf56_6543055.png)
### 3. 添加 Servlet 和 JSP 的依赖包
在 pom.xml 文件中的 `dependencies` 标签中添加 Servlet 和 JSP 的依赖:
```xml
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<!-- JSP 和 标签库(用不着的话就不用导) -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
```
这样,一个 Java Web 项目就创建好了。
## 二、配置 Spring MVC
### 1. 导入 Spring、Spring MVC 的依赖
在 pom.xml 文件中的 `dependencies` 标签中添加如下依赖:
```xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
```
> 导入 spring-webmvc 好像就会自动导入 spring-aop、spring-beans、spring-context、spring-core、spring-expression、spring-web 这些个依赖。
### 2. 配置并启用 Spring MVC
以前(包括现在很多人)配置 Spring MVC 都是通过 web.xml 配置的,随着 Java 和 Spring 的发展,现在完全可以不使用 xml 配置并启用 Spring MVC。
下面的配置适用于 Spring 3.2 及以上版本我写本文时Spring 的版本已经是 5.2.9 了),且 Servlet 容器支持 Servlet 3.02009 年 12 月发布)。所以,你的开发环境大概率支持以下配置方法。
#### 2.1.1 创建 RootConfig 配置类
**RootConfig 类将用于非 web 部分的配置。** *本示例中重在与 Web 相关的配置,所以 `RootConfig` 相对简单,实际项目中将会有很多非 Web 的配置来充实完善 RootConfig。*
```java
package xyz.zhouxy.chapter01.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
@ComponentScan(basePackages = "xyz.zhouxy.chapter01",
excludeFilters = {
@Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class)})
public class RootConfig {
}
```
#### 2.1.2 创建 WebConfig 配置类
WebConfig 将用于 DispatcherServlet 应用程序上下文配置。
```java
package xyz.zhouxy.chapter01.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan("xyz.zhouxy.chapter01.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;
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
```
- `@EnableWebMvc` 注解启动 Spring MVC
- `@ComponentScan` 启用组件扫描;所指定的包中的所有带有 `@Controller` 注解的类都会成为 Spring bean。
- `viewResolver` 方法配置 JSP 视图解析器,将 `InternalResourceViewResolver` 类的实例声明为 bean
- 重写的 `configureDefaultServletHandling` 方法,通过调用 `DefaultServletHandlerConfigurer``enable()`,要求 `DispatcherServlet` 将对静态资源的请求转发到 Servlet 容器中默认的 Servlet 上,而不是使用 `DispatcherServlet` 本身来处理此类请求。
> 《Spring 实战第4版》中WebConfig 是继承自 `WebMvcConfigurerAdapter` 类,但当前的版本,该类已经过时,`WebConfig` 类实现 `WebMvcConfigurer` 接口即可。
#### 2.1.3 创建 WebAppInitializer 类
当我们创建了 `RootConfig``WebConfig` 配置类之后,怎么让它们应用于我们的项目呢?答案是通过写一个 `WebAppInitializer`
`WebAppInitializer` 类继承自 `AbstractAnnotationConfigDispatcherServletInitializer`,所以它会自动地配置 `DispatcherServlet` 和 Spring 应用上下文Spring 应用上下文会位于应用程序的 Servlet 上下文中。
```java
package xyz.zhouxy.chapter01.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
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[] { "/" };
}
}
```
> **更多细节:**
> 在 Servlet 3.0 环境中,容器会在类路径中查找 `javax.servlet.ServletContainerInitializer` 接口的实现类,找到的话,就用它来配置 Servlet 容器。Spring 的 `SpringServletContainerInitializer` 类即为该接口的实现类,`SpringServletContainerInitializer` 又会查找实现 `WebApplicationInitializer` 的类并将配置的任务交给它们来完成。
>
> Spring 3.2 中引入了一个便利的 `WebApplicationInitializer` 基础实现,也就是 `AbstractAnnotationConfigDispatcherServletInitializer`。
>
> 因为我们的 `WebAppInitializer` 继承自 `AbstractAnnotationConfigDispatcherServletInitializer`(同时也就实现了 `WebApplicationInitializer` 接口),因此当部署到 Servlet 3.0 容器中的时候,容器会自动发现它,并用它来配置 Servlet 上下文。
## 三、使用 Spring MVC
前面我们已经配置好了 Spring MVC接下来我们编写一个 Controller 来测试一下吧。
### 1. 创建页面
在 ${basedir}/src/main/webapp/WEB-INF/ 文件夹中新建一个 `views` 文件夹,再在 `views` 文件夹中新建 `test.jsp` 文件:
```html
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>Test</title>
</head>
<body>
<h1>Test Page</h1>
</body>
</html>
```
### 2. 创建 TestController
```java
package xyz.zhouxy.chapter01.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class TestController {
@GetMapping("/test")
public String toTestPage() {
return "test";
}
}
```
### 3. 部署项目
将项目部署到 Tomcat应用上下文为 `chapter01`
> 不同 IDE 配置 Tomcat 部署项目具体细节找时间再写吧。
在浏览器输入 http://localhost:8080/chapter01/test ,由于上面的映射,`toTestPage()` 方法将被执行它返回字符串“test”被视作视图的名称`WebConfig` 类中配置的视图解析器解析为具体的视图 `/WEB-INF/views/test.jsp`
![运行结果](http://zhouxy.xyz/img/233117_0a37d814_6543055.png "屏幕截图.png")