SSM框架学习——Eclipse创建Spring MVC maven项目

Spring MVC项目创建

什么是Spring MVC

Spring MVC是Spring内置的,实现了Web MVC设计模式的框架。

它解决了Web开发过程中很多的问题,例如参数接收、表单验证等。另外它采用松散耦合可插拔组件等结构,具有相对较高的灵活性和扩展性。

Spring MVC官方文档可参考 docs.spring.io

Spring MVC执行流程

按顺序可分为如下流程

  • 用户请求被DispatcherServlet进行拦截处理
  • DispatcherServlet收到请求调用HandlerMapping
  • HandlerMapping找到具体的处理器,生成处理器对象及处理器拦截器,再一起返回给DispatcherServlet
  • DispatcherServlet调用HandlerAdapter
  • HandlerAdapter经过适配调用具体的处理器
  • Controller执行完成返回ModelAndView对象
  • HandlerAdapterModelAndView返回给DispatcherServlet
  • DispatcherServletModelAndView传给ViewReslover
  • ViewReslover解析ModelAndView后返回View(给DispatcherServlet
  • DispatcherServlet根据View进行渲染
  • DispatcherServlet响应View给用户

通过上面流程可知,程序员需要配置DispatcherServlet,并开发ViewController/Handler

项目创建

即然如此,我们就来创建一个Spring MVC项目。

打开Eclipse,创建一个Maven项目(想必经过前面学习已经很熟了),项目名称top.cairbin.test7

但是需要注意,创建时请勾选下图的Add project(s) to working set

Select an Archetype这一步需要注意,我们不再用之前的maven-archetype-quickstart,而是maven-archetype-webapp,如下图所示

创建完成后项目目录结构大概如下

我们还需要引入Spring MVC的依赖包以及Servlet,这你很清楚应该在pom.xml里配置

xml 复制代码
<!-- 添加servlet依赖 -->
<dependency>
	<groupId>javax.servlet</groupId>
	<artifactId>javax.servlet-api</artifactId>
	<scope>provided</scope>
	<version>3.1.0</version>
</dependency>
    
<!-- 添加spring依赖 -->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-core</artifactId>
	<version>5.3.23</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-web</artifactId>
	<version>5.3.23</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>5.3.23</version>
</dependency>

最终效果看起来是这样

xml 复制代码
<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>top.cairbin</groupId>
  <artifactId>test7</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>test7 Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    
    <!-- 添加servlet依赖 -->
	<dependency>
		<groupId>javax.servlet</groupId>
		<artifactId>javax.servlet-api</artifactId>
		<scope>provided</scope>
		<version>3.1.0</version>
	</dependency>
    
	<!-- 添加spring依赖 -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-core</artifactId>
		<version>5.3.23</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-web</artifactId>
		<version>5.3.23</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-webmvc</artifactId>
		<version>5.3.23</version>
	</dependency>
    
  </dependencies>
  <build>
    <finalName>test7</finalName>
  </build>
</project>

相比于以往的项目,你会发现webapp已经为我们创建了一个resources资源文件夹,并且src/main下多了一个webapp目录。webapp它一般存放前端相关的文件。

webapp目录下有一个WEB-INF,里面有一个默认生成的web.xml配置文件。还记得我们刚才提到的Spring MVC执行流程吗,用户请求会被DispatcherServlet拦截,它叫前端控制器,而这个XML文件就是用来对它进行设置的。

我们对web.xml进行修改

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	      xmlns="http://java.sun.com/xml/ns/javaee"
	      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">
	<servlet>
	    <!-- 配置前端过滤器 -->
		<servlet-name>springmvc</servlet-name>
		<servlet-class>
              org.springframework.web.servlet.DispatcherServlet
         </servlet-class>
		<!-- 初始化时加载配置文件 -->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springCtx.xml</param-value>
		</init-param>
		<!-- 表示容器在启动时立即加载Servlet -->
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<url-pattern>/</url-pattern> 
	</servlet-mapping>
</web-app>

注意<param-value>classpath:springCtx.xml</param-value>这一段引入了一个文件,是用来配置Controller映射信息的。

我们再来看看,webapp下还有一个index.jsp文件,它正是你的前端代码文件,它的内容如下

jsp 复制代码
<html>
<body>
<h2>Hello World!</h2>
</body>
</html>

你可能对此表示疑惑,这不就是一个HTML文件,现实一个标题,标题内容为Hello World!吗。没错,但是对于传统的HTML来讲页面是静态的,而我们的JSP文件则能动态获取后端一些内容。

有了View来实现USL前台还不够,我们还要实现USL后台,接下来我们在src/main/java下创建包top.cairbin.test7.controller,并在这个包下创建控制器类TestController

java 复制代码
package top.cairbin.test7.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;


public class TestController implements Controller{
	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)  {
         // 创建ModelAndView对象
		ModelAndView mav = new ModelAndView();
         // 向模型对象中添加数据
		mav.addObject("message", "Hello Spring");
         // 设置逻辑视图名
		mav.setViewName("/WEB-INF/views/hello.jsp");
         // 返回ModelAndView对象
		return mav;
	}
}

还记得刚才说的<param-value>classpath:springCtx.xml</param-value>吗,我们创建了控制器,还要告诉Spring MVC控制器与View的映射关系。

springCtx.xml这个文件并不存在我们项目中,需要手动添加。在resources资源文件夹里创建它。

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans.xsd">
	<!-- 配置处理器Handle,映射"/hello"请求 -->
	<bean name="/hello" 
			class="top.cairbin.test7.controller.TestController" />
	<!-- 处理器映射器,将处理器Handle的name作为url进行查找 -->
	<bean class=
	"org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
	<!-- 处理器适配器,配置对处理器中handleRequest()方法的调用-->
	<bean class=
	"org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
	<!-- 视图解析器 -->
	<bean class=
	"org.springframework.web.servlet.view.InternalResourceViewResolver">
	</bean>
</beans> 

请务必注意<bean name="/hello" class="top.cairbin.test7.controller.TestController" />这一段的包名与你控制器一致。它告诉Spring MVC,将这个控制器映射到/hello路径上去,一会你就能在浏览器通过http://ip:port/项目名/hello的形式去访问它。

WEB-INF里创建views文件夹,请注意是WEB-INF下创建。

并在这个viewsview文件夹里新建jsp文件hello.jsp

jsp 复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
     pageEncoding="UTF-8"%>
<%@page isELIgnored="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
     "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello SpringMvc</title>
</head>
<body>
     <h1>${message}</h1>
</body>
</html> 

我们在这里使用${...}的形式来使用后端提供的接口,以此获取后端返回的对象。

那么问题来了,我们这个项目该怎么运行呢?显然对于Web项目我们需要Http服务器。

还记得我们在配置环境的时候安装的Tomcat9吗,现在终于要到了使用它的时候了!

另外,我们注意之前编写的TestController这个控制器,它需要导入的包中可能有两个报错。

java 复制代码
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

如果出现这种情况,我们右键这个项目,打开属性

找到Java Build Path选项的Libraries选项卡,点击Add Library...

选择Server Runtime选项,然后下一步

选择之前配置好的服务器(就是在环境配置那篇文章里的)

保存并退出。

接下来我们尝试运行它,与以往不同的是,我们需要Run As里面的Run on server

如果你第一次这样做,会弹出个窗口

选择Apache里对应的服务器,我这里是Tomcat9.0

然后点击完成。很显然,你的浏览器已经打开了,说明你的项目跑成功了。并且在Eclipse的Package Explorer中多了个Servers文件夹。

我们在浏览器访问的是index.jsp所渲染的页面

在地址栏输入http://localhost:8080/test7/hello访问控制器和hello.jsp所渲染的页面

问题

在这一节其实有很多坑,一是Tomcat版本在10.0以上的话,包名变化问题。

另外如果当初配置环境的时候,Eclipse没选Web选项,这里有些配置是没有的。

上面这些问题请参考环境配置和此教程的问题模块。

如果你项目菜单里的Run as没有Run on server选项的话需要如下操作

打开项目属性

搜索project facets,勾选Dynamic Web Module选项

保存并退出。

接下来如果操作不当的话可能导致Servers文件夹下配置文件里有多个context,这时候需要打开server.xml进行就该

找到如下片段<Context>标签,把重复的删除

相关推荐
不能再留遗憾了13 小时前
【SpringCloud】Sentinel
spring·spring cloud·sentinel
whltaoin14 小时前
AI 超级智能体全栈项目阶段五:RAG 四大流程详解、最佳实践与调优(基于 Spring AI 实现)
java·人工智能·spring·rag·springai
Excuse_lighttime14 小时前
只出现一次的数字(位运算算法)
java·数据结构·算法·leetcode·eclipse
心勤则明14 小时前
Spring AI 文档ETL实战:集成text-embedding-v4 与 Milvus
人工智能·spring·etl
艾菜籽14 小时前
Spring Web MVC入门补充1
java·后端·spring·mvc
艾菜籽17 小时前
Spring MVC入门补充2
java·spring·mvc
为java加瓦20 小时前
Spring 方法注入机制深度解析:Lookup与Replace Method原理与应用
java·数据库·spring
无名客020 小时前
SpringCloud中的网关(Gateway)的作用是什么?
spring·spring cloud·gateway
hrrrrb1 天前
【Spring Security】Spring Security 概念
java·数据库·spring
小信丶1 天前
Spring 中解决 “Could not autowire. There is more than one bean of type“ 错误
java·spring