ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

JavaWeb必学:HTTP协议从报文解析到乱码排查的实战指南

JavaWeb必学:HTTP协议从报文解析到乱码排查的实战指南 学JavaWeb第一座必须翻过去的大山就是HTTP协议。我说句实在话很多人学了半年Servlet、JSP、SpringMVC接口也写过不少但问他“浏览器发一个POST请求Tomcat到底是怎么把表单数据塞进request里的”照样一脸懵。这不怪你因为大部分教程都是先扔给你十几个Servlet接口让你背等真正出了问题——乱码、404、405、请求参数拿不到——才发现自己连HTTP报文长什么样都没见过。这篇博文我就围绕JavaWeb这条学习线把HTTP协议拆开揉碎讲清楚。不扯那些五分钟就能搜到的概念定义重点放在“这玩意儿在JavaWeb项目里到底怎么用、报错时怎么排查”。不管你是刚学完JavaSE准备入门Web的新手还是写了一阵子代码但基础不牢想回头补课的同学这篇都能帮你把Servlet容器、请求响应、状态码、乱码排查这些零散知识点串成一条线。1. 先搞清楚HTTP协议在JavaWeb里扮演什么角色1.1 浏览器和服务器是怎么“对上话”的想象一下这个场景你在浏览器地址栏输入一个地址按下回车几毫秒之后页面出来了。这个过程中浏览器和服务器说的话就是HTTP协议。HTTP的全称是HyperText Transfer Protocol超文本传输协议。听起来很学术但你完全可以把它理解成一份“双方约定好的对话格式”。就像中国人见面问“吃了吗”美国人见面说“How are you”如果两边各说各的交流就断了。浏览器和服务器也是一样它们来自不同的厂商、用不同的语言写成凭什么能沟通就凭大家都遵守HTTP这套“说话规则”。在JavaWeb里这个“说话规则”的落地场景非常具体。你的Servlet、JSP、SpringMVC Controller最终运行在Tomcat这样的Servlet容器里。当用户在浏览器里点了按钮浏览器会按照HTTP协议把请求包装成特定格式发出去Tomcat收到后负责解析这份“格式”转成Java对象也就是HttpServletRequest你的Java代码才能用request.getParameter()这种顺手的方法拿到数据。等你的代码处理完Tomcat又把结果包装成HTTP响应格式发回去浏览器再按照协议解析、渲染成页面。所以HTTP协议是JavaWeb一切功能的地基。Servlet、JSP、SpringMVC都是在这套协议之上封装的工具。地基没打牢后面盖多少层楼都晃。1.2 请求-响应模型一次HTTP通信只做一件事HTTP协议的核心模型特别简单就四个字请求-响应Request-Response。客户端通常是浏览器发一个请求服务器返回一个响应然后这次对话就结束了。不会像打电话一样你一句我一句持续聊更像是发快递你寄一个包裹请求驿站给你一个回执响应然后这个事就翻篇了。这个特性带来一个特别重要的推论HTTP是无状态的。所谓“无状态”就是服务器默认不记得你是谁。你上一次请求带了什么参数、登录过没有服务器一概不记得。每一次请求都是全新的、独立的。这就产生了一个经典问题用户登录之后下次访问怎么知道“还是这个人”所以后来才在HTTP之上补充了Cookie和Session这套机制——服务器在响应里通过Set-Cookie头给浏览器发一个“身份牌”浏览器下次请求时自动把牌带上Cookie头服务器一看牌就知道是谁了。但注意这份“记忆”是应用层的解决方案HTTP协议本身依然是无状态的。在JavaWeb里理解这点特别重要。你写Servlet时每次请求都会走一遍service方法request和response对象都是新创建的成员变量默认也不该用来跨请求存数据——因为HTTP根本不保证两次请求之间有关系。这也是为什么很多新手写的Servlet一高并发就出诡异的并发问题根子就在没理解“无状态”这三个字。1.3 一次HTTP请求的完整旅程把整个流程走一遍你就明白HTTP协议具体在哪个环节发挥作用了。假设你在浏览器地址栏输入了一个地址第一步域名解析。浏览器先要把你输入的域名解析成IP地址它问DNS服务器“这个域名对应的服务器IP是多少”拿到IP后才知道该把请求发到哪里。第二步建立TCP连接。HTTP协议本身不负责数据传输它跑在TCP之上。浏览器要和服务器先建立TCP连接这个过程就是常说的“三次握手”。你可以理解成对暗号浏览器说“在吗”服务器说“在”浏览器说“收到开始说话”。三次握手确认双方都能收能发之后才开始正式的HTTP通信。第三步发送HTTP请求。浏览器按照HTTP协议规定的格式把请求行、请求头、请求体组装成一段文本通过TCP连接发给服务器。第四步服务器处理并返回响应。Tomcat收到这段文本按照协议格式解析出方法、URL、参数封装成request对象交给你的Java代码。你的代码处理完逻辑Tomcat把结果包装成HTTP响应文本发回给浏览器。第五步浏览器解析渲染。浏览器收到响应文本看到响应头里的Content-Type是text/html就知道这是一份HTML文档于是调用HTML解析器、CSS渲染引擎把页面画出来。整个过程中HTTP协议负责第三和第四步的“包装格式”。搞懂这两步在说什么几乎所有HTTP相关的问题都能找到根因。2. HTTP请求到底长什么样2.1 请求行GET和POST的差别远不止“一个能带参数”一次HTTP请求的报文分三部分请求行、请求头、请求体。请求行是第一行格式是“请求方法空格请求路径空格协议版本”。例如POST /api/login HTTP/1.1这里就藏着第一个高频考点GET和POST的区别。网上答案要么太浅“GET能带参数POST不能”要么太深直接扔RFC文档。我直接说实际开发里最关键的差别。GET通常用来获取数据参数拼接在URL的?后面比如/api/login?usernameadminpassword123。因为参数写在URL里浏览器、服务器、代理服务器都会记录这段URL所以敏感信息千万别放GET参数里。另外URL长度有限制不同服务器限制不同Tomcat默认是8KB左右实际还得看浏览器文件上传这种大数据量想都别想用GET。POST通常用来提交数据参数放在请求体里不会暴露在URL中所以URL长度限制管不着它。文件上传、登录表单、JSON数据交互基本都用POST。但很多教程把GET和POST说得像两个完全不同的物种其实核心区别只在“参数放哪里”。至于谁更快、谁更安全那都是表象。POST传输的数据也不是绝对安全它只是不在URL里裸奔用抓包工具一样能看到明文真要安全得上HTTPS。2.2 请求头浏览器在偷偷汇报情报请求行下面是一堆“键值对”这就是请求头Request Headers。每个头都携带一类信息JavaWeb开发中你最常打交道的有这么几个Host请求要发往哪个域名和端口。一台服务器上可以部署多个站点Tomcat靠它来区分虚拟主机。User-Agent浏览器和操作系统的身份标识。做爬虫反爬、PC端和移动端适配时经常要读它。Content-Type请求体的媒体类型。后面会重点讲POST请求的参数能不能被正确解析很大程度看它。Content-Length请求体的字节长度。服务器靠它知道“请求体到这里就结束了”。Cookie浏览器自动带上之前存的身份牌。Session能认出你全靠这个头。Referer当前请求是从哪个页面发出来的可以做简单的来源校验。Accept、Accept-Language、Accept-Encoding浏览器声明自己能接收什么类型、什么语言、什么编码格式的内容。服务器可以根据这组头决定返回什么格式的数据、要不要压缩。在JavaWeb里你可以在Servlet中通过request.getHeader(User-Agent)这种方式拿到任意请求头的值做设备判断、来源校验、日志记录等。理解请求头的意义比死记每个头的定义有用得多。2.3 请求体POST参数的真实藏身处请求头和请求体之间有一个空行隔开空行后面的内容就是请求体Request Body。只有POST、PUT这类方法才会有请求体GET没有。请求体的格式由Content-Type决定这几种最常见的组合建议刻进DNAapplication/x-www-form-urlencoded这是HTML表单默认的提交格式。参数以usernameadminpassword123这样的键值对形式放进请求体并且做了URL编码中文、特殊符号会被转成%开头的形式。你直接用request.getParameter(username)能拿到的就是这种格式。multipart/form-data文件上传时必须用这个格式。请求体会被分成多个部分每部分携带一个表单项或文件还带了自己的Content-Type。所以文件上传的Servlet要另写解析逻辑不能直接用getParameter框架比如SpringMVC的MultipartFile底层就是在处理这种格式。application/json现在前后端分离项目最常用的格式AJAX发JSON数据时就是它。请求体是JSON文本request.getParameter拿不到得手动request.getReader()读流再解析JSON。理解了这层你就明白为什么有时候前端传了参数代码却取不到——十有八九是Content-Type和后端解析方式不匹配。2.4 实操用浏览器开发者工具抓一次请求说再多不如上手看一次真实的HTTP请求长什么样。我建议你现在就按F12打开开发者工具切到Network网络标签页随便访问一个页面点进任意一条请求记录查看Headers信息。你会看到完整的Request Headers和Query String ParametersGET请求的参数、Form Data表单POST请求的参数、Request PayloadJSON请求体。还能看到Response Headers和Response Body。这套操作是排查Web问题的基础技能比会背十个协议头都有用。刚开始看HTTP报文可能会觉得头大觉得头太多了。别怕大部分头平时根本用不到你只需要关注Content-Type、Cookie、User-Agent、Location、Set-Cookie这几个高频头其他遇到再查。3. HTTP响应怎么理解状态码是重中之重3.1 状态码服务器想对你说的话都浓缩在三位数字里响应报文的结构和请求报文类似状态行、响应头、响应体。状态行长这样HTTP/1.1 200 OK三位数字就是状态码它概括了服务器这次处理的结果。不需要背全部但下面这几个在JavaWeb开发中遇到的是绝对的熟面孔200 OK一切正常。开发时看到这个码就知道请求成功处理了。302 Found 或 307 Temporary Redirect临时重定向。服务器说“你要的资源搬走了去Location头里的新地址找吧”。你调用response.sendRedirect()时Tomcat就是返回这个。304 Not Modified资源没改动浏览器可以用本地缓存。这个码在改完CSS、JS却不生效时经常出现后面排查章节会专门说。400 Bad Request请求格式错误服务器看不懂。常见的场景是前端传来的JSON格式错了或者请求参数编码不合法。401 Unauthorized未认证意思是“你谁啊先登录再说”。常见于要求登录才能访问的资源。403 Forbidden没权限意思是“你知道你是谁但你没资格看”。目录禁止访问、IP被限制都会出这个。404 Not Found资源不存在。路径写错了、Servlet没映射对第一反应找它。405 Method Not Allowed方法不允许意思是“这个URL支持GET但你用POST来了”。Servlet里写了doGet却没写doPost用POST请求就会撞上。500 Internal Server Error服务器内部错误通俗说就是你的Java代码抛异常了。启动时类加载失败、运行时空指针最后都会以这个码呈现给客户端。502 Bad Gateway 和 503 Service Unavailable通常和项目本身没关系是网关或上层服务器Nginx连不上后端Tomcat或者Tomcat过载不可用。3.2 响应头告诉浏览器“这是什么、怎么处理”响应头里也有几组高频“熟客”Content-Type这个头最关键。响应体是HTML、图片、JSON都由它标识。你在Java里写response.setContentType(text/html;charsetUTF-8)本质就是设置这个头的值。浏览器看到是text/html就用HTML解析器渲染看到application/json就当数据用。Content-Length响应体的字节长度浏览器根据它知道响应体何时结束。Location配合302重定向使用值是重定向的目标地址。浏览器看到302并读到这个头就会自动发起第二次请求。Set-Cookie服务器用来给浏览器发“身份牌”的头。你登录成功后调response.addCookie()最终会体现在这里。Cache-Control和Expires控制缓存策略。开发时如果不希望浏览器缓存页面可以设置Cache-Control为no-cache。3.3 JavaWeb里的状态码场景实战拿一个最简单也最经典的场景串一下用户登录。假设你写了一个LoginServlet收到POST请求后校验用户名密码。如果正确你想让用户跳到首页于是调用response.sendRedirect(/index)。这时浏览器收到的响应状态码是302响应头里带着Location: /index。浏览器看到302自动向/index发起第二次GET请求你的IndexServlet响应200和HTML。注意这整个过程中用户看到的是先请求、再跳转但底层其实是两个独立的HTTP事务。如果密码错误你通常用request.getRequestDispatcher(/error.jsp).forward()转发到错误页。转发forward和重定向redirect在HTTP层面的区别就在这里转发是服务器内部“代为处理”只发一次请求、拿一次响应地址栏不会变浏览器压根不知道发生了转发重定向是服务器“指路”浏览器发两次请求。很多新手搞不清这两者的区别我提供一个记忆方法看见response.sendRedirect就想“302”看见request.getRequestDispatcher().forward()就想“服务器内部操作”。前者浏览器地址栏会变后者不会前者request里的属性带不过去后者可以因为还是同一个request对象。3.4 看一个真实响应长什么样假设你写了一个非常简单的ServletWebServlet(/hello) public class HelloServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(text/html;charsetUTF-8); response.getWriter().write(h1Hello HTTP/h1); } }部署到Tomcat后用浏览器访问开发者工具里能看到响应大概是这样的HTTP/1.1 200 Content-Type: text/html;charsetUTF-8 Content-Length: 20 Date: ...浏览器看到Content-Type是text/html就把h1Hello HTTP/h1这串字符当HTML渲染成页面了。如果你把这行改成application/json浏览器就不会渲染而是当成一个JSON字符串展示或下载。一个头决定一种行为这就是响应头的力量。4. 在JavaWeb项目中HTTP协议如何落地成代码4.1 Tomcat到底帮你干了多少活Tomcat这种Servlet容器之所以值钱是因为它把HTTP协议解析这堆脏活全包了。它帮你监听端口默认8080、接收TCP连接、读取HTTP报文、解析请求行和请求头、解析表单参数、把你需要的上下文封装成HttpServletRequest对象。你的代码根本不需要关心报文怎么拆分——你拿到的就是一个现成的request对象。但反过来说当你遇到奇怪问题时也必须能“穿透”这层封装去看底层的HTTP报文。这就是为什么我强烈建议遇到问题先开F12看网络面板因为现象在代码里根因往往在报文里。4.2 request.getParameter()背后发生了什么这个方法是JavaWeb新手第一个接触的方法但真的没几个人想过它背后的事。当你POST一个application/x-www-form-urlencoded格式的表单Tomcat在解析请求报文时已经读完了请求体把usernameadminpassword123这种字符串按拆成键值对再按拆成key和value存进一个内部Map。你调request.getParameter(username)时它只是从这个Map里取key对应的value。所以整个流程是HTTP报文 - Tomcat解析 - Map - getParameter方法。但这里有个大坑Tomcat解析请求体的字符集是什么默认是ISO-8859-1。如果你提交的是中文又没有告诉Tomcat“用UTF-8解析”参数拿到手就是乱码。解决办法就是在读取任何参数之前调用request.setCharacterEncoding(UTF-8)。注意必须是“读取之前”因为Tomcat是按需解析的——第一次调getParameter时就已经把请求体解析完了之后再设置编码就晚了数据已经被用错的字符集解码存进Map了。4.3 GET请求的乱码为什么不归setCharacterEncoding管前面说了setCharacterEncoding管的是请求体而GET请求的参数在URL的QueryString里解析时机和处理方式完全不一样。Tomcat解析URL时的字符集由URIEncoding属性决定。在Tomcat 8及以上版本这个默认值已经改成了UTF-8所以你在新版本Tomcat里一般不会遇到GET中文乱码。但如果你还在用老版本或者中间还有一层Nginx代理转发了请求就可能在URL层面把URL编码解开时用错字符集导致GET中文参数乱码。这种场景下改request.setCharacterEncoding是没用的得改Tomcat的Connector配置或代理层。所以学HTTP协议的意义再次体现你只有清楚参数在哪一层、用什么编码被解析才能有的放矢地解决问题而不是瞎试。4.4 response.setContentType和setCharacterEncoding的关系回应用同样涉及编码问题。你写response.setContentType(text/html;charsetUTF-8)这一行干了两件事设置响应头Content-Type同时告诉response对象“写字符数据时用UTF-8编码”。如果你只写response.setCharacterEncoding(UTF-8)不写Content-Type响应头里默认是text/html但没有charset声明浏览器可能用默认编码很可能不是UTF-8去解码你的页面于是你在代码里设置的编码又白费了。所以最稳妥的写法是带上charset养成习惯凡是通过response输出中文文本先设置response.setContentType(text/html;charsetUTF-8)。4.5 Cookie和Session背后的HTTP机制Cookie和Session是JavaWeb里绕不开的话题它们本质上就是HTTP无状态协议之上搭的“临时记忆”。先看Cookie。服务器通过response.addCookie()把一个Cookie发给浏览器体现在HTTP层面就是响应头里的Set-Cookie。浏览器收到后会存在本地下次发请求时把所有Cookie放到请求头里一起发出去。Cookie直接放在HTTP报文里是明文的所以千万别把密码、手机号这种敏感信息放进Cookie。再看Session。Session数据存在服务器端Servlet容器为每个会话生成一个唯一的JSESSIONID。Tomcat怎么知道请求属于哪个会话靠Cookie。它默认通过Set-Cookie: JSESSIONIDxxxx发给浏览器浏览器下次带上Cookie: JSESSIONIDxxxxTomcat一看就能从内存里找到对应的HttpSession对象。理解了这层以后遇到“Session失效”“换浏览器就丢失登录状态”的问题就能顺着HTTP头排查是不是Cookie被禁用了是不是Cookie的Domain/Path设置不对导致没发出来很多面试题里那些答题套路都是从这个底层机制推出来的。5. 实际开发中HTTP相关的高频坑与排查手册5.1 POST请求中文乱码的完整解决方案这是JavaWeb第一坑没有之一。症状表现是前端表单提交中文后台拿到的是ä½ å¥½这种乱码。排查思路按顺序走一是确认前端页面本身是UTF-8编码并且表单页面通过meta charsetUTF-8或请求头正确声明了编码。如果页面本身就是GBK浏览器提交时会按GBK编码你后端再UTF-8也解不对。二是确认后端拿到参数前已经执行了request.setCharacterEncoding(UTF-8)。这个方法必须放在request.getParameter()第一次调用之前。如果你用了Filter统一设置编码要确认Filter的执行顺序在最前面。三是确认Tomcat版本和新旧配置。Tomcat 8以上的URIEncoding默认UTF-8GET一般没问题老的Tomcat 7及以下需要手动在server.xml的Connector上加URIEncodingUTF-8。第四如果你是把中文放到URL上比如/search?keyword中文记得前端先做一次encodeURIComponent编码后端拿到的是URL编码后的字符串需要URLDecoder.decode再解一次。很多开发者会被这个双编码搞晕最直观的排查办法就是抓包看报文里中文变成了什么。5.2 404说明路由根本没找到出现404时先别慌着改代码按这个顺序查地址栏URL拼写对不对大小写、斜杠这些最容易错。WebServlet(/xxx)注解里的路径和访问路径一致吗注意注解里路径要以/开头。用了web.xml的话url-pattern里的写法对不对Servlet的url-pattern是要精确匹配还是要用/*通配项目有没有正常部署看Tomcat控制台启动日志有没有“Deploying web application”和“Completed”的字样。类加载报错的话项目可能处于未完全部署状态。是不是把HTML/JSP/Servlet放在了WEB-INF目录下WEB-INF下的资源是禁止浏览器直接访问的只能通过服务器内部转发。5.3 405说明方法不匹配405的全称是“Method Not Allowed”。典型场景是你写了一个Servlet继承HttpServlet但只重写了doGet没重写doPost。当前端用POST请求访问时Tomcat发现父类的doPost方法直接抛出了405错误——HttpServlet的默认行为就是这样。解决思路很直接要么在子类里补上doPost方法要么把处理逻辑统一放service方法里要么让doPost直接调用doGetprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }当你收到405基本就是这种“方法没实现”的毛病。值得注意的是SpringMVC的Controller方法用RequestMapping时method属性指定了只接受POST拿GET去访问也会出现405。5.4 500说明代码抛异常了500是“服务器内部错误”几乎所有运行时异常最终都表现为500。排查重点就一句话去Tomcat日志里找异常堆栈。Tomcat的日志默认输出在logs目录下的catalina.out或localhost.xxx.log里。你登录后输入url触发500然后去日志里翻最后面的异常找到Exception开始的段落定位Caused by那一行——这才是真正的根因。常见的有NullPointerException某个对象没初始化就被调方法了。ClassNotFoundException依赖的jar包没打进去。ServletException初始化阶段出错比如web.xml里配置了不存在的类。数据库连接错误JDBC驱动没加载、连接池没配置。500唯一的排查路径就是日志。不看日志瞎改代码属于典型的无效努力。5.5 页面改了却不生效多半是304缓存改完CSS或JS刷新页面发现还是旧的。F12看Network发现静态资源请求返回304 Not Modified这就是浏览器在吃缓存。浏览器判断本地缓存的依据是响应头里的Last-Modified或ETag。开发阶段最简单的做法是打开开发者工具勾选Network面板里的Disable cache这样每次刷新都会带Cache-Control: no-cache的请求头不会命中304。另一个土办法是在引用CSS/JS时加上版本号参数style.css?v20250101改了版本号浏览器就会当成新的URL请求绕过缓存。5.6 HTTP排查速查表现象可能原因首选排查思路前端传来的参数后台取不到Content-Type不匹配或参数格式不对抓包看请求体和Content-TypePOST中文乱码前端页面编码不对或后端没设置编码确认页面编码确认setCharacterEncoding在读取前执行GET中文乱码Tomcat URIEncoding配置问题检查Tomcat版本和Connector配置404路径映射错误检查URL、注解、web.xml部署状态405方法未重写检查doGet/doPost是否齐全500运行时异常看Tomcat日志异常堆栈页面不更新浏览器304缓存F12禁用缓存或加版本参数登录状态丢失Cookie被禁用或JSESSIONID未携带抓包看Cookie请求头5.7 代码层面的排查示例在实际开发中我建议你写一个全局的Filter来打印请求的基本信息这对开发调试帮助极大WebFilter(/*) public class LogFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req; System.out.println([ request.getMethod() ] request.getRequestURI()); System.out.println(Content-Type: request.getContentType()); EnumerationString names request.getHeaderNames(); while (names.hasMoreElements()) { String name names.nextElement(); System.out.println(name : request.getHeader(name)); } chain.doFilter(req, resp); } }每次请求进来控制台都会打印完整的请求行和请求头你能直观地看到浏览器到底发了什么。做项目调试时这个Filter比断点调试更直观因为它是HTTP层面的第一现场。6. 从HTTP协议出发的JavaWeb进阶路线6.1 下一站系统学习如何“看报文”我的建议是先玩熟抓包工具。浏览器自带的开发者工具适合看请求头、参数、响应体90%的日常工作用它就够。需要更精细地看TCP层面的内容、改请求再重放可以试试Postman、Apifox这类接口调试工具。它们的好处是能自由构造各种HTTP请求POST、PUT、DELETE自定义请求头模拟不同Content-Type你可以在几分钟内构造出各种“奇怪”的请求观察服务器的反应。当年我带新人的时候有个特别好的练手方式拿Postman反复调自己写的Servlet先发正常请求再故意改错请求头、传错格式看报错变化。几次下来对HTTP协议的理解比看十篇教程都深。6.2 进阶必须掌握的HTTP特性顺着HTTP这条线有几个进阶知识点值得花时间啃连接复用Keep-Alive。HTTP/1.1默认开启了持久连接就是说浏览器和服务器之间建立一次TCP连接后可以连续发送多个请求。这也是现代网页能同时加载那么多资源的原因之一。请求流水线和多路复用。HTTP/1.1虽然能复用连接但同一时刻一个连接上只能有一个请求在“进行中”排队是难免的。HTTP/2引入了多路复用把多个请求交错地放在一个连接上传输效率提升非常明显。HTTPS。HTTPS就是在HTTP和TCP之间加了一层TLS/SSL加密。爬过这个坑的人都知道到了HTTPS的排查场景第一眼要分清是证书问题、加密套件问题还是应用层问题。缓存策略和条件请求。除了前面说的304还有ETag、Last-Modified、Cache-Control的组合。前后端分离项目里静态资源缓存策略、接口请求缓存策略都是简历上能写一笔的实战经验。6.3 JavaWeb层面的学习顺序建议HTTP协议理解到位了JavaWeb的学习就有了主心骨。按这个顺序往下走比较顺第一Servlet核心知识和请求响应模型。这时候你已经知道request和response就是HTTP报文的Java封装学起来会感觉处处都通。第二Filter和Listener。Filter本质就是在请求到达Servlet之前和响应离开Servlet之后插入处理逻辑编码过滤器、登录拦截器都是这么做的。第三JSP。JSP本质上还是Servlet模板渲染本质就是服务器端把动态数据填充成HTML文本再通过response返回。第四MVC分层思想。Controller收请求、Service处理业务、DAO访问数据库各层分工数据流转路径清晰。第五前后端分离和AJAX。这时候你发的请求不再导致整个页面刷新而是通过JS异步发HTTP请求拿到JSON数据再操作DOM。前端用fetch、axios发出的还是HTTP请求只是响应体变成了JSON。第六现成框架。SpringMVC的DispatcherServlet核心思想还是前端控制器模式拦截所有请求再做分发。你有了Servlet和HTTP的底子再学SpringMVC会非常快。我见过太多人一上来就学SpringBoot接口也能写能调但问他“POST请求乱码了去哪改配置”“403和401有什么区别”一个字答不上来。这不是他的问题是地基缺课了。JavaWeb这条路上HTTP协议就是第一层地基。把这层学扎实后面任何框架都只是换壳的玩具。等你再遇到奇奇怪怪的线上问题记住一个原则先抓包看报文再谈代码。这个习惯能让你少走一年弯路。
返回列表