我一直建议刚学JavaWeb的同学直接用IDEA社区版来练手,原因很简单:免费、干净、不用折腾任何激活相关的东西,而且该有的功能一样不少。很多人一听“社区版”就觉得做不了Web开发,其实根本没这回事——JavaWeb核心就是Servlet、JSP、JDBC这一套,跟IDE是否收费没有必然关系。这篇教程我就把整套流程从头到尾捋一遍,从工具下载、环境配置,到用Maven创建一个完整的Web项目,再到集成Tomcat跑出第一个页面,所有步骤都是我自己实测过的,属于保姆级中的保姆级。
这篇内容适合两类人:一是刚学完JavaSE,准备进军Web开发的自学者和学生,二是公司电脑只能装免费版IDE、又想快速验证项目的开发者。不管你是Windows还是macOS,思路完全一样,只是个别安装路径和快捷键略有差异。我会把每个环节的“为什么这么做”也讲清楚,这样你以后换任何工具都不会慌。
1. 写在前面:社区版IDEA到底能不能做JavaWeb
1.1 旗舰版和社区版的关键差异
很多人在下载IDEA时会纠结:到底装Ultimate(旗舰版)还是Community(社区版)?旗舰版功能确实全,自带Java Enterprise开发向导、Spring/MyBatis等框架的图形化支持,还能直接在IDE里配置Tomcat、打War包,整体体验很顺。社区版则砍掉了一部分企业级开发功能,但保留了最核心的代码编辑、重构、调试、版本控制、Maven集成、终端等能力。
具体到JavaWeb开发,社区版缺失的最关键功能是“应用服务器集成”,也就是说你在Run配置里找不到添加Tomcat的入口,无法一键部署Web项目。这导致很多人误以为社区版做不了JavaWeb。但实际上,Web项目本质就是一个按照特定目录结构打包的Java程序,IDE只是辅助工具。我们完全可以用Maven来管理依赖和构建,再通过免费插件或者Maven命令来启动Tomcat,实现和旗舰版几乎一样的开发体验。
我用社区版搭过不下十个教学项目,从最经典的用户登录注册,到带数据库的商品管理,全部跑得很稳。功能上没有任何问题,只是中间需要补一个Smart Tomcat插件,这个在后面会详细讲。
1.2 这套方案适合谁
如果你正在学JavaWeb,目标是把Servlet、JSP、Session、Filter、JDBC这些基础概念搞懂,那社区版完全够用。因为教学项目基本不依赖框架,不需要IDEA提供所谓的框架支持,Maven本身就能解决依赖问题。
另外,社区版是Apache 2.0协议开源的,可以放心在公司或学校电脑上使用,不存在授权风险。对于预算有限的学生党来说,社区版是零成本起步的绝佳选择。我见过不少朋友为了用旗舰版到处找激活资源,结果电脑中毒或者软件不稳定,实在没必要。
还有一部分人适合这套方案:你已经装了旗舰版,但公司合规要求不能使用盗版工具;或者你只是临时想跑一个JavaWeb小项目,不需要重型框架。这时候社区版加上Maven骨架,三分钟就能把项目拉起。
2. 开始之前:把环境一次配到位
2.1 JDK选型与环境变量配置
JavaWeb项目跑在JVM上,因此JDK是第一步。我推荐大多数新手直接装JDK 8或者JDK 11,这两个版本在学习和就业场景中覆盖率最高,各种教程和开源项目的兼容性也最好。如果你用的是比较新的IDEA版本,JDK 17也可以,但要注意Tomcat版本和Maven编译参数,避免出现不兼容问题。
安装JDK很简单,去Oracle官网或者Adoptium下载对应系统的安装包,一路Next即可。这里要特别提醒:安装路径不要带中文,不要带空格,推荐直接装在D:\Java\jdk1.8这种简单目录。装完之后需要配置环境变量:
- 新建系统变量
JAVA_HOME,值填JDK安装路径,比如D:\Java\jdk1.8。 - 编辑系统变量
Path,新增一行%JAVA_HOME%\bin。
配置完成后,打开命令行输入java -version,如果能看到版本信息,说明JDK安装成功。很多新手卡在这一步是因为环境变量配置后没有重新打开命令行窗口,Windows下环境变量修改不会自动刷新到已经打开的终端里。
2.2 Maven安装与镜像换源
Maven是Java项目最常用的构建工具,负责依赖下载、编译打包。它的核心优势在于:你只需要在pom.xml里声明要用哪些库,Maven会自动下载并管理版本,不用再手动把jar包复制到lib目录。
下载Maven同样选择二进制压缩包,解压到纯英文路径,比如D:\Maven\apache-maven-3.9.6。然后配置系统变量:
- 新增
MAVEN_HOME,值为Maven解压目录。 - 编辑
Path,新增%MAVEN_HOME%\bin。
验证方法是在命令行执行mvn -v,看到Maven版本即表示成功。接下来有个关键操作:修改Maven的settings.xml。这个文件位于Maven目录下的conf文件夹里。你需要做两件事:
第一,修改本地仓库路径。默认仓库存放在C:\Users\你的用户名\.m2\repository,如果C盘空间紧张,建议改到其他盘。在settings.xml中找到<localRepository>标签,改为D:\Maven\repository。
第二,配置阿里云镜像。由于Maven中央仓库服务器在国外,下载依赖经常很慢甚至超时,使用阿里云镜像后速度会提升好几个量级。在<mirrors>节点里添加:
<mirror> <id>aliyunmaven</id> <mirrorOf>central</mirrorOf> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/repository/public</url> </mirror>这一步看起来不起眼,但对开发体验影响巨大。我见过不少同学在创建项目时卡在“Downloading...”界面半天没反应,其实就是镜像没有配置。
2.3 IDEA社区版下载与安装
IDEA社区版官方下载地址是JetBrains官网,进入后选择Community版本下载即可,注意不要下成Ultimate的试用版。安装过程和普通Windows软件无异,但有几个细节值得留意:
- 安装选项里建议勾选“Add to PATH”和“Create Desktop Shortcut”,这样可以方便地在命令行启动IDE。
- 如果你之前装过其他版本的IDEA,建议安装时不要共用同一个配置目录,否则可能引发插件冲突。
- 首次启动会进入主题选择和插件安装界面,选择默认的Darcula深色主题即可,后续可以再换。
IDEA社区版内置了Maven支持,所以你不需要额外安装Maven插件。但需要在IDEA里配置一下Maven路径:File -> Settings -> Build, Execution, Deployment -> Build Tools -> Maven,把Maven home path改成你刚才解压的目录,同时把User settings file指向你修改过的settings.xml。这样IDEA和命令行Maven使用相同的本地仓库,能避免很多“我在IDEA里能编译,命令行却报错”的奇怪问题。
2.4 Tomcat与MySQL环境准备
JavaWeb项目最终跑在Servlet容器里,这里选择Tomcat,免费、轻量、资料多。我强烈建议新手使用Tomcat 9.x版本,不建议直接上Tomcat 10或11。原因在于Tomcat 10开始把javax.servlet包名迁移成了jakarta.servlet,而目前绝大多数教学代码、老项目和网上的案例都还是javax开头。如果你用Tomcat 10跑传统教学代码,会频繁遇到包名找不到的报错,排查起来非常打击信心。
Tomcat的安装方式有两种:一是下载zip解压版,配置环境变量后直接用;二是通过IDE插件自动管理。对于初学者,我更推荐下载zip解压版放在固定目录,因为后面配置插件时需要手动指定Tomcat路径。
MySQL方面,你只需要安装一个8.x版本即可,安装时记住root密码。在JavaWeb学习阶段还不需要接触复杂的数据库管理,所以这里不展开。如果你暂时还没装MySQL,可以先跳过数据库部分,先把Servlet和JSP跑通,后面的学习再慢慢补上。很多人一上来就想把数据库环境全部搭好,结果卡在环境层面,代码一行没写,这样很影响信心。
3. 创建项目:社区版建JavaWeb项目的正确姿势
3.1 为什么不能用普通的Java项目直接做
社区版没有Java Enterprise向导,所以你在New Project里找不到“Web Application”这个选项。有些同学会退而求其次,创建一个普通的Java项目,然后手动新建webapp目录,再导入一堆jar包。这种方法不是不行,但有两个问题:第一,jar包管理全靠手动,一旦依赖版本冲突,排查起来极其痛苦;第二,项目结构不规范,后续转用Maven或Gradle还得重来。
更好的方案是直接用Maven骨架创建项目。Maven的maven-archetype-webapp就是专门用来生成JavaWeb项目骨架的,它会自动创建标准的目录结构,并且通过pom.xml管理依赖。这也是目前大多数教学案例采用的方式。
具体操作如下:
- 打开IDEA,点击
File -> New -> Project。 - 左侧选择
Maven,不要选Spring Initializr,因为那主要用来创建Spring Boot项目,不适合当前场景。 - 勾选
Create from archetype,在列表中找到org.apache.maven.archetypes:maven-archetype-webapp。 - 填写
GroupId(一般是公司域名倒写,比如com.example)、ArtifactId(项目名,比如javweb-demo)、Version(默认1.0-SNAPSHOT即可)。 - 点击
Finish,等待Maven下载骨架和依赖。
第一次创建时Maven会下载大量依赖,耗时根据网络状况各异。这时候Ctrl + Shift + S打开设置,检查Maven配置是否指向了本地目录和阿里云镜像,如果没问题,一般两三分钟就能完成。
3.2 补全标准Web目录结构与注意事项
用骨架生成的目录默认长这样:
src/main/webapp/ index.jsp WEB-INF/web.xml看起来是不是有点简陋?没错,maven-archetype-webapp骨架比较老,默认只生成webapp目录,src/main/java目录并不存在。我们需要手动补全标准JavaWeb的目录结构:
src/main/java:存放Java源码,标记为Sources Root。src/main/resources:存放配置文件,标记为Resources Root。src/test/java:存放测试代码,标记为Test Sources Root。
手动创建的步骤是:右键src/main目录 ->New -> Directory,输入java,然后右键java目录 ->Mark Directory as -> Sources Root。同理创建resources目录并标记为Resources Root。
另一个重要细节是web.xml的版本。骨架默认生成的web.xml是Servlet 2.3版本的声明,这会导致很多现代特性不可用,比如@WebServlet注解无法被识别。我强烈建议你直接替换成Servlet 3.1版本的声明:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> </web-app>这一步不处理的话,你后面用注解写Servlet时很可能会遇到404或者页面无法加载的情况,而且这类问题从报错日志里看往往不明显,新手很容易陷进去。
3.3 在pom.xml中加入Servlet、JSP、MySQL依赖
项目的pom.xml是Maven的核心配置文件。骨架生成的pom.xml内容很简单,我们需要手动补充依赖。以下是我在生产教学项目中常用的依赖配置:
<dependencies> <!-- Servlet API --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> <!-- JSP API --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.3</version> <scope>provided</scope> </dependency> <!-- JSTL 标签库,如果后续用到可以加上 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- MySQL 驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> </dependencies>这里有几个关键点要解释清楚。第一,Servlet API和JSP API的scope是provided,意思是编译时需要,但打包和运行时不需要,因为Tomcat容器自带这些jar包。如果你忘记设置provided,打出的War包会把Servlet API也包含进去,部署到Tomcat时容易引发类冲突。
第二,MySQL驱动版本要和你的MySQL版本对应。如果你装的是MySQL 5.7,驱动用5.1.47更稳;如果是MySQL 8.x,就用8.0.33或更高版本。我遇到过同学拿着MySQL 8的驱动去连MySQL 5.7,报错信息五花八门,最后发现是驱动版本不匹配。
此外,考虑到你使用的JDK版本,可能还需要在pom.xml的build节点中指定Maven编译插件的版本和源码级别:
<build> <finalName>javaweb-demo</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build>这里的<finalName>决定了最终打出的War包名称,也直接影响访问路径。如果你设置成javaweb-demo,部署后就要通过http://localhost:8080/javaweb-demo/来访问,不能想当然地认为是项目名。
4. 写代码:先跑通一个Servlet+JSP
4.1 编写前端页面index.jsp
骨架默认生成的index.jsp是一个“Hello World”示例,内容比较简单。我们先把它改造成一个带表单的登录页面,这样既能演示JSP语法,又能为后面的Servlet交互做准备。
右键src/main/webapp下的index.jsp,删除原有内容,替换成如下代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>用户登录</title> <style> body { font-family: Arial, sans-serif; max-width: 400px; margin: 50px auto; padding: 20px; border: 1px solid #ddd; border-radius: 5px; } input { width: 100%; padding: 10px; margin: 8px 0; box-sizing: border-box; } button { width: 100%; padding: 10px; background: #4CAF50; color: white; border: none; border-radius: 3px; cursor: pointer; } </style> </head> <body> <h2>欢迎使用JavaWeb示例</h2> <form action="loginServlet" method="post"> <label for="username">用户名:</label> <input type="text" id="username" name="username" required> <label for="password">密码:</label> <input type="password" id="password" name="password" required> <button type="submit">登录</button> </form> </body> </html>这里有个细节:<%@ page contentType="text/html;charset=UTF-8" language="java" %>这一行声明了页面编码为UTF-8,可以避免中文乱码。很多同学在JSP里写中文出现乱码,第一反应是改IDE编码,其实首先要检查的是这一行的charset设置。
4.2 编写后端Servlet
在src/main/java下新建包,比如com.example.servlet,然后创建LoginServlet类。这里我们使用@WebServlet注解来配置URL映射,而不使用web.xml,这也是Servlet 3.0之后推荐的写法。
package com.example.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/loginServlet") public class LoginServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置请求和响应编码,防止中文乱码 request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); String username = request.getParameter("username"); String password = request.getParameter("password"); PrintWriter out = response.getWriter(); if ("admin".equals(username) && "123456".equals(password)) { out.write("<html><body>"); out.write("<h2>登录成功,欢迎 " + username + "!</h2>"); out.write("<a href='index.jsp'>返回首页</a>"); out.write("</body></html>"); } else { out.write("<html><body>"); out.write("<h2>用户名或密码错误</h2>"); out.write("<a href='index.jsp'>重新登录</a>"); out.write("</body></html>"); } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 如果通过GET访问,转发到登录页面 response.sendRedirect("index.jsp"); } }这个Servlet逻辑很简单,但涉及两个必须掌握的要点:
第一,请求编码设置要在读取参数之前完成,否则中文参数可能已经乱码了。request.setCharacterEncoding("UTF-8")必须在request.getParameter()之前调用。
第二,响应内容的编码要通过response.setContentType("text/html;charset=UTF-8")来指定。如果你输出的是纯文本但忘了设置编码,浏览器会按照默认编码解析,中文照样乱码。
写完Servlet后,还有一件很重要的事:确保web.xml里没有重复映射这个URL。如果你在web.xml里配置了一个<servlet-mapping>指向/loginServlet,同时又在代码里写@WebServlet,启动时会报重复映射错误。既然我们使用注解方式,web.xml保持我上面给的3.1版本空模板即可。
4.3 一个简单的JDBC连接MySQL示例
登录功能跑通之后,就可以尝试接入数据库了。这里给一个最简单的JDBC查询示例,目的不是写复杂的业务,而是让你验证JDBC环境是否正常。
package com.example.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; @WebServlet("/dbTest") public class DbTestServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); String url = "jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=Asia/Shanghai"; String user = "root"; String password = "你的数据库密码"; try { Class.forName("com.mysql.cj.jdbc.Driver"); Connection conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT '数据库连接成功' AS info"); if (rs.next()) { out.write("<h3>" + rs.getString("info") + "</h3>"); } rs.close(); stmt.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); out.write("<h3>数据库连接失败: " + e.getMessage() + "</h3>"); } } }注意几个容易踩的坑:MySQL 8.x驱动的类名是com.mysql.cj.jdbc.Driver,老版本是com.mysql.jdbc.Driver,别写错。连接URL中serverTimezone=Asia/Shanghai必须加上,否则会报时区错误。另外,这个写法只是为了最快的验证环境,在真实项目中一定要使用连接池,比如Druid或HikariCP,否则高并发下数据库连接很容易被打满。
5. 部署运行:用Smart Tomcat让项目跑起来
5.1 为什么社区版没有Tomcat Server配置入口
这是社区版使用者最常问的问题。在旗舰版中,Run/Debug Configurations左侧有“Tomcat Server”选项,点击加号就能添加本地Tomcat并部署项目。但社区版把这个功能砍掉了,你翻遍整个设置界面也找不到。这并不意味着社区版不能跑Tomcat,解决方案是使用免费插件Smart Tomcat。
Smart Tomcat插件的原理很简单:它通过IDEA的Run机制调用你本地的Tomcat,把当前项目的Web目录部署到Tomcat上,从而实现一键启动和停止。它本质上是外部Tomcat的“遥控器”,而不是把Tomcat集成到IDE里。
5.2 Smart Tomcat插件的安装与配置
安装步骤:
- 打开IDEA,进入
File -> Settings -> Plugins。 - 在
Marketplace搜索框中输入Smart Tomcat。 - 找到插件后点击
Install,安装完成后重启IDEA。
重启后,进行运行配置:
- 点击IDEA右上角的运行配置下拉框,选择
Edit Configurations...。 - 点击左上角加号,找到
Smart Tomcat选项。 - 填写配置信息:
Tomcat Server:选择你本地Tomcat的安装目录,比如D:\Tomcat\apache-tomcat-9.0.82。Context Path:建议填项目名,比如/javaweb-demo。这个值决定了访问路径,很重要。Deployment Directory:选择项目的src/main/webapp目录。- 其他选项保持默认。
配置完成后点击OK。此时右上角会出现一个绿色的启动按钮,点击它,IDEA会自动启动Tomcat并在浏览器中打开项目地址。
访问http://localhost:8080/javaweb-demo/,你应该能看到刚才编写的登录页面。输入admin和123456,如果能正常跳转,恭喜你,一个完整的JavaWeb项目已经跑起来了。
这里有两个容易出问题的点:第一,Context Path写法和URL访问路径必须一致。如果你在配置里填了/javaweb-demo,浏览器地址一定要用/javaweb-demo,二者不匹配时会出现404。第二,Deployment Directory一定要选到webapp目录,不能选项目根目录,否则JSP页面和静态资源不会被拷贝到Tomcat的部署目录。
5.3 通过Maven的tomcat7插件运行(备选)
除了Smart Tomcat插件,还有一种纯Maven的启动方式:在pom.xml中加入tomcat7-maven-plugin,然后通过命令行或IDEA的Maven面板执行tomcat7:run。
<plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <port>8080</port> <path>/javaweb-demo</path> <uriEncoding>UTF-8</uriEncoding> </configuration> </plugin>这个方式的优点是配置简单,不依赖任何IDE插件;缺点是插件停更较早,对Servlet 3.1和WebSocket等新特性的支持有限。如果你只是写一些基本的Servlet和JSP,它完全够用。但如果后面用到更现代的特性,还是建议用Smart Tomcat或者直接部署到外部Tomcat。
在实际项目中,我一般会把Smart Tomcat作为首选开发工具,因为它和IDEA的集成度更高,日志输出也更清晰。在需要模拟线上环境或做正式部署时,再改用外部Tomcat手动部署War包。
6. 常见问题与避坑实录
6.1 部署后404、报404怎么办
404是最常见的报错,而且新手一旦遇到404就慌了,其实排查思路很清晰。
第一步,看URL的Context Path是否正确。假设你配置的Context Path是/javaweb-demo,那访问路径必须是http://localhost:8080/javaweb-demo/index.jsp。少写一个/javaweb-demo,Tomcat会去根目录找资源,自然返回404。第二步,确认资源是否真的在webapp目录下。JSP文件必须放在src/main/webapp目录里,如果放到了WEB-INF目录下,直接通过URL是访问不到的。第三步,确认Tomcat是否真的完成了部署。启动日志里如果出现Deploying web application directory...和Deployment of web application ... has finished,说明部署成功;如果只是启动成功但没部署,检查Deployment Directory配置。
我见过一个特别有意思的案例:有个同学每次启动都成功,但页面就是404,最后发现他把src/main/webapp和src/main/java的根目录标记搞反了,导致整个项目的目录结构在IDEA里被错误识别,编译后的class文件放到了错误的位置。所以目录标记这块一定要细心。
6.2 端口被占用、页面中文乱码
Tomcat默认使用8080端口,如果这个端口被其他程序占用,启动时会报Port 8080 was already in use错误。解决方法有三种:一是关掉占用端口的程序,在命令行执行netstat -ano | findstr 8080查出进程号,然后taskkill /PID 进程号 /F杀掉;二是改Tomcat的端口,在conf/server.xml里把8080改成其他端口;三是用Smart Tomcat配置里的端口参数修改。我个人推荐优先使用前两种,因为很多Web应用的端口是约定俗成的,频繁改端口容易造成混淆。
中文乱码这个问题出现的频率也极高。乱码可以从三个层面排查:文件编码层面,确保IDEA的全局编码、项目编码、文件编码都是UTF-8,可以在Settings -> Editor -> File Encodings中统一设置;HTTP请求响应层面,在Servlet里调用request.setCharacterEncoding("UTF-8")和response.setContentType("text/html;charset=UTF-8"),Tomcat的server.xml中Connector节点加上URIEncoding="UTF-8";数据库层面,MySQL连接URL中加上characterEncoding=utf8参数。
6.3 依赖冲突:Servlet-api重复、jakarta包名
很多新手在第一次打War包或者部署到Tomcat时会遇到奇怪的ClassCastException或者ClassNotFoundException,最后发现是Servlet API重复引入导致的。如果你在pom.xml中把javax.servlet-api的scope设置成默认的compile,那么这个jar包会被打进War包的WEB-INF/lib目录。而Tomcat自身也带有Servlet API,同一个类被加载两次,就会引发各种诡异的问题。解决办法就是严格使用provided作用域,让编写和编译时使用API,运行时由容器提供。
另外,如果你不小心下载了Tomcat 10及以上版本,在运行网上的老代码时会看到类似java.lang.ClassNotFoundException: javax.servlet.Filter的报错。这是因为Tomcat 10后包名从javax.servlet变成了jakarta.servlet。如果你对Servlet和Tomcat的关系还不够熟悉,最简单的办法就是换用Tomcat 9,等你理解了包名迁移的来龙去脉后再升级也不迟。
6.4 我的几个实践经验
最后分享几条我在实际搭建项目过程中的体会。
第一次用社区版做JavaWeb,千万别一上来就追求“完美架构”或者“企业级规范”,先把最基础的项目启动起来最重要。我记得自己第一次搭项目,光环境配置就折腾了一个周末,最后发现只是JDK版本不对。后来熟练了,从空白环境到一个能跑的Servlet项目,十分钟就能完成。熟练来自重复,重复来自不怕错。
第二,遇到问题先看日志。很多同学在浏览器里看到一个500或者404,第一反应是去网上搜索,但缓存中的异常堆栈往往才是关键信息。IDEA的Run面板里会输出Tomcat的catalina日志,浏览器页面上的错误提示也值得仔细看,不要只盯着一句“访问失败”。
第三,先跑通“空壳”项目,再加业务逻辑。我一般会先创建一个只有index.jsp的空项目,部署成功后,再逐步增加Servlet、JDBC、Filter等组件。每次只增加一个组件,这样出了问题能立刻定位到是哪一步导致的。如果你一次性把代码全写完再启动,报错时根本不知道从哪里查起。
第四,学会用Maven的离线模式。如果你网络状况不稳定,Maven下载依赖断断续续,可以先用mvn -o离线模式看看本地仓库有没有缓存。当然这只是一个临时方案,治本的办法还是配置好阿里云镜像。
这个项目跑通之后,你可以继续扩展很多方向:用Filter写一个简单的登录拦截器,用Session实现记住登录状态,用JDBC把用户信息存入数据库,再到后面接上MyBatis、Spring MVC等框架。但无论后面的路怎么走,最开始的这套环境搭建、项目创建、Servlet和JSP交互的流程,都是你理解JavaWeb的基础底座。把这个底座打扎实了,后面的学习会顺很多。
我个人在实际操作中的体会是:工具只是辅助,关键是理解原理。社区版IDEA少了图形化的Web项目向导,反而逼着我搞清楚了Maven项目的目录结构、Servlet容器的部署机制、依赖作用域这些底层概念,这对后续学习框架有非常大的帮助。现在让我去看Spring Boot的自动配置,我一点都不觉得神秘,因为我已经知道Tomcat是怎么把Web应用跑起来的了。所以,如果你现在用的也是社区版,别觉得低人一等,它恰恰是帮你打好基本功的最好工具。
最后再分享一个小技巧:如果你经常创建类似的项目,可以把一套已经配置好的pom.xml、web.xml和目录结构保存为模板,或者直接用IDEA的Save Project as Template功能。下次新项目直接复用,省去重复配置的时间,把精力集中在业务代码上。