JavaWeb学习路线:从Servlet到Spring Boot的全链路解析

发布时间:2026/10/16 4:39:17
JavaWeb学习路线:从Servlet到Spring Boot的全链路解析 1. 为什么我在2024年才开始写JavaWeb学习日记打开博客后台准备敲第一篇文章的时候其实挺感慨的。做开发这几年断断续续用过不少框架也写过一些接口但一直没系统梳理过JavaWeb这条线。直到最近重新翻自己早年记的零散笔记才意识到很多当时会用但不明白的东西其实一直是靠背诵应付过来的。这个系列想写给两类人一类是刚接触JavaWeb、被各种概念绕晕的学生另一类是像我这样能跑通代码但内心总觉得根基不太稳的半路开发者。我的目标是把这个领域里那些教科书讲得太抽象、培训班又讲得太功利的内容用一个学习者的视角重新捋一遍。这一篇先不急着写代码而是把Web开发这座大厦的整体轮廓描清楚——它有哪些楼层、每层住着谁、数据是怎么在楼里跑来跑去的。开头先给一个最直白的结论JavaWeb不是一门技术而是一整条技术链的组合。很多人学不动的原因不是某一环太难而是始终不知道自己学的这个Servlet、那个Filter在整个链路里到底站在哪、负责什么。所以这篇日记的第一章我会先把这条链从用户浏览器到数据库完整走一遍再逐层拆开。注意这是一篇长文我不会为了显得专业堆术语每个概念尽量用生活类比说明白同时给出下一步可以去验证的实操入口。2. 浏览器到服务器的第一公里HTTP和URL在幕后做了什么很多人学Web开发第一个接触的抽象概念就是客户端—服务器但很少人认真想过你按下回车的那一刻电脑到底做了几件事。我把这个过程拆成五步每一步都可以通过浏览器自带的开发者工具亲眼验证。2.1 从你输入网址到看到页面的完整旅程假设你在地址栏输入了一个网址为避开真实域名这里我们用example-test.com代替。浏览器并没有嗖地一下就连到了某台服务器它做的事是先在本机缓存、系统hosts文件、本地DNS缓存里找这个域名对应的IP地址没找到就向最近的DNS服务器发起查询拿到真正的IP浏览器向这个IP的80或443端口发起TCP连接连接建立后组装一个HTTP请求报文发出去服务器返回HTTP响应报文浏览器解析HTML、加载CSS和JS、渲染页面。这五步听起来简单但每一步都值得展开。以第二步的DNS解析为例很多企业级问题都出在这个环节配置了CDN之后访问不稳定往往是不同地区DNS解析到了不同节点本地开发时改了hosts没生效往往是浏览器缓存了DNS记录。学习JavaWeb没必要一上来就深挖网络原理但至少要清楚HTTP是Web世界唯一的通用语言JavaWeb就是这门语言的服务器端方言体系。2.2 HTTP报文的真实长相用浏览器工具亲眼看一下我教过几个朋友看HTTP报文最好的办法不是背文档而是打开Chrome开发者工具F12切到Network面板刷新一个网页。你会看到一整列请求点开任意一个右侧会分门别类展示请求头、响应头、载荷数据。一个典型的GET请求大概长这样GET /index.html HTTP/1.1 Host: example-test.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Accept: text/html,application/xhtmlxml Connection: keep-alive对应响应可能是HTTP/1.1 200 OK Content-Type: text/html; charsetutf-8 Content-Length: 4821 Date: Mon, 11 Mar 2024 08:30:00 GMT这两段报文其实就是纯文本但恰恰是JavaWeb后端开发每天都要打交道的东西。比如Content-Type决定浏览器把响应当HTML还是JSON解析Set-Cookie决定登录状态如何保存在客户端Status Code的200、302、404、500分别代表什么这些是后端开发的基本功。这里分享一个我的笨办法刚学Servlet的时候我写了一个故意只返回hello world字符串的接口然后在响应头里轮流改Content-Type为text/plain和text/html亲眼观察浏览器渲染结果的差异。这个实验花不了十分钟但比背十遍Content-Type的作用都管用。3. 静态页面与动态页面区分JavaWeb到底Web在哪在我还没系统学习JavaWeb之前一直有个困惑我会写HTML和CSS也用过JavaScript为什么还要专门学一套Java的东西后来才想明白HTML、CSS、JS这些是前端的静态艺术而JavaWeb的核心价值在于——在服务器上动态生成HTML或者生成数据供前端动态渲染。3.1 静态页面写死了的文件所谓静态页面就是服务器上放着一个已经写好的.html文件用户请求什么服务器原样返回什么。就像你去一家餐厅菜单是印刷好的今天来是这个菜单明天来还是这个菜单。比如我本地放一个index.html内容固定是!DOCTYPE html html headtitle测试页/title/head body h1欢迎访问/h1 p当前时间写死在文件里/p /body /html不管谁访问、什么时候访问看到的都是这一模一样的内容。这种模式简单高效但对于需要定制内容的场景完全不够用——你不可能为每个用户手写一份不同的HTML文件。3.2 动态页面由程序现场加工出来的页面动态页面则相反服务器收到请求后会根据参数、数据库里的数据临时拼装出一份HTML返回给浏览器。还是餐厅类比动态页面更像是厨师根据你点的菜现场炒制同一个菜名加辣不加辣放葱不放葱出来的成品不一样。在JavaWeb里早期实现动态页面的技术叫Servlet后来有了JSPJava Server Pages再后来前后端分离兴起动态内容不再直接拼HTML而是返回JSON数据由前端JavaScript负责渲染。但不管形式怎么变底层的核心逻辑一致服务器接收请求解析请求参数URL里的Query String、表单Body、请求头等调用Java代码处理业务逻辑比如查数据库生成动态响应内容HTML或JSON通过HTTP响应返回给浏览器。3.3 一个最容易让初学者误解的点很多人初学JavaWeb时会以为Servlet就是用来写HTML的甚至觉得JSP是HTML的替代品。这其实是本末倒置。Servlet和JSP的定位都是服务器端生成动态内容它们本质是一家人JSP在运行时会被容器翻译成Servlet。后面系列文章里我会专门写一篇Servlet生命周期和JSP九大内置对象的拆解这里先记住结论JSP本质是Servlet的套壳模板学透ServletJSP就只剩语法壳子。4. JavaWeb技术栈全景图从Servlet到Spring BootJavaWeb发展了几十年技术栈层层叠加新人入门时最头疼的问题就是这么多框架和名词到底先学哪个、哪个已经过时、哪个必须在简历里写我根据自己的学习和面试经历把JavaWeb技术栈按时间线画了一张楼层图帮大家建立坐标系。4.1 底层地基Servlet规范和Servlet容器所有JavaWeb应用的基石是Servlet。需要注意Servlet本身只是一套Java接口规范javax.servlet.Servlet定义了Java类如何接收请求、返回响应。真正干活的是Servlet容器也叫Web容器它负责网络监听、请求解析、Servlet实例创建和销毁。最常见的容器是Tomcat之前还有Jetty、Undertow可选。一个最基本Servlet类长这样import javax.servlet.http.*; import javax.servlet.*; import java.io.IOException; public class HelloServlet extends HttpServlet { Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(text/html;charsetutf-8); response.getWriter().write(h1第一个Servlet/h1); } }这段代码的重点不在语法而在于它揭示了JavaWeb最原始的模型继承HttpServlet、重写doGet/doPost、操作request和response两个对象。后续所有框架本质上都是在这个流程外面包了一层又一层的便利设施。4.2 繁荣期三件套JSP、Filter、ListenerServlet之后出现的三样配套技术在今天依然有很多老项目在用JSP在HTML里嵌Java代码服务器动态渲染页面。早期后端一人包揽前后端时期的绝对主力。Filter过滤器可以在请求到达Servlet之前、响应返回给客户端之前对请求和响应做统一处理最典型的应用是登录校验、字符编码设置。Listener监听器监听应用启动、停止、Session创建销毁等事件常用于初始化全局配置。这三样是JavaWeb的经典原味如果你看老项目满眼都是它们的影子。但2024年的今天新项目基本不会直接用JSP写页面了转向了前后端分离架构。4.3 框架时代SSM到Spring Boot的演进JavaWeb真正进入框架时代是从Spring开始的。Spring的核心思想是容器管理对象——你不需要自己new一个Service对象而是告诉Spring什么类需要被管理、依赖怎么注入Spring在应用启动时帮你组装好一切。这个概念就是IoC控制反转和DI依赖注入之所以重要是因为它彻底改变了JavaWeb代码的组织方式从我们自己控制一切变成把控制权交给容器。SSMSpring Spring MVC MyBatis是2015年前后国内JavaWeb开发的标准套餐Spring负责整体容器管理、事务、AOPSpring MVC负责Web层把请求分发到对应Controller方法MyBatis负责数据库访问把SQL和Java方法绑定。再后来Spring Boot出现它的最大贡献不是新概念而是消灭了海量配置文件。以前配置一个Spring项目要写XML数据源、包扫描、事务管理器、视图解析器Spring Boot用约定大于配置的方式加上自动配置机制让项目几乎开箱即用的跑起来。现在的JavaWeb新项目十有八九是Spring Boot起步。4.4 一张表看懂当前主流技术选择我根据在实际项目中的使用频率列一个当前JavaWeb开发的技术选型参考表给不同目标的人参考应用场景主流选择替代方案我的备注Web接口开发Spring Boot Spring MVCJAX-RS新项目首选ORM/数据库访问MyBatis-Plus / Spring Data JPAJDBC / JdbcTemplate根据团队习惯选模板页面渲染Thymeleaf服务端渲染JSP已基本退出前后端分离则不用安全权限Spring Security / Sa-TokenShiro新手先学登录鉴权基础接口文档Knife4j / springdoc-openapiPostman手写文档团队协作必备这个表格并不是教大家无脑追新而是想说明一件事JavaWeb的学习路线可以从Servlet学到Spring Boot但不要迷失在框架丛林中。最重要的永远是HTTP模型、面向对象设计、数据库操作这几根支柱。5. 环境准备是第一道坎JDK、Tomcat、Maven和IDEA的配合关系说实话很多JavaWeb初学者不是被代码难倒的而是被环境配置挡住了。这一章我想花点篇幅把环境这件鸡毛蒜皮的小事讲透因为这是后续一切实操的地基同时也能帮你避开一堆常见的坑。5.1 先搞清楚这几个工具的关系用一个餐厅来比喻我们的JavaWeb开发环境JDKJava Development Kit就是厨师的厨艺工具箱没有它Java代码没法编译和运行。IDEA开发工具相当于厨房的操作台帮你切菜写代码、配菜管理项目结构。Maven相当于食材供应链管理帮你从中央仓库Maven中央仓库拉取各种食材——也就是第三方jar包同时管理它们的版本关系让你不用手动满网找jar包再往lib目录里扔。Tomcat相当于前厅服务员和后厨之间的传菜窗口你的Java程序编译完后不是一个独立的EXE而是一个Web应用war或目录必须被放进Tomcat这个容器里托管外部请求才会被正确送达。这四个工具缺一不可但它们各管各的新手常见的误会是以为装了IDEA就有了JDK或者以为安装了Tomcat就等于装了服务器。实际上IDEA可以自动帮你管理JDK路径但Tomcat需要单独下载、配置。5.2 我推荐的最小环境清单如果你现在从零开始建议按这个版本组合装JDK版本8或17。JDK 8是老项目的长期主流17是目前Spring Boot 3.x要求的基础版本。个人学习和新项目建议直接上17避免以后踩版本太低跑不了新框架的坑。开发工具IntelliJ IDEA Community版就够不需要盗版旗舰版Community版足够支撑纯JavaWeb学习创建项目时选择Maven Archetype的maven-archetype-webapp模板即可。构建工具Maven 3.9.x注意Maven本地仓库默认在用户目录.m2下国内网络建议配置阿里云镜像否则下载依赖等到怀疑人生。容器Tomcat 9.x或10.x版本。有个坑Tomcat 10后被Servlet规范移到了新包名jakarta.*很多老教程代码是javax.*照着写会报类找不到新手如果暂时不想纠结这个差异用Tomcat 9配合JDK 8或17最顺。5.3 第一个Hello Web应该怎么跑环境装完不少人又卡在我代码写了怎么看到效果这一步。这里给一个最不容易出错的流程IDEA里新建Maven Webapp项目生成标准的src/main/java和src/main/webapp/WEB-INF/web.xml结构写一个最简单的Servlet类参照上一章的示例代码在web.xml里配置Servlet映射或者用注解WebServlet(/hello)现在Tomcat支持注解方式简洁很多点击IDEA右上角配置Tomcat选择Deployment标签把当前项目Artifact挂到Tomcat上启动Tomcat浏览器访问http://localhost:8080/hello。如果你每一步都照着做却没有出现预期页面大概率是卡在Deployment这一步——Artifact没选对或者Application context配置错了路径。这类问题有个通用自查口诀看IDEA下部日志控制台的Tomcat报错信息比反复看代码更管用。我第一次配环境时绕了整整一天后来总结下来80%的启动失败问题日志里都会明明白白写着ClassNotFoundException或Port already in use之类的关键句。6. 写一个能处理请求的Servlet理解HttpServletRequest和HttpServletResponse理解了环境现在进入JavaWeb的第一段真正的编码体验。这一章我打算用一个非常典型的业务场景——用户登录注册的简化版——来串起Servlet开发的核心操作。这样做的原因是登录注册几乎涵盖Web后端最常用的功能模块以此为切入点学Servlet学到的每个知识点都能直接映射到现实开发。6.1 从浏览器拿到用户参数用户登录时需要把用户名和密码传给服务器。最常见的传参方式有两种GETURL后面跟?usernameabcpassword123和POST请求体里传表单数据。在Servlet里取参数的方式完全一样WebServlet(/login) public class LoginServlet extends HttpServlet { Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(utf-8); String username request.getParameter(username); String password request.getParameter(password); response.setContentType(text/html;charsetutf-8); response.getWriter().write( h2收到请求 username /h2 ); } }这里有三个点值得停下来解释request.setCharacterEncoding(utf-8)是在读取Body参数之前调用的如果放在getParameter之后再调用就来不及了。这个先设置再读取的顺序是中文乱码问题最重要的避坑规则。response.getWriter()拿到的是向客户端输出文本的字符流一定要在首次获得Writer之前设置ContentType否则可能输出乱码。为什么用doPost而不用doGet因为登录信息属于敏感数据POST不会被浏览器记录在URL历史里也不容易被日志直接打印。6.2 请求转发和重定向两个看起来像但本质不同的跳转写Web应用的时候经常会遇到登录成功后跳转到首页这样的需求。JavaWeb里有两种实现方式forward和sendRedirect。我当年分不清后来用一句话记牢forward是服务器内部转发地址栏不变sendRedirect是浏览器重新发起请求地址栏会变。具体来说// 服务器内部转发浏览器地址栏依然是 /login request.getRequestDispatcher(/welcome).forward(request, response); // 302重定向浏览器地址栏会变成 /welcome response.sendRedirect(welcome);选择哪种取决于业务场景。如果登录成功后只是想让用户看到结果页用forward更快如果登录后想彻底跳到另一个URL比如防止表单刷新重复提交用sendRedirect更合理。后续写登录拦截器的时候这些概念都会反复出现。6.3 踩坑记录为什么我的表单提交后中文全是问号分享一个我早期真实踩过的坑也大概率是每个JavaWeb初学者都会遇到的表单里输入中文提交后控制台打印出来全是???。排查思路是先看请求是不是POST并且Body带的是UTF-8编码——排除前端问题再检查Servlet代码里是否在getParameter之前调用了setCharacterEncoding——这是原因如果还是没有修复再检查IDEA里Tomcat的VM options是不是设置了-Dfile.encodingGBK——这种情况会出现日志显示正常、程序里乱码的双重乱码问题。我当时的情况就是第二种。因为在一个教程里看到别人写了setCharacterEncoding但没注意到他写在了getParameter之后导致我跟着抄也没生效。后来我养成一个习惯凡是Servlet处理中文第一行就是设置编码不只对POST Body设UTF-8还会在响应时设置同样的字符编码。这套组合拳打下来乱码问题基本能规避九成。7. Servlet生命周期和配置细节容器比你想象中管得多很多教程会把Servlet生命周期放到很靠前的位置讲我反而想放在这里因为只有你亲手写过一个Servlet并在服务器日志里看到那些输出才能真正理解生命周期四个字的含义。7.1 init、service、destroy三个关键时刻Servlet的生命周期由容器Tomcat接管我们作为开发者只需要继承HttpServlet并重写特定方法。生命周期主要经过三个阶段init()Servlet被首次加载或首次请求到达时调用一次常用于初始化资源如加载配置文件、建立数据库连接池。service()每次请求都会进入这个方法。HttpServlet已经帮我们实现好service它会根据请求方法分发到doGet、doPost等重写方法里。destroy()应用关闭或Servlet被卸载时调用一次常用于释放资源。一个常见到令人意外的现象是Servlet默认不是启动时就创建的而是第一个请求到达时才实例化。所以很多人会写一个init()里加了打印的Servlet启动Tomcat发现控制台没有输出以为代码没生效。其实不是只是你这个Servlet还没被第一次使用而已。想让容器启动时就初始化Servlet可以在配置里指定load-on-startup1/load-on-startup。7.2 单实例多线程的并发模型Servlet容器的一个经典设计是每一个Servlet在容器中只有一个实例单例但它要同时服务所有并发请求每个请求由独立线程执行。这意味着如果你在Servlet类里定义了成员变量用于存储用户数据那么不同请求的线程会同时读写这个变量极易产生并发安全问题。我见过很多初学者写的代码:public class BadServlet extends HttpServlet { private String username; // 危险 protected void doPost(...) { username request.getParameter(username); // 后续逻辑使用username } }如果请求A设置了username为A请求B紧接着设置了B然后A的逻辑继续往下执行时读到的可能就不是userA了结果就是数据串号。正确的做法是Servlet类不存请求相关的可变状态数据一律通过方法参数或局部变量传递。这一点不只是面试爱问项目写多了迟早会遇到。7.3 从web.xml到注解配置方式的演进早期Servlet必须在web.xml里按这个方式配置servlet servlet-nameloginServlet/servlet-name servlet-classcom.example.LoginServlet/servlet-class /servlet servlet-mapping servlet-nameloginServlet/servlet-name url-pattern/login/url-pattern /servlet-mapping现在Tomcat支持注解简化WebServlet(name loginServlet, urlPatterns /login) public class LoginServlet extends HttpServlet { ... }两者作用是等价的urlPatterns就是映射的URL。不过我的建议是初学阶段还是把web.xml的配置方式亲手写几遍。因为等你后面学Spring MVC时会看到很多前端控制器DispatcherServlet映射字符编码过滤器配置之类的概念如果连最原始的web.xml都看不懂框架里的那些配置对你来说就永远是黑盒。8. 绕过教科书顺序聊聊初学JavaWeb真正应该养成的三个习惯最后这一章不写具体代码想聊些更软的东西。我在带几个新人朋友入门时发现技术细节能通过查资料补齐但学习方法和调试思维上的差距会直接影响学习效率。如果你正准备系统性学习JavaWeb有这三个习惯越早养成越好。8.1 日志不是报错后的救命稻草而是开发过程中的仪表盘我在前面已经提过两次看日志。这里想认真强调一下很多初学者遇到报错第一反应是读红色异常信息但Tomcat的控制台日志信息量大且混杂新手往往只看最后一行Exception开头的内容错过了更早的Caused by。这个问题在我每次排查时都很常见——真正的根因很少在最后一行往往出现在某个at com.example.xxx的堆栈里中间夹着Servlet.service() threw exception这类容器包装信息。我自己处理日志的一个方法是阅读异常信息时从底部往上找第一个出现自己项目包名的行。那是离你的代码出错最近的地方。另外从第一天起就给自己的每个Servlet配置slf4j日志而不是System.out.println虽然初期略麻烦但长期收益巨大——到时候你就知道为什么所有框架都在用日志框架而不建议太多控制台输出了。8.2 学会最小化验证而不是在烂代码上缝缝补补我见过不少人写了个几百行的Servlet一运行出错就开始一行行检查哪儿写错了结果越看越糊涂。更高效的做法是把业务逻辑临时注释掉先写一个只输出固定字符串的最小版本确认请求能到Servlet、响应能返回再逐步把业务代码加回来。这个过程叫最小化验证它能帮你快速锁定问题到底在链路哪一环是请求没到Servlet写错了还是响应输出有问题每次碰到疑难杂症我都默认遵循二分排查先确认请求能进代码再确认数据能取到再确认逻辑没报错最后看响应格式。按这个顺序把问题按层切分远比在一个大报错信息里猜答案高效。8.3 建立自己写个框架的思维实验学Servlet时会接触到Filter、Listener、Session、Cookie这些概念如果只看它们各自的功能容易记了就忘。我推荐一个思维实验想象一下如果让你自己设计一个纯Java的Web框架在Servlet基础上你打算用哪个组件做权限拦截哪个组件做统一编码哪个组件做全局参数读取答案其实很直接Filter做拦截Listener做启动初始化Session做状态保持。当你从设计者角度理解这些组件的分工学到的就不仅仅是Filter是过滤器这句话而是为什么需要过滤器以及过滤器放在哪里最合适。这个思维实验对我后续学Spring MVC帮助巨大因为框架里那些Interceptor、AOP概念其实都隐藏着Servlet时代的老影子。9. 写在第一篇日志的结尾下一站学什么以及给初学者的路线图按计划这篇只是系列的开胃菜重点是把Web开发的全貌、JavaWeb的定位、Servlet的核心模型和常见环境配置讲清楚。下一篇我打算深入Servlet的会话跟踪技术把Cookie、Session、Token这条线完整捋一遍并写一个可运行的登录状态保持Demo。因为登录状态管理几乎是每个Web应用绕不开的硬骨头也是从Servlet转向框架之前必须打牢的底子。给你一个当前阶段我认为合理的JavaWeb学习路线图参考HTML/CSS/JavaScript基础会写简单页面、理解DOM操作和Ajax请求Java SE基础重点是面向对象、集合、IO、异常、多线程基础MySQL基础能写增删改查SQL理解主键、外键和简单索引本篇内容——Servlet和Tomcat基础理解HTTP、请求响应模型JSP简单了解即可重点放在会话管理和过滤器Spring、Spring MVC、MyBatis三大框架Spring Boot整合实践做一个完整的CRUD项目之后视方向选择微服务、前端框架深入学习、部署运维等。这个路线不是死的但如果你的目标是找一份Java开发工作前七步几乎是所有人都会走的路径。区别在于有的人每一步都是背概念糊弄过去有的人像我一样重新回来逐层补课。这个系列就是我补课的详细记录。如果你正卡在某个具体环节比如Tomcat启动失败、Maven依赖下载不下来、Servlet注解不生效可以先翻翻我前面提到的排查方法——先看日志、再做最小化验证、再逐层拆。我在后续日记里也会把这些高频问题单独开篇详聊。下一篇文章见。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询