SpringMVC是Spring生态中最常用的Web层框架,几乎所有Java后端学习路线里它都是绕不开的一环。而对初学者来说,能不能顺利跑通第一个HelloWorld程序,直接影响后续学习的信心。本文将手把手演示一个完整的SpringMVC HelloWorld例子,从环境搭建、配置文件编写到控制器代码实现,再到Tomcat中运行验证,同时分析这个框架的优缺点以及入门阶段最容易踩到的坑。

一、SpringMVC HelloWorld完整实现步骤
先来说明整体思路。SpringMVC的核心是DispatcherServlet,它相当于整个框架的总调度员,所有请求先经过它,再由它分发给对应的Controller处理。理解了这一点,配置文件怎么写就容易看懂了。下面基于Spring 5.x版本和Maven搭建项目,整个过程同样适用于Spring 6,只需要把JDK换成17以上即可。
第一步,在pom.xml中引入依赖。除了spring-webmvc本身,还需要servlet-api,注意它的scope要设置为provided,因为Tomcat自带这个包,打包时不需要带进去。
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.30</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>第二步,配置web.xml。这里声明DispatcherServlet,并通过init-param指定Spring配置文件的位置。load-on-startup设为1表示容器启动时立即初始化这个Servlet。
<web-app version="4.0" xmlns="http://xmlns.jcp.org/xml/ns/javaee">
<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:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>第三步,编写springmvc.xml配置文件。这里主要做两件事:开启注解扫描,让容器识别Controller;配置视图解析器,把Controller返回的逻辑视图名拼接成实际的JSP路径。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.example.controller"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>第四步,编写控制器类。@Controller标记这是个控制器,@RequestMapping把URL映射到方法上,方法返回的字符串hello会被视图解析器处理,最终跳转到/WEB-INF/views/hello.jsp页面。
package com.example.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
@RequestMapping("/hello")
public String hello(Model model) {
// 向视图传递数据
model.addAttribute("message", "Hello World, SpringMVC!");
// 返回逻辑视图名,拼接后为 /WEB-INF/views/hello.jsp
return "hello";
}
}最后在WEB-INF/views目录下创建hello.jsp,用EL表达式取出message输出到页面。把项目部署到Tomcat,浏览器访问 http://localhost:8080/项目名/hello ,看到输出就说明第一个程序跑通了。
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
<title>HelloWorld</title>
</head>
<body>
<h1>${message}</h1>
</body>
</html>二、SpringMVC的优缺点分析
跑通例子之后,有必要冷静看待这个框架本身。SpringMVC的优点非常突出。首先是与Spring无缝集成,IoC、AOP这些能力可以直接在Web层使用,数据校验、事务控制都是现成的。其次是清晰的请求处理流程,HandlerMapping、HandlerAdapter、ViewResolver各司其职,出了问题容易定位到具体环节。再者,注解驱动的开发方式非常简洁,一个@RequestMapping就能完成过去需要大量XML才能实现的映射配置,参数绑定也高度自动化,表单数据、JSON报文都能自动转换成Java对象。
当然缺点也不能回避。对纯新手来说,入门门槛偏高,配置环节多,一旦某个XML写错,报错信息往往不够直观。传统的JSP视图方案现在已经显得过时,前后端分离成为主流后,SpringMVC更多承担接口层的角色,模板引擎的使用场景在收缩。另外,框架封装程度深,初学者容易只会用注解却不知道底层原理,面试问到DispatcherServlet的执行流程时就容易卡壳。这也是为什么建议学完HelloWorld后,一定要追一遍源码里的doDispatch方法。
横向对比一下:如果项目追求轻量和快速开发,SpringMVC加Spring Boot的组合依然是首选;如果只是极简的接口服务,Javalin、Vert.x这类轻量框架上手更快;而大型企业级项目里,SpringMVC的生态优势又很难被替代。选型的本质是匹配团队技术栈和项目规模,而不是盲目追新。
三、常见问题与注意事项
第一个高频问题是404。原因通常有这么几种:访问路径少了项目上下文名;url-pattern写成了/*,导致JSP请求也被DispatcherServlet拦截;控制器包没被component-scan扫描到;web.xml位置不对,没有放在WEB-INF目录下。排查时可以先看Tomcat启动日志里是否打印了RequestMapping的注册信息,如果没打印,基本就是扫描路径的问题。
第二个常见问题是中文乱码。GET请求乱码可以在Tomcat的server.xml中给Connector节点加上URIEncoding="UTF-8";POST请求乱码则需要在web.xml中配置CharacterEncodingFilter过滤器,注意这个过滤器必须放在所有Filter的最前面才生效。
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>第三个坑是静态资源被拦截。当url-pattern配置为/时,CSS、JS、图片等静态资源请求也会进入DispatcherServlet,找不到对应Handler就会404。解决办法是在配置文件中加上<mvc:default-servlet-handler/>,或者通过<mvc:resources>标签显式放行静态资源目录。
还有几个细节值得注意:JSP放在WEB-INF下是为了安全,外部无法直接访问,必须通过Controller转发;如果用了Spring 6和Spring Boot 3,相关的包名已经从javax换成了jakarta,导入依赖时别搞混版本;另外IDEA中建议开启自动构建并配置Tomcat的update resources选项,改代码后不用重启也能生效,开发效率会高很多。掌握这些要点后,再往深层学拦截器、文件上传、全局异常处理就会顺畅许多。
SpringMVC HelloWorldSpringMVC入门SpringMVC配置修改时间:2026-09-14 14:05:09