[{"data":1,"prerenderedAt":3884},["ShallowReactive",2],{"post:\u002Fposts\u002F2021\u002Ftomcat-servlet":3,"posts:catalog":3613},{"id":4,"title":5,"aiSummary":6,"audio":7,"body":8,"categories":3595,"cover":3597,"description":3598,"extension":3599,"meta":3600,"navigation":6,"path":3601,"pin":3602,"publish":3603,"seo":3604,"series":7,"seriesOrder":7,"stem":3605,"summary":7,"summarySource":3606,"tags":3607,"theme":3609,"update":7,"wip":3610,"wordCount":3611,"__hash__":3612},"posts\u002Fposts\u002F2021\u002Ftomcat-servlet.md","Tomcat和Servlet应用配置及部分问题",true,null,{"type":9,"value":10,"toc":3514},"minimark",[11,15,20,25,31,35,40,63,66,69,72,77,80,83,86,93,96,102,105,115,118,167,170,174,287,291,330,334,417,421,425,428,439,443,446,457,462,466,486,490,493,520,523,529,533,536,546,549,788,792,795,888,891,894,897,900,914,920,924,927,931,933,1149,1152,1161,1165,1170,1173,1196,1199,1202,1205,1261,1264,1267,1335,1338,1341,1383,1387,1390,1393,1396,1399,1402,1405,1409,1463,1466,1772,1775,1778,1805,1808,1930,1933,1936,1939,1961,1966,1969,2013,2018,2021,2024,2027,2062,2065,2073,2076,2079,2158,2162,2165,2168,2171,2228,2286,2289,2294,2297,2300,2303,2377,2380,2383,2409,2412,2455,2459,2462,2466,2524,2528,2531,2681,2685,2688,2691,2711,2741,2745,2762,2766,2769,2773,2776,2779,2936,2940,2943,2947,2950,2952,3052,3057,3061,3064,3067,3132,3136,3140,3143,3146,3154,3251,3253,3355,3359,3362,3464,3468,3487,3491,3494,3510],[12,13,14],"p",{},"持续更新中……",[16,17,19],"h1",{"id":18},"tomcat","Tomcat",[21,22,24],"h3",{"id":23},"维基百科复制来的长篇大论","维基百科复制来的长篇大论：",[26,27,28],"blockquote",{},[12,29,30],{},"Tomcat是由Apache软件基金会属下Jakarta项目开发的Servlet容器，按照Sun Microsystems提供的技术规范，实现了对Servlet和JavaServer Page（JSP）的支持，并提供了作为Web服务器的一些特有功能，如Tomcat管理和控制平台、安全局管理和Tomcat阀等。由于Tomcat本身也内含了HTTP服务器，因此也可以视作单独的Web服务器。但是，不能将Tomcat和Apache HTTP服务器混淆，Apache HTTP服务器是用C语言实现的HTTPWeb服务器；这两个HTTP web server不是捆绑在一起的。Apache Tomcat包含了配置管理工具，也可以通过编辑XML格式的配置文件来进行配置。",[32,33,34],"h2",{"id":34},"使用",[26,36,37],{},[12,38,39],{},"Idea的下载安装及配置不再赘述。",[26,41,42],{},[12,43,44,45,52,53,52,58],{},"Tomcat10.0.4下载地址：",[46,47,51],"a",{"href":48,"rel":49},"https:\u002F\u002Fmirror-hk.koddos.net\u002Fapache\u002FTomcat\u002FTomcat-10\u002Fv10.0.4\u002Fbin\u002Fapache-Tomcat-10.0.4-windows-x64.zip",[50],"nofollow","64位win.zip","、",[46,54,57],{"href":55,"rel":56},"https:\u002F\u002Fmirror-hk.koddos.net\u002Fapache\u002FTomcat\u002FTomcat-10\u002Fv10.0.4\u002Fbin\u002Fapache-Tomcat-10.0.4-windows-x86.zip",[50],"32位win.zip",[46,59,62],{"href":60,"rel":61},"https:\u002F\u002FTomcat.apache.org\u002Fdownload-10.cgi",[50],"其他(官网)",[21,64,65],{"id":65},"安装",[12,67,68],{},"下载的压缩包需要解压到纯英文目录，安装包同理安装在纯英文目录下。",[21,70,71],{"id":71},"环境变量",[26,73,74],{},[12,75,76],{},"如果没有配置过jdk和jre的目录，需要首先下载和配置jdk！！",[12,78,79],{},"双击Tomcat\u002Fbin目录下setclasspath.bat，会有cmd窗口一闪而过。",[21,81,82],{"id":82},"启动",[12,84,85],{},"双击Tomcat\u002Fbin目录下startup.bat，cmd窗口中出现以下文字则服务器开启成功：",[12,87,88],{},[89,90],"img",{"alt":91,"src":92},"image-20210322183754160","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-1.png",[12,94,95],{},"此时在浏览器中输入localhost:8000即可开启Tomcat的demo页面：",[12,97,98],{},[89,99],{"alt":100,"src":101},"image-20210322183711196","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-2.png",[21,103,104],{"id":104},"关闭",[106,107,108,112],"ul",{},[109,110,111],"li",{},"强行关闭，直接点x",[109,113,114],{},"双击打开bin目录下shutdown.bat",[32,116,117],{"id":117},"问题分析",[119,120,121,145],"ol",{},[109,122,123,124],{},"控制台都是乱码看不懂",[106,125,126,136],{},[109,127,128,129,132],{},"首先说明这是编码问题，在Tomcat\\conf目录下找到logging.properties",[130,131],"br",{},[89,133],{"alt":134,"src":135},"image-20210322183413959","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-3.png",[109,137,138,139,141],{},"更改UTF-8为GBK",[130,140],{},[89,142],{"alt":143,"src":144},"image-20210322183357065","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-4.png",[109,146,147,148,150,151],{},"打开Tomcat闪退",[130,149],{},"有两种情况：",[119,152,153,156],{},[109,154,155],{},"环境变量没设置好，打开cmd输入java -version即可查看有无设置好jdk的环境变量，其次可能Tomcat的环境变量没设置好，试试以管理员身份打开setclasspath.bat。",[109,157,158,159],{},"端口占用\n",[106,160,161,164],{},[109,162,163],{},"打开cmd输入netstat -aon|findstr \"端口号\" ，检测端口占用情况（可跳过",[109,165,166],{},"找到Tomcat\\conf\\server.xml，用文本编辑器打开，ctrl+f找到8080，改成其他端口，1~1023为系统端口不要设，改为1024~65535即可。",[32,168,169],{"id":169},"部署项目",[21,171,173],{"id":172},"部署项目的方式","部署项目的方式：",[119,175,176,196,259],{},[109,177,178,179],{},"直接将项目放到webapps目录下即可。",[106,180,181,184],{},[109,182,183],{},"\u002Fhello：项目的访问路径–>虚拟目录",[109,185,186,187],{},"简化部署：将项目打城一个war包，再将war包放置到webapps目录下。\n",[106,188,189],{},[109,190,191],{},[26,192,193],{},[12,194,195],{},"war包会自动解压缩",[109,197,198,199,201,202,251],{},"配置conf\u002Fserver.xml文件",[130,200],{},"在\u003CHost>标签体中配置",[203,204,209],"pre",{"className":205,"code":206,"language":207,"meta":208,"style":208},"language-xml shiki shiki-themes catppuccin-mocha catppuccin-latte","\u003CContext docBase=\"D:\\hello\" path=\"\u002Fhehe\" \u002F>d\n","xml","",[210,211,212],"code",{"__ignoreMap":208},[213,214,217,221,225,229,233,237,240,242,245,248],"span",{"class":215,"line":216},"line",1,[213,218,220],{"class":219},"siJSA","\u003C",[213,222,224],{"class":223},"sZBvu","Context",[213,226,228],{"class":227},"sIs8M"," docBase",[213,230,232],{"class":231},"szT_X","=",[213,234,236],{"class":235},"ssZzq","\"D:\\hello\"",[213,238,239],{"class":227}," path",[213,241,232],{"class":231},[213,243,244],{"class":235},"\"\u002Fhehe\"",[213,246,247],{"class":219}," \u002F>",[213,249,250],{"class":231},"d\n",[106,252,253,256],{},[109,254,255],{},"docBase:项目存放的路径",[109,257,258],{},"path:虚拟目录",[109,260,261,262,282],{},"在conf\\Catalina\\localhost创建任意名称的xml文件.在文件中编写",[203,263,265],{"className":205,"code":264,"language":207,"meta":208,"style":208},"\u003CContext docBase=\"D:\\hello\" \u002F>\n",[210,266,267],{"__ignoreMap":208},[213,268,269,271,273,275,277,279],{"class":215,"line":216},[213,270,220],{"class":219},[213,272,224],{"class":223},[213,274,228],{"class":227},[213,276,232],{"class":231},[213,278,236],{"class":235},[213,280,281],{"class":219}," \u002F>\n",[106,283,284],{},[109,285,286],{},"虚拟目录:xml文件的名称",[21,288,290],{"id":289},"动态项目和静态项目","动态项目和静态项目:",[106,292,293],{},[109,294,295,296],{},"目录结构:\n",[106,297,298,306],{},[109,299,300,301],{},"静态项目:\n",[106,302,303],{},[109,304,305],{},"使用静态资源",[109,307,308,309],{},"java动态项目的目录结构:\n",[106,310,311],{},[109,312,313,314],{},"项目根目录\n",[106,315,316],{},[109,317,318,319],{},"WEB-INF\n",[106,320,321,324,327],{},[109,322,323],{},"web.xml:该项目的核心配置文件",[109,325,326],{},"classes目录: 放置字节码文件",[109,328,329],{},"lib目录: 防止项目依赖的jar包",[21,331,333],{"id":332},"tomcat集成到idea中","Tomcat集成到IDEA中",[119,335,336,345,354,357,366,378,399],{},[109,337,338,339,341],{},"点击Run->Edit Configurations或Add Configurations",[130,340],{},[89,342],{"alt":343,"src":344},"image-20210322191002812","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-5.png",[109,346,347,348,350],{},"点击Configure…",[130,349],{},[89,351],{"alt":352,"src":353},"image-20210322191129266","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-6.png",[109,355,356],{},"选择Tomcat根目录",[109,358,359,360,362],{},"上面有",[130,361],{},[89,363],{"alt":364,"src":365},"image-20210322191422916","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-7.png",[109,367,368,369,371,375,377],{},"你可能需要点击",[130,370],{},[89,372],{"alt":373,"src":374},"image-20210322191526306","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-8.png",[130,376],{},"没有就不点",[109,379,380,381,383,387,388,392,396,398],{},"新建一个Module",[130,382],{},[89,384],{"alt":385,"src":386},"image-20210322192109197","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-9.png","\nctrl+shift+alt+\u002F打开Maintenance，打开Registry，找到",[389,390,391],"strong",{},"javaee.legacy.project.wizard",[89,393],{"alt":394,"src":395},"image-20210322193149809","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-10.png",[130,397],{},"勾选后即可在新建Module中找到JavaEE的Web Application选项",[109,400,401,402,404,408,410,411,413],{},"在index.jsp中编写html代码(也可跳过),运行就可以了",[130,403],{},[89,405],{"alt":406,"src":407},"image-20210322194041872","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-11.png",[130,409],{},"打开浏览器，成功运行项目：",[130,412],{},[89,414],{"alt":415,"src":416},"image-20210322194128864","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-12.png",[16,418,420],{"id":419},"servlet","Servlet",[32,422,424],{"id":423},"简介","简介：",[21,426,24],{"id":427},"维基百科复制来的长篇大论-1",[26,429,430,433,436],{},[12,431,432],{},"Servlet（Server Applet），全称Java Servlet。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据，生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口，广义的Servlet是指任何实现了这个Servlet接口的类，一般情况下，人们将Servlet理解为后者。",[12,434,435],{},"Servlet运行于支持Java的应用服务器中。从实现上讲，Servlet可以响应任何类型的请求，但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。",[12,437,438],{},"最早支持Servlet标准的是JavaSoft的Java Web Server。此后，一些其它的基于Java的Web服务器开始支持标准的Servlet。",[21,440,442],{"id":441},"概述","概述：",[12,444,445],{},"Servlet(server applet)为运行在服务器端的小程序。",[106,447,448,451,454],{},[109,449,450],{},"Servlet本质上也是Java类，但要遵循Servlet规范进行编写，没有main()方法，它的创建、使用、销毁都由Servlet容器管理（如Tomcat）。",[109,452,453],{},"Servlet是和HTTP协议紧密联系的，其可以处理HTTP协议相关的所有内容。这也是Servlet应用广泛的原因之一。",[109,455,456],{},"Servlet容器有很多，如Tomcat，Jetty，WebLogic Server，web Sphere，JBoss等等。",[458,459,461],"h4",{"id":460},"继承httpservlet","继承HttpServlet",[21,463,465],{"id":464},"servlet的工作流程","Servlet的工作流程",[119,467,468,471,474,477,480,483],{},[109,469,470],{},"通过请求头获知浏览器访问的是哪个主机",[109,472,473],{},"再通过请求行获取访问的是哪个一个web应用",[109,475,476],{},"再通过请求行中的请求路径获知访问的是哪个资源",[109,478,479],{},"通过获取的资源路径在配置中匹配到真实的路径，",[109,481,482],{},"服务器会创建servlet对象，（如果是第一次访问时，创建servlet实例，并调用init方法进行初始化操作）",[109,484,485],{},"调用service（request， response）方法来处理请求和响应的操作 7. 调用service完毕后返回服务器 由服务器讲response缓冲区的数据取出，以http响应的格式发送给浏览器",[32,487,489],{"id":488},"servlet的实现","Servlet的实现",[21,491,492],{"id":492},"创建web项目",[119,494,495,502,511],{},[109,496,497,498],{},"new project\n",[89,499],{"alt":500,"src":501},"image-20210324165256255","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-13.png",[109,503,504,505,507],{},"继续next",[130,506],{},[89,508],{"alt":509,"src":510},"image-20210324165447210","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-14.png",[109,512,513,514,516],{},"改个项目名字",[130,515],{},[89,517],{"alt":518,"src":519},"image-20210324165529088","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-15.png",[12,521,522],{},"最终得到的项目结构如下：",[12,524,525],{},[89,526],{"alt":527,"src":528},"image-20210324165642311","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-16.png",[21,530,532],{"id":531},"实现servlet","实现Servlet",[12,534,535],{},"实现Servlet规范，即继承HttpServlet类，该类中已经完成了通信的规则，我们只需要进行业务的实现即可。",[26,537,538],{},[12,539,540,541],{},"警告：请下载对应版本的tomcat，不然会导致404错误无法启动servlet项目。点击直达—>",[46,542,545],{"href":543,"rel":544},"https:\u002F\u002Ftomcat.apache.org\u002Fwhichversion.html",[50],"官方版本说明",[21,547,548],{"id":548},"版本表格",[550,551,552,583],"table",{},[553,554,555],"thead",{},[556,557,558,562,565,568,571,574,577,580],"tr",{},[559,560,561],"th",{},"Servlet Spec",[559,563,564],{},"JSP Spec",[559,566,567],{},"EL Spec",[559,569,570],{},"WebSocket Spec",[559,572,573],{},"JASPIC Spec",[559,575,576],{},"Apache Tomcat version",[559,578,579],{},"Actual release revision",[559,581,582],{},"Supported Java Versions",[584,585,586,613,637,658,680,699,722,745,767],"tbody",{},[556,587,588,592,595,598,601,604,607,610],{},[589,590,591],"td",{},"4.0",[589,593,594],{},"TBD (2.4?)",[589,596,597],{},"TBD (3.1?)",[589,599,600],{},"TBD (1.2?)",[589,602,603],{},"1.1",[589,605,606],{},"9.0.x",[589,608,609],{},"9.0.0.M9 (alpha)",[589,611,612],{},"8 and later",[556,614,615,618,621,624,626,628,631,634],{},[589,616,617],{},"3.1",[589,619,620],{},"2.3",[589,622,623],{},"3.0",[589,625,603],{},[589,627,603],{},[589,629,630],{},"8.5.x",[589,632,633],{},"8.5.4",[589,635,636],{},"7 and later",[556,638,639,641,643,645,647,650,653,656],{},[589,640,617],{},[589,642,620],{},[589,644,623],{},[589,646,603],{},[589,648,649],{},"N\u002FA",[589,651,652],{},"8.0.x (superseded)",[589,654,655],{},"8.0.35 (superseded)",[589,657,636],{},[556,659,660,662,665,667,669,671,674,677],{},[589,661,623],{},[589,663,664],{},"2.2",[589,666,664],{},[589,668,603],{},[589,670,649],{},[589,672,673],{},"7.0.x",[589,675,676],{},"7.0.70",[589,678,679],{},"6 and later",[556,681,682,685,687,689,691,693,695,697],{},[589,683,684],{},"(7 and later for WebSocket)",[589,686],{},[589,688],{},[589,690],{},[589,692],{},[589,694],{},[589,696],{},[589,698],{},[556,700,701,704,707,709,711,713,716,719],{},[589,702,703],{},"2.5",[589,705,706],{},"2.1",[589,708,706],{},[589,710,649],{},[589,712,649],{},[589,714,715],{},"6.0.x",[589,717,718],{},"6.0.45",[589,720,721],{},"5 and later",[556,723,724,727,730,732,734,736,739,742],{},[589,725,726],{},"2.4",[589,728,729],{},"2.0",[589,731,649],{},[589,733,649],{},[589,735,649],{},[589,737,738],{},"5.5.x (archived)",[589,740,741],{},"5.5.36 (archived)",[589,743,744],{},"1.4 and later",[556,746,747,749,752,754,756,758,761,764],{},[589,748,620],{},[589,750,751],{},"1.2",[589,753,649],{},[589,755,649],{},[589,757,649],{},[589,759,760],{},"4.1.x (archived)",[589,762,763],{},"4.1.40 (archived)",[589,765,766],{},"1.3 and later",[556,768,769,771,773,775,777,779,782,785],{},[589,770,664],{},[589,772,603],{},[589,774,649],{},[589,776,649],{},[589,778,649],{},[589,780,781],{},"3.3.x (archived)",[589,783,784],{},"3.3.2 (archived)",[589,786,787],{},"1.1 and later",[21,789,791],{"id":790},"重写servlet方法","重写Servlet方法",[12,793,794],{},"满足Servlet规范只是让我们的类能够满足接受请求的要求，接收到请求后需要对请求进行分析，以及进行业务逻辑处理，计算出结果，则需要添加代码，在规范中有一个叫做service的方法，专门用来做请求处理的操作，业务代码则可以卸载该方法中。",[119,796,797,806,877],{},[109,798,799,800,802],{},"新建一个类",[130,801],{},[89,803],{"alt":804,"src":805},"image-20210324172642919","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-17.png",[109,807,461,808],{},[203,809,813],{"className":810,"code":811,"language":812,"meta":208,"style":208},"language-java shiki shiki-themes catppuccin-mocha catppuccin-latte","import javax.servlet.http.HttpServlet;\n\npublic class ServletDemo1 extends HttpServlet {\n}\n\n","java",[210,814,815,843,849,871],{"__ignoreMap":208},[213,816,817,821,824,828,830,832,835,837,840],{"class":215,"line":216},[213,818,820],{"class":819},"sDkzg","import",[213,822,823],{"class":231}," javax",[213,825,827],{"class":826},"sxk1D",".",[213,829,419],{"class":231},[213,831,827],{"class":826},[213,833,834],{"class":231},"http",[213,836,827],{"class":826},[213,838,839],{"class":231},"HttpServlet",[213,841,842],{"class":826},";\n",[213,844,846],{"class":215,"line":845},2,[213,847,848],{"emptyLinePlaceholder":6},"\n",[213,850,852,855,858,862,865,868],{"class":215,"line":851},3,[213,853,854],{"class":819},"public",[213,856,857],{"class":819}," class",[213,859,861],{"class":860},"szFfR"," ServletDemo1",[213,863,864],{"class":819}," extends",[213,866,867],{"class":860}," HttpServlet",[213,869,870],{"class":826}," {\n",[213,872,874],{"class":215,"line":873},4,[213,875,876],{"class":826},"}\n",[109,878,879,880],{},"重写service方法",[203,881,886],{"className":882,"code":884,"language":885},[883],"language-text","import javax.servlet.ServletException;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.IOException;\n\npublic class HelloServlet extends HttpServlet {\n    @Override\n    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {\n        System.out.println(\"hello servlet\");\u002F\u002F 打印内容到控制台\n        resp.getWriter().write(\"Hello world!\");\u002F\u002F 通过流输出数据到浏览器\n    }\n","text",[210,887,884],{"__ignoreMap":208},[21,889,890],{"id":890},"设置注解",[12,892,893],{},"在完成好了一切代码的编写后，还需要向服务器说明，特定请求对应特定资源。",[12,895,896],{},"开发servlet项目，使用@WebServlet将一个继承于javax.servlet.http.HttpServlet的类顶i为Servlet组件。",[12,898,899],{},"在Servlet3.0中，可以使用@WebServlet注解将一个继承于javax.servlet.http.HttpServlet的类标注为可以处理用户请求的Servlet。",[106,901,902,911],{},[109,903,904,905,907],{},"通过设置注解，指定访问路径",[130,906],{},[89,908],{"alt":909,"src":910},"image-20210324173507993","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-18.png",[109,912,913],{},"启动服务器",[12,915,916],{},[89,917],{"alt":918,"src":919},"image-20210324180345268","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-19.png",[458,921,923],{"id":922},"继承genericservlet","继承GenericServlet",[12,925,926],{},"继承GenericServlet类，其他不变",[458,928,930],{"id":929},"实现接口servlet","实现接口Servlet",[12,932,930],{},[119,934,935,938,947,956,1135],{},[109,936,937],{},"创建一个JavaEE项目",[109,939,940,941,943],{},"定义一个类，实现Servlet接口",[130,942],{},[89,944],{"alt":945,"src":946},"image-20210324083857086","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-20.png",[109,948,949,950,952],{},"实现接口中的抽象方法",[130,951],{},[89,953],{"alt":954,"src":955},"image-20210324083917998","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-21.png",[109,957,958,959],{},"配置Servlet",[106,960,961,1000],{},[109,962,963,964,994,996],{},"在service方法中加上：",[203,965,967],{"className":810,"code":966,"language":812,"meta":208,"style":208},"System.out.println(\"hello servlet\");\n",[210,968,969],{"__ignoreMap":208},[213,970,971,974,976,979,981,985,988,991],{"class":215,"line":216},[213,972,973],{"class":231},"System",[213,975,827],{"class":826},[213,977,978],{"class":231},"out",[213,980,827],{"class":826},[213,982,984],{"class":983},"s3Fsb","println",[213,986,987],{"class":826},"(",[213,989,990],{"class":235},"\"hello servlet\"",[213,992,993],{"class":826},");\n",[130,995],{},[89,997],{"alt":998,"src":999},"image-20210324131053590","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-22.png",[109,1001,1002,1003,1126,1128,1129,1131],{},"在WEB-INF下的web.xml中加入：",[203,1004,1006],{"className":205,"code":1005,"language":207,"meta":208,"style":208},"\u003C!-- 配置Servlet -->\n\u003Cservlet>\n  \u003Cservlet-name>demo\u003C\u002Fservlet-name>\n  \u003Cservlet-class>setobox.me.servlet.ServletDemo1\u003C\u002Fservlet-class>\n\u003C\u002Fservlet>\n\u003Cservlet-mapping>\n  \u003Cservlet-name>demo\u003C\u002Fservlet-name>\n  \u003Curl-pattern>\u002Fdemo\u003C\u002Furl-pattern>\n\u003C\u002Fservlet-mapping>\n",[210,1007,1008,1014,1023,1044,1062,1071,1081,1098,1117],{"__ignoreMap":208},[213,1009,1010],{"class":215,"line":216},[213,1011,1013],{"class":1012},"s0D_2","\u003C!-- 配置Servlet -->\n",[213,1015,1016,1018,1020],{"class":215,"line":845},[213,1017,220],{"class":219},[213,1019,419],{"class":223},[213,1021,1022],{"class":219},">\n",[213,1024,1025,1028,1031,1034,1037,1040,1042],{"class":215,"line":851},[213,1026,1027],{"class":219},"  \u003C",[213,1029,1030],{"class":223},"servlet-name",[213,1032,1033],{"class":219},">",[213,1035,1036],{"class":231},"demo",[213,1038,1039],{"class":219},"\u003C\u002F",[213,1041,1030],{"class":223},[213,1043,1022],{"class":219},[213,1045,1046,1048,1051,1053,1056,1058,1060],{"class":215,"line":873},[213,1047,1027],{"class":219},[213,1049,1050],{"class":223},"servlet-class",[213,1052,1033],{"class":219},[213,1054,1055],{"class":231},"setobox.me.servlet.ServletDemo1",[213,1057,1039],{"class":219},[213,1059,1050],{"class":223},[213,1061,1022],{"class":219},[213,1063,1065,1067,1069],{"class":215,"line":1064},5,[213,1066,1039],{"class":219},[213,1068,419],{"class":223},[213,1070,1022],{"class":219},[213,1072,1074,1076,1079],{"class":215,"line":1073},6,[213,1075,220],{"class":219},[213,1077,1078],{"class":223},"servlet-mapping",[213,1080,1022],{"class":219},[213,1082,1084,1086,1088,1090,1092,1094,1096],{"class":215,"line":1083},7,[213,1085,1027],{"class":219},[213,1087,1030],{"class":223},[213,1089,1033],{"class":219},[213,1091,1036],{"class":231},[213,1093,1039],{"class":219},[213,1095,1030],{"class":223},[213,1097,1022],{"class":219},[213,1099,1101,1103,1106,1108,1111,1113,1115],{"class":215,"line":1100},8,[213,1102,1027],{"class":219},[213,1104,1105],{"class":223},"url-pattern",[213,1107,1033],{"class":219},[213,1109,1110],{"class":231},"\u002Fdemo",[213,1112,1039],{"class":219},[213,1114,1105],{"class":223},[213,1116,1022],{"class":219},[213,1118,1120,1122,1124],{"class":215,"line":1119},9,[213,1121,1039],{"class":219},[213,1123,1078],{"class":223},[213,1125,1022],{"class":219},[130,1127],{},"ps: 一定要写在web-app标签中",[130,1130],{},[89,1132],{"alt":1133,"src":1134},"image-20210324130846832","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-23.png",[109,1136,1137,1138],{},"运行项目",[106,1139,1140,1143],{},[109,1141,1142],{},"点击运行，浏览器地址栏中加\u002Fdemo",[109,1144,1145],{},[89,1146],{"alt":1147,"src":1148},"image-20210324180512244","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-24.png",[21,1150,1151],{"id":1151},"其他配置",[106,1153,1154],{},[109,1155,1156,1157],{},"这个地方只保留斜杠可以缩短地址栏",[89,1158],{"alt":1159,"src":1160},"image-20210324181850981","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet-25.png",[32,1162,1164],{"id":1163},"servlet的生命周期","Servlet的生命周期",[26,1166,1167],{},[12,1168,1169],{},"Servlet没有main()方法，不能独立运行，它的运行完全由Servlet引擎来控制和调度。所谓生命周期，指的是servlet容器何时创建servlet实例、何时调用其方法进行请求的处理、何时销毁其实例的整个过程。",[12,1171,1172],{},"Servlet的生命周期，servlet类加载–>实例化–>服务–>销毁",[106,1174,1175,1181,1187],{},[109,1176,1177,1178,1180],{},"实例和初始化时机",[130,1179],{},"当请求到达容器时，容器查找该servlet对象是否存在，如果不存在，则会创建实例并进行初始化。",[109,1182,1183,1184,1186],{},"就绪\u002F调用\u002F服务阶段",[130,1185],{},"有请求到达容器，容器调用servlet对象的service()方法，处理请求的方法在整个生命周期中可以被多次调用；HttpServlet的service()方法，会依据请求方式来调用doGet()或者doPost()方法。但是，这两个do方法默认情况下，会抛出异常，需要子类去override。",[109,1188,1189,1190,1192,1193,1195],{},"销毁时机",[130,1191],{},"当容器关闭时(应用程序停止时)，会将程序中的Servlet实例进行销毁。",[130,1194],{},"上述的生命周期可以通过Servlet中的生命周期方法来观察。在Servlet中有三个生命周期方法，不由用户手动调用，而是在特定的时机有容器自动调用，观察这三个生命周期方法，即可观察到Servlet的生命周期。",[12,1197,1198],{},"三个方法：",[21,1200,1201],{"id":1201},"init方法",[12,1203,1204],{},"在Servlet实例创建之后执行(证明该Servlet有实例创建了)",[203,1206,1208],{"className":810,"code":1207,"language":812,"meta":208,"style":208},"public void init(ServletConfig config) throws ServletException {\n  System.out.println(\"创建了实例，只会执行一次\");\n}\n",[210,1209,1210,1237,1257],{"__ignoreMap":208},[213,1211,1212,1214,1217,1220,1222,1225,1228,1231,1234],{"class":215,"line":216},[213,1213,854],{"class":819},[213,1215,1216],{"class":819}," void",[213,1218,1219],{"class":983}," init",[213,1221,987],{"class":826},[213,1223,1224],{"class":819},"ServletConfig",[213,1226,1227],{"class":231}," config",[213,1229,1230],{"class":826},")",[213,1232,1233],{"class":231}," throws ServletException ",[213,1235,1236],{"class":826},"{\n",[213,1238,1239,1242,1244,1246,1248,1250,1252,1255],{"class":215,"line":845},[213,1240,1241],{"class":231},"  System",[213,1243,827],{"class":826},[213,1245,978],{"class":231},[213,1247,827],{"class":826},[213,1249,984],{"class":983},[213,1251,987],{"class":826},[213,1253,1254],{"class":235},"\"创建了实例，只会执行一次\"",[213,1256,993],{"class":826},[213,1258,1259],{"class":215,"line":851},[213,1260,876],{"class":826},[21,1262,1263],{"id":1263},"service方法",[12,1265,1266],{},"每次有请求到达某个Servlet方法时执行，用来处理请求(证明该Servlet进行服务了)",[203,1268,1270],{"className":810,"code":1269,"language":812,"meta":208,"style":208},"protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {\n    System.out.println(\"调用了服务，可多次调用\");\n}\n",[210,1271,1272,1311,1331],{"__ignoreMap":208},[213,1273,1274,1277,1279,1282,1284,1287,1290,1293,1296,1299,1301,1304,1306,1309],{"class":215,"line":216},[213,1275,1276],{"class":819},"protected",[213,1278,1216],{"class":819},[213,1280,1281],{"class":983}," service",[213,1283,987],{"class":826},[213,1285,1286],{"class":819},"HttpServletRequest",[213,1288,1289],{"class":231}," req",[213,1291,1292],{"class":826},",",[213,1294,1295],{"class":819}," HttpServletResponse",[213,1297,1298],{"class":231}," resp",[213,1300,1230],{"class":826},[213,1302,1303],{"class":231}," throws ServletException",[213,1305,1292],{"class":826},[213,1307,1308],{"class":231}," IOException ",[213,1310,1236],{"class":826},[213,1312,1313,1316,1318,1320,1322,1324,1326,1329],{"class":215,"line":845},[213,1314,1315],{"class":231},"    System",[213,1317,827],{"class":826},[213,1319,978],{"class":231},[213,1321,827],{"class":826},[213,1323,984],{"class":983},[213,1325,987],{"class":826},[213,1327,1328],{"class":235},"\"调用了服务，可多次调用\"",[213,1330,993],{"class":826},[213,1332,1333],{"class":215,"line":851},[213,1334,876],{"class":826},[21,1336,1201],{"id":1337},"init方法-1",[12,1339,1340],{},"Servlet实例销毁时执行(证明该Servlet的实例被销毁了)",[203,1342,1344],{"className":810,"code":1343,"language":812,"meta":208,"style":208},"public void destroy() {\n    System.out.println(\"服务器或应用关闭\");\n}\n",[210,1345,1346,1360,1379],{"__ignoreMap":208},[213,1347,1348,1350,1352,1355,1358],{"class":215,"line":216},[213,1349,854],{"class":819},[213,1351,1216],{"class":819},[213,1353,1354],{"class":983}," destroy",[213,1356,1357],{"class":826},"()",[213,1359,870],{"class":826},[213,1361,1362,1364,1366,1368,1370,1372,1374,1377],{"class":215,"line":845},[213,1363,1315],{"class":231},[213,1365,827],{"class":826},[213,1367,978],{"class":231},[213,1369,827],{"class":826},[213,1371,984],{"class":983},[213,1373,987],{"class":826},[213,1375,1376],{"class":235},"\"服务器或应用关闭\"",[213,1378,993],{"class":826},[213,1380,1381],{"class":215,"line":851},[213,1382,876],{"class":826},[32,1384,1386],{"id":1385},"httpservletrequest对象","HttpServletRequest对象",[21,1388,424],{"id":1389},"简介-1",[12,1391,1392],{},"作用：用来接收客户端发送过来的请求信息",[12,1394,1395],{},"HttpServletRequest是ServletRequest的子接口，ServletRequest只有一个子接口，就是HttpServletRequest。提问：既然只有一个子接口，为什么不将两个接口合并为一个？",[12,1397,1398],{},"答：从长远来说，现在主要用的是HTTP协议，以后会出现更多新的协议，如果之后想要支持这种新的协议，只需要继承ServletRequest接口就可以了。",[21,1400,1401],{"id":1401},"接受请求",[458,1403,1404],{"id":1404},"常用方法",[1406,1407,1404],"h5",{"id":1408},"常用方法-1",[550,1410,1411,1421],{},[553,1412,1413],{},[556,1414,1415,1418],{},[559,1416,1417],{},"getRequestURL()",[559,1419,1420],{},"获取客户端发出请求时的完整URL",[584,1422,1423,1431,1439,1447,1455],{},[556,1424,1425,1428],{},[589,1426,1427],{},"getRequestURI(",[589,1429,1430],{},"获取请求行中的资源名称部分(项目名称开始)",[556,1432,1433,1436],{},[589,1434,1435],{},"getQueryString()",[589,1437,1438],{},"获取请求行中的参数部分",[556,1440,1441,1444],{},[589,1442,1443],{},"getMethod()",[589,1445,1446],{},"获取客户端请求方式",[556,1448,1449,1452],{},[589,1450,1451],{},"getProtocol()",[589,1453,1454],{},"获取HTTP版本号",[556,1456,1457,1460],{},[589,1458,1459],{},"getContextPath()",[589,1461,1462],{},"获取webapp名字",[1406,1464,1465],{"id":1465},"示例",[203,1467,1469],{"className":810,"code":1468,"language":812,"meta":208,"style":208},"\u002F\u002F 获取客户端请求的完整URL （从http开始，到?前面结束）\nString url = request.getRequestURL().toString();\nSystem.out.println(\"获取客户端请求的完整URL：\" + url);\n\u002F\u002F 获取客户端请求的部分URL （从站点名开始，到?前面结束）\nString uri = request.getRequestURI();\nSystem.out.println(\"获取客户端请求的部分URL：\" + uri);\n\u002F\u002F 获取请求行中的参数部分\nString queryString = request.getQueryString();\nSystem.out.println(\"获取请求行中的参数部分：\" + queryString);\n\u002F\u002F 获取客户端的请求方式\nString method = request.getMethod();\nSystem.out.println(\"获取客户端的请求方式：\" + method);\n\u002F\u002F 获取HTTP版本号\nString protocol = request.getProtocol();\nSystem.out.println(\"获取HTTP版本号：\" + protocol);\n\u002F\u002F 获取webapp名字 （站点名）\nString webapp = request.getContextPath();\nSystem.out.println(\"获取webapp名字：\" + webapp);\n",[210,1470,1471,1476,1503,1528,1533,1551,1575,1580,1598,1622,1628,1647,1672,1678,1697,1722,1728,1747],{"__ignoreMap":208},[213,1472,1473],{"class":215,"line":216},[213,1474,1475],{"class":1012},"\u002F\u002F 获取客户端请求的完整URL （从http开始，到?前面结束）\n",[213,1477,1478,1481,1484,1486,1489,1491,1494,1497,1500],{"class":215,"line":845},[213,1479,1480],{"class":819},"String",[213,1482,1483],{"class":231}," url ",[213,1485,232],{"class":219},[213,1487,1488],{"class":231}," request",[213,1490,827],{"class":826},[213,1492,1493],{"class":983},"getRequestURL",[213,1495,1496],{"class":826},"().",[213,1498,1499],{"class":983},"toString",[213,1501,1502],{"class":826},"();\n",[213,1504,1505,1507,1509,1511,1513,1515,1517,1520,1523,1526],{"class":215,"line":851},[213,1506,973],{"class":231},[213,1508,827],{"class":826},[213,1510,978],{"class":231},[213,1512,827],{"class":826},[213,1514,984],{"class":983},[213,1516,987],{"class":826},[213,1518,1519],{"class":235},"\"获取客户端请求的完整URL：\"",[213,1521,1522],{"class":219}," +",[213,1524,1525],{"class":231}," url",[213,1527,993],{"class":826},[213,1529,1530],{"class":215,"line":873},[213,1531,1532],{"class":1012},"\u002F\u002F 获取客户端请求的部分URL （从站点名开始，到?前面结束）\n",[213,1534,1535,1537,1540,1542,1544,1546,1549],{"class":215,"line":1064},[213,1536,1480],{"class":819},[213,1538,1539],{"class":231}," uri ",[213,1541,232],{"class":219},[213,1543,1488],{"class":231},[213,1545,827],{"class":826},[213,1547,1548],{"class":983},"getRequestURI",[213,1550,1502],{"class":826},[213,1552,1553,1555,1557,1559,1561,1563,1565,1568,1570,1573],{"class":215,"line":1073},[213,1554,973],{"class":231},[213,1556,827],{"class":826},[213,1558,978],{"class":231},[213,1560,827],{"class":826},[213,1562,984],{"class":983},[213,1564,987],{"class":826},[213,1566,1567],{"class":235},"\"获取客户端请求的部分URL：\"",[213,1569,1522],{"class":219},[213,1571,1572],{"class":231}," uri",[213,1574,993],{"class":826},[213,1576,1577],{"class":215,"line":1083},[213,1578,1579],{"class":1012},"\u002F\u002F 获取请求行中的参数部分\n",[213,1581,1582,1584,1587,1589,1591,1593,1596],{"class":215,"line":1100},[213,1583,1480],{"class":819},[213,1585,1586],{"class":231}," queryString ",[213,1588,232],{"class":219},[213,1590,1488],{"class":231},[213,1592,827],{"class":826},[213,1594,1595],{"class":983},"getQueryString",[213,1597,1502],{"class":826},[213,1599,1600,1602,1604,1606,1608,1610,1612,1615,1617,1620],{"class":215,"line":1119},[213,1601,973],{"class":231},[213,1603,827],{"class":826},[213,1605,978],{"class":231},[213,1607,827],{"class":826},[213,1609,984],{"class":983},[213,1611,987],{"class":826},[213,1613,1614],{"class":235},"\"获取请求行中的参数部分：\"",[213,1616,1522],{"class":219},[213,1618,1619],{"class":231}," queryString",[213,1621,993],{"class":826},[213,1623,1625],{"class":215,"line":1624},10,[213,1626,1627],{"class":1012},"\u002F\u002F 获取客户端的请求方式\n",[213,1629,1631,1633,1636,1638,1640,1642,1645],{"class":215,"line":1630},11,[213,1632,1480],{"class":819},[213,1634,1635],{"class":231}," method ",[213,1637,232],{"class":219},[213,1639,1488],{"class":231},[213,1641,827],{"class":826},[213,1643,1644],{"class":983},"getMethod",[213,1646,1502],{"class":826},[213,1648,1650,1652,1654,1656,1658,1660,1662,1665,1667,1670],{"class":215,"line":1649},12,[213,1651,973],{"class":231},[213,1653,827],{"class":826},[213,1655,978],{"class":231},[213,1657,827],{"class":826},[213,1659,984],{"class":983},[213,1661,987],{"class":826},[213,1663,1664],{"class":235},"\"获取客户端的请求方式：\"",[213,1666,1522],{"class":219},[213,1668,1669],{"class":231}," method",[213,1671,993],{"class":826},[213,1673,1675],{"class":215,"line":1674},13,[213,1676,1677],{"class":1012},"\u002F\u002F 获取HTTP版本号\n",[213,1679,1681,1683,1686,1688,1690,1692,1695],{"class":215,"line":1680},14,[213,1682,1480],{"class":819},[213,1684,1685],{"class":231}," protocol ",[213,1687,232],{"class":219},[213,1689,1488],{"class":231},[213,1691,827],{"class":826},[213,1693,1694],{"class":983},"getProtocol",[213,1696,1502],{"class":826},[213,1698,1700,1702,1704,1706,1708,1710,1712,1715,1717,1720],{"class":215,"line":1699},15,[213,1701,973],{"class":231},[213,1703,827],{"class":826},[213,1705,978],{"class":231},[213,1707,827],{"class":826},[213,1709,984],{"class":983},[213,1711,987],{"class":826},[213,1713,1714],{"class":235},"\"获取HTTP版本号：\"",[213,1716,1522],{"class":219},[213,1718,1719],{"class":231}," protocol",[213,1721,993],{"class":826},[213,1723,1725],{"class":215,"line":1724},16,[213,1726,1727],{"class":1012},"\u002F\u002F 获取webapp名字 （站点名）\n",[213,1729,1731,1733,1736,1738,1740,1742,1745],{"class":215,"line":1730},17,[213,1732,1480],{"class":819},[213,1734,1735],{"class":231}," webapp ",[213,1737,232],{"class":219},[213,1739,1488],{"class":231},[213,1741,827],{"class":826},[213,1743,1744],{"class":983},"getContextPath",[213,1746,1502],{"class":826},[213,1748,1750,1752,1754,1756,1758,1760,1762,1765,1767,1770],{"class":215,"line":1749},18,[213,1751,973],{"class":231},[213,1753,827],{"class":826},[213,1755,978],{"class":231},[213,1757,827],{"class":826},[213,1759,984],{"class":983},[213,1761,987],{"class":826},[213,1763,1764],{"class":235},"\"获取webapp名字：\"",[213,1766,1522],{"class":219},[213,1768,1769],{"class":231}," webapp",[213,1771,993],{"class":826},[458,1773,1774],{"id":1774},"获取请求参数",[1406,1776,1777],{"id":1777},"方法",[550,1779,1780,1793],{},[553,1781,1782],{},[556,1783,1784,1787,1790],{},[559,1785,1786],{},"**",[559,1788,1789],{},"getParameter(name)",[559,1791,1792],{},"获取指定名称的参数",[584,1794,1795],{},[556,1796,1797,1800,1803],{},[589,1798,1799],{},"getParameterValues(String name)",[589,1801,1802],{},"获取指定名称参数的所有值",[589,1804,1786],{},[1406,1806,1465],{"id":1807},"示例-1",[203,1809,1811],{"className":810,"code":1810,"language":812,"meta":208,"style":208},"\u002F\u002F 获取指定名称的参数，返回字符串\nString uname = request.getParameter(\"uname\");\nSystem.out.println(\"uname的参数值：\" + uname);\n\u002F\u002F 获取指定名称参数的所有参数值，返回数组\nString[] hobbys = request.getParameterValues(\"hobby\");\nSystem.out.println(\"获取指定名称参数的所有参数值：\" + Arrays.toString(hobbys));\n",[210,1812,1813,1818,1841,1865,1870,1896],{"__ignoreMap":208},[213,1814,1815],{"class":215,"line":216},[213,1816,1817],{"class":1012},"\u002F\u002F 获取指定名称的参数，返回字符串\n",[213,1819,1820,1822,1825,1827,1829,1831,1834,1836,1839],{"class":215,"line":845},[213,1821,1480],{"class":819},[213,1823,1824],{"class":231}," uname ",[213,1826,232],{"class":219},[213,1828,1488],{"class":231},[213,1830,827],{"class":826},[213,1832,1833],{"class":983},"getParameter",[213,1835,987],{"class":826},[213,1837,1838],{"class":235},"\"uname\"",[213,1840,993],{"class":826},[213,1842,1843,1845,1847,1849,1851,1853,1855,1858,1860,1863],{"class":215,"line":851},[213,1844,973],{"class":231},[213,1846,827],{"class":826},[213,1848,978],{"class":231},[213,1850,827],{"class":826},[213,1852,984],{"class":983},[213,1854,987],{"class":826},[213,1856,1857],{"class":235},"\"uname的参数值：\"",[213,1859,1522],{"class":219},[213,1861,1862],{"class":231}," uname",[213,1864,993],{"class":826},[213,1866,1867],{"class":215,"line":873},[213,1868,1869],{"class":1012},"\u002F\u002F 获取指定名称参数的所有参数值，返回数组\n",[213,1871,1872,1874,1877,1880,1882,1884,1886,1889,1891,1894],{"class":215,"line":1064},[213,1873,1480],{"class":819},[213,1875,1876],{"class":826},"[]",[213,1878,1879],{"class":231}," hobbys ",[213,1881,232],{"class":219},[213,1883,1488],{"class":231},[213,1885,827],{"class":826},[213,1887,1888],{"class":983},"getParameterValues",[213,1890,987],{"class":826},[213,1892,1893],{"class":235},"\"hobby\"",[213,1895,993],{"class":826},[213,1897,1898,1900,1902,1904,1906,1908,1910,1913,1915,1918,1920,1922,1924,1927],{"class":215,"line":1073},[213,1899,973],{"class":231},[213,1901,827],{"class":826},[213,1903,978],{"class":231},[213,1905,827],{"class":826},[213,1907,984],{"class":983},[213,1909,987],{"class":826},[213,1911,1912],{"class":235},"\"获取指定名称参数的所有参数值：\"",[213,1914,1522],{"class":219},[213,1916,1917],{"class":231}," Arrays",[213,1919,827],{"class":826},[213,1921,1499],{"class":983},[213,1923,987],{"class":826},[213,1925,1926],{"class":231},"hobbys",[213,1928,1929],{"class":826},"));\n",[21,1931,1932],{"id":1932},"请求乱码问题",[12,1934,1935],{},"Requests的编码方式为ISO-8859-1(此编码不支持中文)，所以解码时会出现乱码。可以设置Requests中的编码方式，告诉服务器以何种方式来解码，也可以在接收到乱码数据后，通过相应的编码还原数据。",[458,1937,1938],{"id":1938},"方法1",[203,1940,1942],{"className":810,"code":1941,"language":812,"meta":208,"style":208},"request.setCharacterEncoding(\"UTF-8\");\n",[210,1943,1944],{"__ignoreMap":208},[213,1945,1946,1949,1951,1954,1956,1959],{"class":215,"line":216},[213,1947,1948],{"class":231},"request",[213,1950,827],{"class":826},[213,1952,1953],{"class":983},"setCharacterEncoding",[213,1955,987],{"class":826},[213,1957,1958],{"class":235},"\"UTF-8\"",[213,1960,993],{"class":826},[26,1962,1963],{},[12,1964,1965],{},"仅对post请求有效",[458,1967,1968],{"id":1968},"方法2",[203,1970,1972],{"className":810,"code":1971,"language":812,"meta":208,"style":208},"new String(request.getParameter(name).getBytes(\"ISO-8859-1\"),\"UTF-8\");\n",[210,1973,1974],{"__ignoreMap":208},[213,1975,1976,1979,1982,1984,1986,1988,1990,1992,1995,1998,2001,2003,2006,2009,2011],{"class":215,"line":216},[213,1977,1978],{"class":819},"new",[213,1980,1981],{"class":983}," String",[213,1983,987],{"class":826},[213,1985,1948],{"class":231},[213,1987,827],{"class":826},[213,1989,1833],{"class":983},[213,1991,987],{"class":826},[213,1993,1994],{"class":231},"name",[213,1996,1997],{"class":826},").",[213,1999,2000],{"class":983},"getBytes",[213,2002,987],{"class":826},[213,2004,2005],{"class":235},"\"ISO-8859-1\"",[213,2007,2008],{"class":826},"),",[213,2010,1958],{"class":235},[213,2012,993],{"class":826},[26,2014,2015],{},[12,2016,2017],{},"Tomcat7及以下版本的GET请求会乱码，借助String方法，对任意请求都有效。但如果数据原本不乱吗，使用此方法会导致乱码。",[21,2019,2020],{"id":2020},"请求转发",[12,2022,2023],{},"请求转发，是一种服务器的行为，当用户请求到达后，服务器进行转发，此时会将请求对象进行保存，地址栏中的URL地址不会改变，得到响应后，服务器端再将响应发送给客户端，从始至终只有一个请求发出。",[12,2025,2026],{},"实现方法如下：",[203,2028,2030],{"className":810,"code":2029,"language":812,"meta":208,"style":208},"request.getRequestDispatcher(url).forward(request,response);\n",[210,2031,2032],{"__ignoreMap":208},[213,2033,2034,2036,2038,2041,2043,2046,2048,2051,2053,2055,2057,2060],{"class":215,"line":216},[213,2035,1948],{"class":231},[213,2037,827],{"class":826},[213,2039,2040],{"class":983},"getRequestDispatcher",[213,2042,987],{"class":826},[213,2044,2045],{"class":231},"url",[213,2047,1997],{"class":826},[213,2049,2050],{"class":983},"forward",[213,2052,987],{"class":826},[213,2054,1948],{"class":231},[213,2056,1292],{"class":826},[213,2058,2059],{"class":231},"response",[213,2061,993],{"class":826},[12,2063,2064],{},"特点：",[106,2066,2067,2070],{},[109,2068,2069],{},"服务端行为",[109,2071,2072],{},"地址栏不发生改变",[21,2074,2075],{"id":2075},"request作用域",[12,2077,2078],{},"通过该对象可以在一个请求中传递数据，作用范围：在一次请求中有效(请求转发时有效)。",[203,2080,2082],{"className":810,"code":2081,"language":812,"meta":208,"style":208},"\u002F\u002F 设置域对象内容\nrequest.setAttribute(String name, String value);\n\u002F\u002F 获取域对象内容\nrequest.getAttribute(String name);\n\u002F\u002F 删除域对象内容\nrequest.removeAttribute(String name);\n",[210,2083,2084,2089,2114,2119,2136,2141],{"__ignoreMap":208},[213,2085,2086],{"class":215,"line":216},[213,2087,2088],{"class":1012},"\u002F\u002F 设置域对象内容\n",[213,2090,2091,2093,2095,2098,2100,2102,2105,2107,2109,2112],{"class":215,"line":845},[213,2092,1948],{"class":231},[213,2094,827],{"class":826},[213,2096,2097],{"class":983},"setAttribute",[213,2099,987],{"class":826},[213,2101,1480],{"class":819},[213,2103,2104],{"class":231}," name",[213,2106,1292],{"class":826},[213,2108,1981],{"class":819},[213,2110,2111],{"class":231}," value",[213,2113,993],{"class":826},[213,2115,2116],{"class":215,"line":851},[213,2117,2118],{"class":1012},"\u002F\u002F 获取域对象内容\n",[213,2120,2121,2123,2125,2128,2130,2132,2134],{"class":215,"line":873},[213,2122,1948],{"class":231},[213,2124,827],{"class":826},[213,2126,2127],{"class":983},"getAttribute",[213,2129,987],{"class":826},[213,2131,1480],{"class":819},[213,2133,2104],{"class":231},[213,2135,993],{"class":826},[213,2137,2138],{"class":215,"line":1064},[213,2139,2140],{"class":1012},"\u002F\u002F 删除域对象内容\n",[213,2142,2143,2145,2147,2150,2152,2154,2156],{"class":215,"line":1073},[213,2144,1948],{"class":231},[213,2146,827],{"class":826},[213,2148,2149],{"class":983},"removeAttribute",[213,2151,987],{"class":826},[213,2153,1480],{"class":819},[213,2155,2104],{"class":231},[213,2157,993],{"class":826},[32,2159,2161],{"id":2160},"httpservletresponse对象","HttpServletResponse对象",[12,2163,2164],{},"接收用request对象，输出用response对象。",[21,2166,2167],{"id":2167},"响应数据",[12,2169,2170],{},"接收到客户端请求后，可以通过 HttpServletResponse 对象直接进行响应，响应时需要获取输出流。\n有两种形式：",[203,2172,2174],{"className":810,"code":2173,"language":812,"meta":208,"style":208},"\u002F\u002F getWriter() 字符输出流 （输出字符串）\n\u002F\u002F 获取字符输出流\nPrintWriter writer = response.getWriter();\n\u002F\u002F 输出数据\nwriter.write(\"Hello\");\n",[210,2175,2176,2181,2186,2206,2211],{"__ignoreMap":208},[213,2177,2178],{"class":215,"line":216},[213,2179,2180],{"class":1012},"\u002F\u002F getWriter() 字符输出流 （输出字符串）\n",[213,2182,2183],{"class":215,"line":845},[213,2184,2185],{"class":1012},"\u002F\u002F 获取字符输出流\n",[213,2187,2188,2191,2194,2196,2199,2201,2204],{"class":215,"line":851},[213,2189,2190],{"class":819},"PrintWriter",[213,2192,2193],{"class":231}," writer ",[213,2195,232],{"class":219},[213,2197,2198],{"class":231}," response",[213,2200,827],{"class":826},[213,2202,2203],{"class":983},"getWriter",[213,2205,1502],{"class":826},[213,2207,2208],{"class":215,"line":873},[213,2209,2210],{"class":1012},"\u002F\u002F 输出数据\n",[213,2212,2213,2216,2218,2221,2223,2226],{"class":215,"line":1064},[213,2214,2215],{"class":231},"writer",[213,2217,827],{"class":826},[213,2219,2220],{"class":983},"write",[213,2222,987],{"class":826},[213,2224,2225],{"class":235},"\"Hello\"",[213,2227,993],{"class":826},[203,2229,2231],{"className":810,"code":2230,"language":812,"meta":208,"style":208},"\u002F\u002F getOutputStream() 字节输出流 （输出一切数据）\n\u002F\u002F 获取字节输出流\nServletOutputStream out = response.getOutputStream();\n\u002F\u002F 输出数据\nout.write(\"Hello2\".getBytes());\n",[210,2232,2233,2238,2243,2262,2266],{"__ignoreMap":208},[213,2234,2235],{"class":215,"line":216},[213,2236,2237],{"class":1012},"\u002F\u002F getOutputStream() 字节输出流 （输出一切数据）\n",[213,2239,2240],{"class":215,"line":845},[213,2241,2242],{"class":1012},"\u002F\u002F 获取字节输出流\n",[213,2244,2245,2248,2251,2253,2255,2257,2260],{"class":215,"line":851},[213,2246,2247],{"class":819},"ServletOutputStream",[213,2249,2250],{"class":231}," out ",[213,2252,232],{"class":219},[213,2254,2198],{"class":231},[213,2256,827],{"class":826},[213,2258,2259],{"class":983},"getOutputStream",[213,2261,1502],{"class":826},[213,2263,2264],{"class":215,"line":873},[213,2265,2210],{"class":1012},[213,2267,2268,2270,2272,2274,2276,2279,2281,2283],{"class":215,"line":1064},[213,2269,978],{"class":231},[213,2271,827],{"class":826},[213,2273,2220],{"class":983},[213,2275,987],{"class":826},[213,2277,2278],{"class":235},"\"Hello2\"",[213,2280,827],{"class":826},[213,2282,2000],{"class":983},[213,2284,2285],{"class":826},"());\n",[12,2287,2288],{},"响应回的数据到客户端被浏览器解析。",[26,2290,2291],{},[12,2292,2293],{},"注意：两者不能同时使用",[21,2295,2296],{"id":2296},"响应乱码问题",[12,2298,2299],{},"在响应中，如果我们响应的内容中含有中文，则有可能出现乱码。这是因为服务器响应的数据也会经过网络传输，服务器端有一种编码方式，在客户端也存在一种编码方式，当量古达使用的编码方式不同时则出现乱码。",[12,2301,2302],{},"解决方法：",[203,2304,2306],{"className":810,"code":2305,"language":812,"meta":208,"style":208},"\u002F\u002F 设置服务端的编码格式\nresponse.setCharacterEncoding(\"UTF-8\");\n\u002F\u002F 设置客户端的编码格式\nresponse.setHeader(\"content-type\",\"text\u002Fhtml;charset=UTF-8\");\n\n\u002F\u002F 同时设置客户端和服务端的编码格式\nresponse.setContentType(\"text\u002Fhtml;charset=UTF-8\");\n",[210,2307,2308,2313,2327,2332,2353,2357,2362],{"__ignoreMap":208},[213,2309,2310],{"class":215,"line":216},[213,2311,2312],{"class":1012},"\u002F\u002F 设置服务端的编码格式\n",[213,2314,2315,2317,2319,2321,2323,2325],{"class":215,"line":845},[213,2316,2059],{"class":231},[213,2318,827],{"class":826},[213,2320,1953],{"class":983},[213,2322,987],{"class":826},[213,2324,1958],{"class":235},[213,2326,993],{"class":826},[213,2328,2329],{"class":215,"line":851},[213,2330,2331],{"class":1012},"\u002F\u002F 设置客户端的编码格式\n",[213,2333,2334,2336,2338,2341,2343,2346,2348,2351],{"class":215,"line":873},[213,2335,2059],{"class":231},[213,2337,827],{"class":826},[213,2339,2340],{"class":983},"setHeader",[213,2342,987],{"class":826},[213,2344,2345],{"class":235},"\"content-type\"",[213,2347,1292],{"class":826},[213,2349,2350],{"class":235},"\"text\u002Fhtml;charset=UTF-8\"",[213,2352,993],{"class":826},[213,2354,2355],{"class":215,"line":1064},[213,2356,848],{"emptyLinePlaceholder":6},[213,2358,2359],{"class":215,"line":1073},[213,2360,2361],{"class":1012},"\u002F\u002F 同时设置客户端和服务端的编码格式\n",[213,2363,2364,2366,2368,2371,2373,2375],{"class":215,"line":1083},[213,2365,2059],{"class":231},[213,2367,827],{"class":826},[213,2369,2370],{"class":983},"setContentType",[213,2372,987],{"class":826},[213,2374,2350],{"class":235},[213,2376,993],{"class":826},[21,2378,2379],{"id":2379},"重定向",[12,2381,2382],{},"重定向是由服务器指导的客户端的行为。客户端发出第一个请求，被服务器接收处理后，服务器会进行响应，在响应的同时，服务器会给客户端一个新的地址。",[203,2384,2386],{"className":810,"code":2385,"language":812,"meta":208,"style":208},"\u002F\u002F 重定向跳转到index.jsp\nresponse.sendRedirect(\"index.jsp\");\n",[210,2387,2388,2393],{"__ignoreMap":208},[213,2389,2390],{"class":215,"line":216},[213,2391,2392],{"class":1012},"\u002F\u002F 重定向跳转到index.jsp\n",[213,2394,2395,2397,2399,2402,2404,2407],{"class":215,"line":845},[213,2396,2059],{"class":231},[213,2398,827],{"class":826},[213,2400,2401],{"class":983},"sendRedirect",[213,2403,987],{"class":826},[213,2405,2406],{"class":235},"\"index.jsp\"",[213,2408,993],{"class":826},[21,2410,2411],{"id":2411},"请求转发与重定向的区别",[550,2413,2414,2422],{},[553,2415,2416],{},[556,2417,2418,2420],{},[559,2419,2020],{},[559,2421,2379],{},[584,2423,2424,2432,2439,2447],{},[556,2425,2426,2429],{},[589,2427,2428],{},"一次请求，数据在request域中共享",[589,2430,2431],{},"两次请求，数据在request域中不共享",[556,2433,2434,2436],{},[589,2435,2069],{},[589,2437,2438],{},"客户端行为",[556,2440,2441,2444],{},[589,2442,2443],{},"地址栏不发生变化",[589,2445,2446],{},"地址栏发生变化",[556,2448,2449,2452],{},[589,2450,2451],{},"绝对地址定位到站点后",[589,2453,2454],{},"绝对地址可写到http:\u002F\u002F",[32,2456,2458],{"id":2457},"cookie对象","Cookie对象",[12,2460,2461],{},"Cookie可以将一些只需要保存在客户端，或只需要在客户端进行处理的出局，存储在本地，减少网络传输，提高网页处理的效率。如：记住密码等。",[21,2463,2465],{"id":2464},"cookie的创建和发送","Cookie的创建和发送",[203,2467,2469],{"className":810,"code":2468,"language":812,"meta":208,"style":208},"\u002F\u002F 创建Cookie对象\nCookie cookie = new Cookie(\"uname\",\"zhangsan\");\n\u002F\u002F 发送Cookie对象\nresponse.addCookie(cookie);\n",[210,2470,2471,2476,2503,2508],{"__ignoreMap":208},[213,2472,2473],{"class":215,"line":216},[213,2474,2475],{"class":1012},"\u002F\u002F 创建Cookie对象\n",[213,2477,2478,2481,2484,2486,2489,2492,2494,2496,2498,2501],{"class":215,"line":845},[213,2479,2480],{"class":819},"Cookie",[213,2482,2483],{"class":231}," cookie ",[213,2485,232],{"class":219},[213,2487,2488],{"class":819}," new",[213,2490,2491],{"class":983}," Cookie",[213,2493,987],{"class":826},[213,2495,1838],{"class":235},[213,2497,1292],{"class":826},[213,2499,2500],{"class":235},"\"zhangsan\"",[213,2502,993],{"class":826},[213,2504,2505],{"class":215,"line":851},[213,2506,2507],{"class":1012},"\u002F\u002F 发送Cookie对象\n",[213,2509,2510,2512,2514,2517,2519,2522],{"class":215,"line":873},[213,2511,2059],{"class":231},[213,2513,827],{"class":826},[213,2515,2516],{"class":983},"addCookie",[213,2518,987],{"class":826},[213,2520,2521],{"class":231},"cookie",[213,2523,993],{"class":826},[21,2525,2527],{"id":2526},"cookie的获取","Cookie的获取",[12,2529,2530],{},"getCookies()方法不能指定获取某个cookie，只能获取由全部cookie组成的一个数组。如果向获取某个cookie，则需要遍历数组，并用Cookie的方法获取。",[203,2532,2534],{"className":810,"code":2533,"language":812,"meta":208,"style":208},"\u002F\u002F 获取Cookie数组\nCookie[] cookies = request.getCookies();\n\u002F\u002F 判断数组是否为空\nif(cookies != null && cookies.length > 0){\n  \u002F\u002F 遍历Cookie数组\n  for(Cookie cookie : cookies){\n    System.out.println(cookie.getName());\n    System.out.println(cookie.getValue());\n  }\n}\n",[210,2535,2536,2541,2561,2566,2603,2608,2626,2649,2672,2677],{"__ignoreMap":208},[213,2537,2538],{"class":215,"line":216},[213,2539,2540],{"class":1012},"\u002F\u002F 获取Cookie数组\n",[213,2542,2543,2545,2547,2550,2552,2554,2556,2559],{"class":215,"line":845},[213,2544,2480],{"class":819},[213,2546,1876],{"class":826},[213,2548,2549],{"class":231}," cookies ",[213,2551,232],{"class":219},[213,2553,1488],{"class":231},[213,2555,827],{"class":826},[213,2557,2558],{"class":983},"getCookies",[213,2560,1502],{"class":826},[213,2562,2563],{"class":215,"line":851},[213,2564,2565],{"class":1012},"\u002F\u002F 判断数组是否为空\n",[213,2567,2568,2571,2573,2576,2579,2583,2586,2589,2591,2594,2596,2600],{"class":215,"line":873},[213,2569,2570],{"class":819},"if",[213,2572,987],{"class":826},[213,2574,2575],{"class":231},"cookies ",[213,2577,2578],{"class":219},"!=",[213,2580,2582],{"class":2581},"s3vbe"," null",[213,2584,2585],{"class":219}," &&",[213,2587,2588],{"class":231}," cookies",[213,2590,827],{"class":826},[213,2592,2593],{"class":231},"length ",[213,2595,1033],{"class":219},[213,2597,2599],{"class":2598},"s_wmW"," 0",[213,2601,2602],{"class":826},"){\n",[213,2604,2605],{"class":215,"line":1064},[213,2606,2607],{"class":1012},"  \u002F\u002F 遍历Cookie数组\n",[213,2609,2610,2613,2615,2617,2619,2622,2624],{"class":215,"line":1073},[213,2611,2612],{"class":819},"  for",[213,2614,987],{"class":826},[213,2616,2480],{"class":819},[213,2618,2483],{"class":231},[213,2620,2621],{"class":819},":",[213,2623,2588],{"class":231},[213,2625,2602],{"class":826},[213,2627,2628,2630,2632,2634,2636,2638,2640,2642,2644,2647],{"class":215,"line":1083},[213,2629,1315],{"class":231},[213,2631,827],{"class":826},[213,2633,978],{"class":231},[213,2635,827],{"class":826},[213,2637,984],{"class":983},[213,2639,987],{"class":826},[213,2641,2521],{"class":231},[213,2643,827],{"class":826},[213,2645,2646],{"class":983},"getName",[213,2648,2285],{"class":826},[213,2650,2651,2653,2655,2657,2659,2661,2663,2665,2667,2670],{"class":215,"line":1100},[213,2652,1315],{"class":231},[213,2654,827],{"class":826},[213,2656,978],{"class":231},[213,2658,827],{"class":826},[213,2660,984],{"class":983},[213,2662,987],{"class":826},[213,2664,2521],{"class":231},[213,2666,827],{"class":826},[213,2668,2669],{"class":983},"getValue",[213,2671,2285],{"class":826},[213,2673,2674],{"class":215,"line":1119},[213,2675,2676],{"class":826},"  }\n",[213,2678,2679],{"class":215,"line":1624},[213,2680,876],{"class":826},[21,2682,2684],{"id":2683},"cookie的生存时间","Cookie的生存时间",[12,2686,2687],{},"通过设定Cookie的有效时间，可以减少一些隐私泄露的问题，默认情况下，Cookie在当前浏览器关闭时便失效。",[12,2689,2690],{},"生存时间取值有三种：",[106,2692,2693,2699,2705],{},[109,2694,2695,2696,2698],{},"负整数(默认)",[130,2697],{},"表示不存储该cookie，当前浏览器关闭时该cookie就会从内存中消失。",[109,2700,2701,2702,2704],{},"正整数",[130,2703],{},"表示存储的秒数，cookie会保存到硬盘上。",[109,2706,2707,2708,2710],{},"零",[130,2709],{},"可以删除已经存储的cookie。",[203,2712,2714],{"className":810,"code":2713,"language":812,"meta":208,"style":208},"\u002F\u002F 设置方法\ncookie.setMaxAge(1);\u002F\u002F 在硬盘中存储1秒\n",[210,2715,2716,2721],{"__ignoreMap":208},[213,2717,2718],{"class":215,"line":216},[213,2719,2720],{"class":1012},"\u002F\u002F 设置方法\n",[213,2722,2723,2725,2727,2730,2732,2735,2738],{"class":215,"line":845},[213,2724,2521],{"class":231},[213,2726,827],{"class":826},[213,2728,2729],{"class":983},"setMaxAge",[213,2731,987],{"class":826},[213,2733,2734],{"class":2598},"1",[213,2736,2737],{"class":826},");",[213,2739,2740],{"class":1012},"\u002F\u002F 在硬盘中存储1秒\n",[21,2742,2744],{"id":2743},"cookie注意事项","Cookie注意事项",[119,2746,2747,2750,2756,2759],{},[109,2748,2749],{},"Cookie仅保存在当前浏览器中",[109,2751,2752,2753,2755],{},"Cookie不能存储中文",[130,2754],{},"如果需要中文，则需要通过URLEncoder.encode编码和URLEncoder.decode解码",[109,2757,2758],{},"Cookie同名便会覆盖原有Cookie",[109,2760,2761],{},"浏览器中存储Cookie有限制，一般只存少量数据",[21,2763,2765],{"id":2764},"cookie存储路径","Cookie存储路径",[12,2767,2768],{},"通过setPath()设置存储路径。",[32,2770,2772],{"id":2771},"httpsession对象","HttpSession对象",[12,2774,2775],{},"HttpSession是一个接口，servlet容器使用此接口创建HTTP客户端的HTTP服务器之间的会话，服务器会为每一个用户创建一个独立的会话。",[12,2777,2778],{},"常用方法：",[203,2780,2782],{"className":810,"code":2781,"language":812,"meta":208,"style":208},"\u002F\u002F 获取session对象\nHttpSession session = req.getSession();\n\u002F\u002F 获取session的会话标识符\nString id = session.getId();\nSystem.out.println(id);\n\u002F\u002F 获取session的创建时间\nSystem.out.println(session.getCreationTime());\n\u002F\u002F 获取最后一次访问时间\nSystem.out.println(session.getLastAccessedTime());\n\u002F\u002F 判断是否是新的session对象\nSystem.out.println(session.isNew());\n",[210,2783,2784,2789,2808,2813,2832,2851,2856,2880,2885,2908,2913],{"__ignoreMap":208},[213,2785,2786],{"class":215,"line":216},[213,2787,2788],{"class":1012},"\u002F\u002F 获取session对象\n",[213,2790,2791,2794,2797,2799,2801,2803,2806],{"class":215,"line":845},[213,2792,2793],{"class":819},"HttpSession",[213,2795,2796],{"class":231}," session ",[213,2798,232],{"class":219},[213,2800,1289],{"class":231},[213,2802,827],{"class":826},[213,2804,2805],{"class":983},"getSession",[213,2807,1502],{"class":826},[213,2809,2810],{"class":215,"line":851},[213,2811,2812],{"class":1012},"\u002F\u002F 获取session的会话标识符\n",[213,2814,2815,2817,2820,2822,2825,2827,2830],{"class":215,"line":873},[213,2816,1480],{"class":819},[213,2818,2819],{"class":231}," id ",[213,2821,232],{"class":219},[213,2823,2824],{"class":231}," session",[213,2826,827],{"class":826},[213,2828,2829],{"class":983},"getId",[213,2831,1502],{"class":826},[213,2833,2834,2836,2838,2840,2842,2844,2846,2849],{"class":215,"line":1064},[213,2835,973],{"class":231},[213,2837,827],{"class":826},[213,2839,978],{"class":231},[213,2841,827],{"class":826},[213,2843,984],{"class":983},[213,2845,987],{"class":826},[213,2847,2848],{"class":231},"id",[213,2850,993],{"class":826},[213,2852,2853],{"class":215,"line":1073},[213,2854,2855],{"class":1012},"\u002F\u002F 获取session的创建时间\n",[213,2857,2858,2860,2862,2864,2866,2868,2870,2873,2875,2878],{"class":215,"line":1083},[213,2859,973],{"class":231},[213,2861,827],{"class":826},[213,2863,978],{"class":231},[213,2865,827],{"class":826},[213,2867,984],{"class":983},[213,2869,987],{"class":826},[213,2871,2872],{"class":231},"session",[213,2874,827],{"class":826},[213,2876,2877],{"class":983},"getCreationTime",[213,2879,2285],{"class":826},[213,2881,2882],{"class":215,"line":1100},[213,2883,2884],{"class":1012},"\u002F\u002F 获取最后一次访问时间\n",[213,2886,2887,2889,2891,2893,2895,2897,2899,2901,2903,2906],{"class":215,"line":1119},[213,2888,973],{"class":231},[213,2890,827],{"class":826},[213,2892,978],{"class":231},[213,2894,827],{"class":826},[213,2896,984],{"class":983},[213,2898,987],{"class":826},[213,2900,2872],{"class":231},[213,2902,827],{"class":826},[213,2904,2905],{"class":983},"getLastAccessedTime",[213,2907,2285],{"class":826},[213,2909,2910],{"class":215,"line":1624},[213,2911,2912],{"class":1012},"\u002F\u002F 判断是否是新的session对象\n",[213,2914,2915,2917,2919,2921,2923,2925,2927,2929,2931,2934],{"class":215,"line":1630},[213,2916,973],{"class":231},[213,2918,827],{"class":826},[213,2920,978],{"class":231},[213,2922,827],{"class":826},[213,2924,984],{"class":983},[213,2926,987],{"class":826},[213,2928,2872],{"class":231},[213,2930,827],{"class":826},[213,2932,2933],{"class":983},"isNew",[213,2935,2285],{"class":826},[21,2937,2939],{"id":2938},"session标识符","Session标识符",[12,2941,2942],{},"Session用sessionid标识每个会话。每当一次请求到达服务器，如果开启了会话，服务器第一步会查看客户端是否回传了一个名叫JSESSIONID的cookie，如果有，则认为是之前标识过的一次会话，返回该session对象，达成数据共享；如果没有，则认为这是一次新的会话，重新创建一个新的session对象，并标志此次会话。",[21,2944,2946],{"id":2945},"session域对象","Session域对象",[12,2948,2949],{},"Session用来表示一次会话，在一次会话中数据是可以共享的，这时session作为域对象存在，可以通过setAttribute(name,value)方法向域对象中添加数据，通过getAttribute(name)从域对象中获取数据，通过removeAttribute(name)从域对象中移除数据。",[12,2951,2778],{},[203,2953,2955],{"className":810,"code":2954,"language":812,"meta":208,"style":208},"\u002F\u002F 获取session对象\nHttpSession session = req.getSession();\n\u002F\u002F 设置session域对象\nsession.setAttribute(\"uname\",\"zhangsan\");\n\u002F\u002F 获取指定名称的session域对象\nString uname = (String)req.getAttribute(\"uname\");\n\u002F\u002F 移除指定名称session域对象\nsession.removeAttribute(\"uname\");\n",[210,2956,2957,2961,2977,2982,3000,3005,3033,3038],{"__ignoreMap":208},[213,2958,2959],{"class":215,"line":216},[213,2960,2788],{"class":1012},[213,2962,2963,2965,2967,2969,2971,2973,2975],{"class":215,"line":845},[213,2964,2793],{"class":819},[213,2966,2796],{"class":231},[213,2968,232],{"class":219},[213,2970,1289],{"class":231},[213,2972,827],{"class":826},[213,2974,2805],{"class":983},[213,2976,1502],{"class":826},[213,2978,2979],{"class":215,"line":851},[213,2980,2981],{"class":1012},"\u002F\u002F 设置session域对象\n",[213,2983,2984,2986,2988,2990,2992,2994,2996,2998],{"class":215,"line":873},[213,2985,2872],{"class":231},[213,2987,827],{"class":826},[213,2989,2097],{"class":983},[213,2991,987],{"class":826},[213,2993,1838],{"class":235},[213,2995,1292],{"class":826},[213,2997,2500],{"class":235},[213,2999,993],{"class":826},[213,3001,3002],{"class":215,"line":1064},[213,3003,3004],{"class":1012},"\u002F\u002F 获取指定名称的session域对象\n",[213,3006,3007,3009,3011,3013,3016,3018,3020,3023,3025,3027,3029,3031],{"class":215,"line":1073},[213,3008,1480],{"class":819},[213,3010,1824],{"class":231},[213,3012,232],{"class":219},[213,3014,3015],{"class":826}," (",[213,3017,1480],{"class":231},[213,3019,1230],{"class":826},[213,3021,3022],{"class":231},"req",[213,3024,827],{"class":826},[213,3026,2127],{"class":983},[213,3028,987],{"class":826},[213,3030,1838],{"class":235},[213,3032,993],{"class":826},[213,3034,3035],{"class":215,"line":1083},[213,3036,3037],{"class":1012},"\u002F\u002F 移除指定名称session域对象\n",[213,3039,3040,3042,3044,3046,3048,3050],{"class":215,"line":1100},[213,3041,2872],{"class":231},[213,3043,827],{"class":826},[213,3045,2149],{"class":983},[213,3047,987],{"class":826},[213,3049,1838],{"class":235},[213,3051,993],{"class":826},[106,3053,3054],{},[109,3055,3056],{},"Session域 > request域",[458,3058,3060],{"id":3059},"session域对象的生命周期","Session域对象的生命周期",[12,3062,3063],{},"Tomcat中session默认的存活时间为30min，当无操作时长达到session生存时间，会话便会结束。",[12,3065,3066],{},"自定义生命周期(单位：秒)：",[203,3068,3070],{"className":810,"code":3069,"language":812,"meta":208,"style":208},"\u002F\u002F 获取session对象\nHttpSession session = request.getSession();\n\u002F\u002F 查看session的最大不活动时间\nsession.getMaxInactiveInterval();\n\u002F\u002F 设置session的最大不活动时间\nsession.setMaxInactiveInterval(10);\u002F\u002F 无操作10秒关闭会话\n",[210,3071,3072,3076,3092,3097,3108,3113],{"__ignoreMap":208},[213,3073,3074],{"class":215,"line":216},[213,3075,2788],{"class":1012},[213,3077,3078,3080,3082,3084,3086,3088,3090],{"class":215,"line":845},[213,3079,2793],{"class":819},[213,3081,2796],{"class":231},[213,3083,232],{"class":219},[213,3085,1488],{"class":231},[213,3087,827],{"class":826},[213,3089,2805],{"class":983},[213,3091,1502],{"class":826},[213,3093,3094],{"class":215,"line":851},[213,3095,3096],{"class":1012},"\u002F\u002F 查看session的最大不活动时间\n",[213,3098,3099,3101,3103,3106],{"class":215,"line":873},[213,3100,2872],{"class":231},[213,3102,827],{"class":826},[213,3104,3105],{"class":983},"getMaxInactiveInterval",[213,3107,1502],{"class":826},[213,3109,3110],{"class":215,"line":1064},[213,3111,3112],{"class":1012},"\u002F\u002F 设置session的最大不活动时间\n",[213,3114,3115,3117,3119,3122,3124,3127,3129],{"class":215,"line":1073},[213,3116,2872],{"class":231},[213,3118,827],{"class":826},[213,3120,3121],{"class":983},"setMaxInactiveInterval",[213,3123,987],{"class":826},[213,3125,3126],{"class":2598},"10",[213,3128,2737],{"class":826},[213,3130,3131],{"class":1012},"\u002F\u002F 无操作10秒关闭会话\n",[32,3133,3135],{"id":3134},"servletcontext对象","ServletContext对象",[21,3137,3139],{"id":3138},"servletcontext对象的获取","ServletContext对象的获取",[12,3141,3142],{},"每一个 web 应用都有且仅有一个ServletContext 对象，又称 Application 对象，从名称中可知，该对象是与应用程 序相关的。在 WEB 容器启动的时候，会为每一个 WEB 应用程序创建一个对应的 ServletContext 对象。",[12,3144,3145],{},"作用：",[106,3147,3148,3151],{},[109,3149,3150],{},"第一、作为域对象用来共享数据，此时数据在整个应用程序中共享",[109,3152,3153],{},"第二、该对象中保存了当前应用程序相关信息。",[203,3155,3157],{"className":810,"code":3156,"language":812,"meta":208,"style":208},"\u002F\u002F 通过request对象获取\nServletContext servletContext = request.getServletContext();\n\u002F\u002F 通过session对象获取\nServletContext servletContext1 = request.getSession().getServletContext();\n\u002F\u002F 通过ServletConfig获取\nServletContext servletContext2 = getServletConfig().getServletContext();\n\u002F\u002F 直接获取\nServletContext servletContext3 = getServletContext();\n",[210,3158,3159,3164,3183,3188,3209,3214,3232,3237],{"__ignoreMap":208},[213,3160,3161],{"class":215,"line":216},[213,3162,3163],{"class":1012},"\u002F\u002F 通过request对象获取\n",[213,3165,3166,3169,3172,3174,3176,3178,3181],{"class":215,"line":845},[213,3167,3168],{"class":819},"ServletContext",[213,3170,3171],{"class":231}," servletContext ",[213,3173,232],{"class":219},[213,3175,1488],{"class":231},[213,3177,827],{"class":826},[213,3179,3180],{"class":983},"getServletContext",[213,3182,1502],{"class":826},[213,3184,3185],{"class":215,"line":851},[213,3186,3187],{"class":1012},"\u002F\u002F 通过session对象获取\n",[213,3189,3190,3192,3195,3197,3199,3201,3203,3205,3207],{"class":215,"line":873},[213,3191,3168],{"class":819},[213,3193,3194],{"class":231}," servletContext1 ",[213,3196,232],{"class":219},[213,3198,1488],{"class":231},[213,3200,827],{"class":826},[213,3202,2805],{"class":983},[213,3204,1496],{"class":826},[213,3206,3180],{"class":983},[213,3208,1502],{"class":826},[213,3210,3211],{"class":215,"line":1064},[213,3212,3213],{"class":1012},"\u002F\u002F 通过ServletConfig获取\n",[213,3215,3216,3218,3221,3223,3226,3228,3230],{"class":215,"line":1073},[213,3217,3168],{"class":819},[213,3219,3220],{"class":231}," servletContext2 ",[213,3222,232],{"class":219},[213,3224,3225],{"class":983}," getServletConfig",[213,3227,1496],{"class":826},[213,3229,3180],{"class":983},[213,3231,1502],{"class":826},[213,3233,3234],{"class":215,"line":1083},[213,3235,3236],{"class":1012},"\u002F\u002F 直接获取\n",[213,3238,3239,3241,3244,3246,3249],{"class":215,"line":1100},[213,3240,3168],{"class":819},[213,3242,3243],{"class":231}," servletContext3 ",[213,3245,232],{"class":219},[213,3247,3248],{"class":983}," getServletContext",[213,3250,1502],{"class":826},[12,3252,2778],{},[203,3254,3256],{"className":810,"code":3255,"language":812,"meta":208,"style":208},"\u002F\u002F 1.获取当前服务器的版本信息\nString serverInfo = request.getServletContext().getServerInfo();\nSystem.out.println(serverInfo);\n\u002F\u002F 2.获取真实路径\nString realPath = request.getServletContext().getRealPath(\"\u002F\");\nSystem.out.println(realPath);\n",[210,3257,3258,3263,3285,3304,3309,3336],{"__ignoreMap":208},[213,3259,3260],{"class":215,"line":216},[213,3261,3262],{"class":1012},"\u002F\u002F 1.获取当前服务器的版本信息\n",[213,3264,3265,3267,3270,3272,3274,3276,3278,3280,3283],{"class":215,"line":845},[213,3266,1480],{"class":819},[213,3268,3269],{"class":231}," serverInfo ",[213,3271,232],{"class":219},[213,3273,1488],{"class":231},[213,3275,827],{"class":826},[213,3277,3180],{"class":983},[213,3279,1496],{"class":826},[213,3281,3282],{"class":983},"getServerInfo",[213,3284,1502],{"class":826},[213,3286,3287,3289,3291,3293,3295,3297,3299,3302],{"class":215,"line":851},[213,3288,973],{"class":231},[213,3290,827],{"class":826},[213,3292,978],{"class":231},[213,3294,827],{"class":826},[213,3296,984],{"class":983},[213,3298,987],{"class":826},[213,3300,3301],{"class":231},"serverInfo",[213,3303,993],{"class":826},[213,3305,3306],{"class":215,"line":873},[213,3307,3308],{"class":1012},"\u002F\u002F 2.获取真实路径\n",[213,3310,3311,3313,3316,3318,3320,3322,3324,3326,3329,3331,3334],{"class":215,"line":1064},[213,3312,1480],{"class":819},[213,3314,3315],{"class":231}," realPath ",[213,3317,232],{"class":219},[213,3319,1488],{"class":231},[213,3321,827],{"class":826},[213,3323,3180],{"class":983},[213,3325,1496],{"class":826},[213,3327,3328],{"class":983},"getRealPath",[213,3330,987],{"class":826},[213,3332,3333],{"class":235},"\"\u002F\"",[213,3335,993],{"class":826},[213,3337,3338,3340,3342,3344,3346,3348,3350,3353],{"class":215,"line":1073},[213,3339,973],{"class":231},[213,3341,827],{"class":826},[213,3343,978],{"class":231},[213,3345,827],{"class":826},[213,3347,984],{"class":983},[213,3349,987],{"class":826},[213,3351,3352],{"class":231},"realPath",[213,3354,993],{"class":826},[21,3356,3358],{"id":3357},"servletcontext域对象","ServletContext域对象",[12,3360,3361],{},"ServletContext也可以当作域对象使用给，通过向ServletContext中存取数据，可以使整个应用程序共享某些数据。ServletContext中数据在服务器关闭后失效。",[203,3363,3365],{"className":810,"code":3364,"language":812,"meta":208,"style":208},"\u002F\u002F 获取ServletContext对象\nServletContext servletContext = req.getServletContext();\n\u002F\u002F 设置域对象\nservletContext.setAttribute(\"name\",\"zhangsan\");\n\u002F\u002F 获取域对象\nString name = (String)servletContext.getAttribute(\"name\");\n\u002F\u002F 移除域对象\nservletContext.removeAttribute(\"name\");\n",[210,3366,3367,3372,3388,3393,3413,3418,3445,3450],{"__ignoreMap":208},[213,3368,3369],{"class":215,"line":216},[213,3370,3371],{"class":1012},"\u002F\u002F 获取ServletContext对象\n",[213,3373,3374,3376,3378,3380,3382,3384,3386],{"class":215,"line":845},[213,3375,3168],{"class":819},[213,3377,3171],{"class":231},[213,3379,232],{"class":219},[213,3381,1289],{"class":231},[213,3383,827],{"class":826},[213,3385,3180],{"class":983},[213,3387,1502],{"class":826},[213,3389,3390],{"class":215,"line":851},[213,3391,3392],{"class":1012},"\u002F\u002F 设置域对象\n",[213,3394,3395,3398,3400,3402,3404,3407,3409,3411],{"class":215,"line":873},[213,3396,3397],{"class":231},"servletContext",[213,3399,827],{"class":826},[213,3401,2097],{"class":983},[213,3403,987],{"class":826},[213,3405,3406],{"class":235},"\"name\"",[213,3408,1292],{"class":826},[213,3410,2500],{"class":235},[213,3412,993],{"class":826},[213,3414,3415],{"class":215,"line":1064},[213,3416,3417],{"class":1012},"\u002F\u002F 获取域对象\n",[213,3419,3420,3422,3425,3427,3429,3431,3433,3435,3437,3439,3441,3443],{"class":215,"line":1073},[213,3421,1480],{"class":819},[213,3423,3424],{"class":231}," name ",[213,3426,232],{"class":219},[213,3428,3015],{"class":826},[213,3430,1480],{"class":231},[213,3432,1230],{"class":826},[213,3434,3397],{"class":231},[213,3436,827],{"class":826},[213,3438,2127],{"class":983},[213,3440,987],{"class":826},[213,3442,3406],{"class":235},[213,3444,993],{"class":826},[213,3446,3447],{"class":215,"line":1083},[213,3448,3449],{"class":1012},"\u002F\u002F 移除域对象\n",[213,3451,3452,3454,3456,3458,3460,3462],{"class":215,"line":1100},[213,3453,3397],{"class":231},[213,3455,827],{"class":826},[213,3457,2149],{"class":983},[213,3459,987],{"class":826},[213,3461,3406],{"class":235},[213,3463,993],{"class":826},[32,3465,3467],{"id":3466},"servlet的三大域对象","Servlet的三大域对象",[119,3469,3470,3476,3481],{},[109,3471,3472,3473,3475],{},"request域对象",[130,3474],{},"在一次请求中有效。请求转发有效，重定向失效。",[109,3477,2945,3478,3480],{},[130,3479],{},"在一次会话中有效。请求转发有效，重定向失效。",[109,3482,3483,3484,3486],{},"context域对象",[130,3485],{},"在整个应用程序中有效。关闭服务器后失效。",[16,3488,3490],{"id":3489},"待更新","待更新。。。",[12,3492,3493],{},"参考资料：",[106,3495,3496,3503],{},[109,3497,3498],{},[46,3499,3502],{"href":3500,"rel":3501},"https:\u002F\u002Fzh.wikipedia.org\u002Fzh-hans\u002FJava_Servlet",[50],"维基百科",[109,3504,3505],{},[46,3506,3509],{"href":3507,"rel":3508},"https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1MX4y1G7ap",[50],"b站Servlet教学视频",[3511,3512,3513],"style",{},"html pre.shiki code .siJSA, html code.shiki .siJSA{--shiki-default:#94E2D5;--shiki-light:#179299}html pre.shiki code .sZBvu, html code.shiki .sZBvu{--shiki-default:#89B4FA;--shiki-light:#1E66F5}html pre.shiki code .sIs8M, html code.shiki .sIs8M{--shiki-default:#F9E2AF;--shiki-light:#DF8E1D}html pre.shiki code .szT_X, html code.shiki .szT_X{--shiki-default:#CDD6F4;--shiki-light:#4C4F69}html pre.shiki code .ssZzq, html code.shiki .ssZzq{--shiki-default:#A6E3A1;--shiki-light:#40A02B}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html pre.shiki code .sDkzg, html code.shiki .sDkzg{--shiki-default:#CBA6F7;--shiki-light:#8839EF}html pre.shiki code .sxk1D, html code.shiki .sxk1D{--shiki-default:#9399B2;--shiki-light:#7C7F93}html pre.shiki code .szFfR, html code.shiki .szFfR{--shiki-default:#F9E2AF;--shiki-default-font-style:italic;--shiki-light:#DF8E1D;--shiki-light-font-style:italic}html pre.shiki code .s3Fsb, html code.shiki .s3Fsb{--shiki-default:#89B4FA;--shiki-default-font-style:italic;--shiki-light:#1E66F5;--shiki-light-font-style:italic}html pre.shiki code .s0D_2, html code.shiki .s0D_2{--shiki-default:#9399B2;--shiki-default-font-style:italic;--shiki-light:#7C7F93;--shiki-light-font-style:italic}html pre.shiki code .s3vbe, html code.shiki .s3vbe{--shiki-default:#F38BA8;--shiki-light:#D20F39}html pre.shiki code .s_wmW, html code.shiki .s_wmW{--shiki-default:#FAB387;--shiki-light:#FE640B}",{"title":208,"searchDepth":1649,"depth":1064,"links":3515},[3516,3517,3523,3524,3529,3536,3547,3552,3571,3577,3584,3590,3594],{"id":23,"depth":851,"text":24},{"id":34,"depth":845,"text":34,"children":3518},[3519,3520,3521,3522],{"id":65,"depth":851,"text":65},{"id":71,"depth":851,"text":71},{"id":82,"depth":851,"text":82},{"id":104,"depth":851,"text":104},{"id":117,"depth":845,"text":117},{"id":169,"depth":845,"text":169,"children":3525},[3526,3527,3528],{"id":172,"depth":851,"text":173},{"id":289,"depth":851,"text":290},{"id":332,"depth":851,"text":333},{"id":423,"depth":845,"text":424,"children":3530},[3531,3532,3535],{"id":427,"depth":851,"text":24},{"id":441,"depth":851,"text":442,"children":3533},[3534],{"id":460,"depth":873,"text":461},{"id":464,"depth":851,"text":465},{"id":488,"depth":845,"text":489,"children":3537},[3538,3539,3540,3541,3542,3546],{"id":492,"depth":851,"text":492},{"id":531,"depth":851,"text":532},{"id":548,"depth":851,"text":548},{"id":790,"depth":851,"text":791},{"id":890,"depth":851,"text":890,"children":3543},[3544,3545],{"id":922,"depth":873,"text":923},{"id":929,"depth":873,"text":930},{"id":1151,"depth":851,"text":1151},{"id":1163,"depth":845,"text":1164,"children":3548},[3549,3550,3551],{"id":1201,"depth":851,"text":1201},{"id":1263,"depth":851,"text":1263},{"id":1337,"depth":851,"text":1201},{"id":1385,"depth":845,"text":1386,"children":3553},[3554,3555,3565,3569,3570],{"id":1389,"depth":851,"text":424},{"id":1401,"depth":851,"text":1401,"children":3556},[3557,3561],{"id":1404,"depth":873,"text":1404,"children":3558},[3559,3560],{"id":1408,"depth":1064,"text":1404},{"id":1465,"depth":1064,"text":1465},{"id":1774,"depth":873,"text":1774,"children":3562},[3563,3564],{"id":1777,"depth":1064,"text":1777},{"id":1807,"depth":1064,"text":1465},{"id":1932,"depth":851,"text":1932,"children":3566},[3567,3568],{"id":1938,"depth":873,"text":1938},{"id":1968,"depth":873,"text":1968},{"id":2020,"depth":851,"text":2020},{"id":2075,"depth":851,"text":2075},{"id":2160,"depth":845,"text":2161,"children":3572},[3573,3574,3575,3576],{"id":2167,"depth":851,"text":2167},{"id":2296,"depth":851,"text":2296},{"id":2379,"depth":851,"text":2379},{"id":2411,"depth":851,"text":2411},{"id":2457,"depth":845,"text":2458,"children":3578},[3579,3580,3581,3582,3583],{"id":2464,"depth":851,"text":2465},{"id":2526,"depth":851,"text":2527},{"id":2683,"depth":851,"text":2684},{"id":2743,"depth":851,"text":2744},{"id":2764,"depth":851,"text":2765},{"id":2771,"depth":845,"text":2772,"children":3585},[3586,3587],{"id":2938,"depth":851,"text":2939},{"id":2945,"depth":851,"text":2946,"children":3588},[3589],{"id":3059,"depth":873,"text":3060},{"id":3134,"depth":845,"text":3135,"children":3591},[3592,3593],{"id":3138,"depth":851,"text":3139},{"id":3357,"depth":851,"text":3358},{"id":3466,"depth":845,"text":3467},[3596],"笔记","\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet.jpg","本文介绍Tomcat与Servlet的配置及常见问题。Tomcat部分涵盖安装、环境变量、启动关闭、乱码与端口占用处理、项目部署及IDEA集成。Servlet部分说明实现方式、生命周期、请求与响应对象、乱码处理、请求转发与重定向，以及Cookie、Session、ServletContext等对象和三大域对象的作用范围。","md",{},"\u002Fposts\u002F2021\u002Ftomcat-servlet",0,"2021-03-22",{"title":5,"description":3598},"posts\u002F2021\u002Ftomcat-servlet","ai",[3608,19,420],"JavaWEb","#a369ff",false,4196,"H2cMUlpTxoR4-7QKEMmg0c_TtKO0ivoupQW3j6bbAnY",[3614,3630,3644,3652,3665,3680,3693,3705,3715,3728,3740,3751,3763,3773,3776,3787,3796,3810,3822,3834,3847,3856,3866,3875],{"path":3615,"stem":3616,"title":3617,"description":3618,"wordCount":3619,"publish":3620,"update":3620,"cover":3621,"tags":3622,"categories":3628,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002F2026\u002Fwsl3","posts\u002F2026\u002Fwsl3","WSL 3 正式发布~","微软发布 WSL 3.0.1，正式提供稳定的 WSL 容器功能，无需 Docker 即可原生创建和运行 Linux 容器。该版本改进包括跨操作系统文件访问性能最高提升至原来的两倍（采用 virtiofs），以及网络模式 Consomme 优化端口映射和 VPN 兼容性。文章介绍了 WSL 安装、从 WSL 2 升级的方法，并示例使用 wslc 运行 Ubuntu、Nginx 容器及构建自定义镜像。",1038,"2026-10-01","\u002Fimages\u002F2026\u002Fwsl3\u002Fwsl3.png",[3623,3624,3625,3626,3627],"WSL","Linux","Windows","Docker","容器",[3629],"工具",{"path":3631,"stem":3632,"title":3633,"description":3634,"wordCount":3635,"publish":3636,"update":7,"cover":3637,"tags":3638,"categories":3643,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002F2026\u002Fcodex-prompt","posts\u002F2026\u002Fcodex-prompt","Codex 的 GPT-6 Sol 提示词泄露了？","文章围绕网传Codex GPT-6 Sol提示词泄露展开，选取部分内容解读。提示词要求像同事一样交流、降低认知负担，用具体描述并说明改动、原因、测试与风险；明确禁止使用AI套话；通过高质量和低质量示例约束输出。摘要表还涵盖沟通、执行、权限、长期任务、工具与界面、质量与证据等核心要求。",1073,"2026-09-25","\u002Fimages\u002F2026\u002Fcodex-prompt\u002Fcodex-prompt.png",[3639,3640,3641,3642],"AI","Codex","提示词","Agent",[3639],{"path":3645,"stem":3646,"title":3647,"description":3648,"wordCount":3649,"publish":3636,"update":7,"cover":7,"tags":3650,"categories":3651,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002F2026\u002Fcodex-prompt-translation","posts\u002F2026\u002Fcodex-prompt-translation","Codex GPT-6 Sol 提示词完整中文译文","第三方仓库收录的 Codex GPT-6 Sol 提示词中文译文，按原顺序保留全部 54 个模板。",34261,[3639,3640,3641,3642],[3639],{"path":3653,"stem":3654,"title":3655,"description":3656,"wordCount":3657,"publish":3658,"update":3659,"cover":3660,"tags":3661,"categories":3664,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002F2026\u002Fjev","posts\u002F2026\u002Fjev","JEV 是好模型吗？","本文评析JEV模型，认为其并非通用大模型，而是专做预定义判断的System One模型，通过选择、评分、是非题返回结构化结果，不生成文本。其快与便宜源于非自回归并行输出，但“零幻觉”仅指输出结构合规，判断仍可能出错。该思路适用于答案范围明确、需频繁调用的场景，也可用普通大模型近似实现，核心在于把任务收窄为单一判断。",2429,"2026-09-21","2026-09-23","\u002Fimages\u002F2026\u002Fjev\u002Fjev.webp",[3639,3662,3663],"JEV","LLM",[3639],{"path":3666,"stem":3667,"title":3668,"description":3669,"wordCount":3670,"publish":3671,"update":3672,"cover":7,"tags":3673,"categories":3678,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002Fblog\u002Foverview","posts\u002F2.blog\u002F01.overview","新版博客已上线！","新版博客“mukuchi”上线，具备文章写作、标签分类、全文搜索、阅读目录、代码复制、图片缩放、深浅主题切换及移动端适配等功能。内容以Markdown和MDC编写，后台支持草稿、上传、预览与发布，并可生成AI摘要、朗读和双人播客。技术栈采用Nuxt、Vue、UnoCSS、Nuxt Content及Cloudflare服务，文章存于GitHub仓库。后续计划增加工具、重做账号系统并改为站内评论。",1059,"2026-09-14","2026-09-22",[3674,3675,3676,3677],"博客","Nuxt","Vue","Cloudflare",[3679],"建站记录",{"path":3681,"stem":3682,"title":3683,"description":3684,"wordCount":3685,"publish":3686,"update":7,"cover":7,"tags":3687,"categories":3691,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002F2026\u002Fgame-dlss5","posts\u002F2026\u002Fgame-dlss5","哦，我的上帝！这是真实的！ —— DLSS 5 渲染实测","文章以《崩坏3rd》和《崩坏：星穹铁道》为例，展示DLSS 5渲染在多个场景下开启与关闭的画面对比。教程说明通过XXMI-Launcher注入ReShade的d3d12.dll，启动游戏后按Home键配置RenoDX DLSS参数，并提示下线前需手动关闭。文末附相关工具与网盘资源下载方式。",390,"2026-09-08",[3688,3689,3690],"DLSS5","mod","xxmi",[3692],"游戏",{"path":3694,"stem":3695,"title":3696,"description":3697,"wordCount":3698,"publish":3699,"update":3700,"cover":7,"tags":3701,"categories":3704,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002F2026\u002Fmilanote-api","posts\u002F2026\u002Fmilanote-api","Milanote API","本文介绍了作者开发的 Milanote API 项目，用于在外部使用 Milanote 分享 Board 的内容。项目已完成根据分享链接获取完整 API 数据、解析卡片内容与布局、构建 Playground 在线可视化示例、部署至 Cloudflare Workers 并提供字段筛选功能；待实现免密钥在线解析。文章还说明了获取 Milanote 只读分享链接的步骤，并展示了 Playground 界面效果。",234,"2026-07-22","2026-07-23",[3702,3703],"Milanote","API",[3629],{"path":3706,"stem":3707,"title":3708,"description":3709,"wordCount":3710,"publish":3711,"update":7,"cover":3712,"tags":3713,"categories":3714,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002F2026\u002Fduolingo","posts\u002F2026\u002Fduolingo","今天你 Duolingo 了吗？","本文介绍使用 Cloudflare Workers 构建 Duolingo 用户信息接口，解决跨域与缓存问题。接口支持按环境变量查询固定用户，返回昵称、头像、经验及连续学习天数，并提供搜索和其他用户详情接口。通过 KV 缓存和定时任务减少上游请求，支持带鉴权的手动刷新，并包含超时和错误处理。",1581,"2026-07-14","\u002Fimages\u002F2026\u002Fduolingo\u002Fduolingo.png",[3703,3677],[3629],{"path":3716,"stem":3717,"title":3718,"description":3719,"wordCount":3720,"publish":3721,"update":7,"cover":7,"tags":3722,"categories":3727,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002Fblender","posts\u002Fblender\u002Findex","Blender 专题","本文介绍Blender这一免费开源3D建模软件，涵盖建模、动画、渲染、视频剪辑等功能，适合从入门到高级开发。文档提供官网地址；教程部分包含动画大师课VV purple、角色建模课Zimon3D，并附B站链接；素材推荐BlenderKit官方素材库、Sketchfab及模之屋等免费资源平台。",158,"2026-06-18",[3723,3724,3725,3726],"Blender","3D","建模","动画",[3723],{"path":3729,"stem":3730,"title":3731,"description":3732,"wordCount":3733,"publish":3721,"update":7,"cover":7,"tags":3734,"categories":3739,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002Fthreejs","posts\u002Fthreejs\u002Findex","Three.js 专题","本文介绍Three.js作为Web端主流3D图形库，封装WebGL\u002FWebGPU，用于构建3D场景、动画、游戏和数据可视化等。文章汇总官方资源，包括官网、示例、文档、教程、在线编辑器和GitHub仓库。基础使用方面，说明在Vue3中通过TresJS、React中通过React Three Fiber进行组件化开发，并提及GSAP动画库和Blender建模软件。其他资源推荐Three.js Journey系统教程、The Book of Shaders书籍和Kenney免费游戏素材，AI与问题部分尚在完善中。",418,[3735,3736,3737,3738],"Three.js","WebGL","WebGPU","Shader",[3735],{"path":3741,"stem":3742,"title":3743,"description":3744,"wordCount":3745,"publish":3746,"update":3746,"cover":3747,"tags":3748,"categories":3750,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002F2025\u002Fmagic-js","posts\u002F2025\u002Fmagic-js","你能看懂这些 JavaScript 表达式吗？","本文解析了JavaScript中多个怪异表达式结果的原因，指出其源于IEEE 754浮点数表示、隐式类型转换及同一符号在不同语法环境中的歧义。例如NaN为number、大整数舍入、0.1+0.2不等于0.3、空数组与对象相加、布尔值运算及宽松相等等行为，均可据此解释。建议工程中使用严格相等和明确转换以避免陷阱。",2035,"2025-07-31","\u002Fimages\u002F2025\u002Fmagic-js\u002Fmagic-js.png",[3749],"JavaScript",[3749],{"path":3752,"stem":3753,"title":3754,"description":3755,"wordCount":3756,"publish":3757,"update":3758,"cover":3759,"tags":3760,"categories":3762,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002F2021\u002Fgit","posts\u002F2021\u002Fgit","Git 笔记","本文介绍Git的安装与基础配置，涵盖用户名邮箱设置及配置作用域优先级；解释工作区、暂存区和本地仓库的工作流；列举git add、commit、branch、switch、log、diff、stash、rm、mv等常用命令；说明查看日志、比较差异、对象关系、搁置改动、忽略文件等操作；并回答删除分支、修改提交信息、合并提交、取消暂存、丢弃改动和删除文件等常见问题。",878,"2021-09-07","2026-05-17","https:\u002F\u002Fgit-scm.com\u002Fimages\u002Flogo@2x.png",[3761],"Git",[3629],{"path":3764,"stem":3765,"title":3766,"description":3767,"wordCount":3768,"publish":3603,"update":7,"cover":3769,"tags":3770,"categories":3772,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002F2021\u002Fhexo-editor","posts\u002F2021\u002Fhexo-editor","HexoEditor(适用于Hexo的专用编辑器)","本文介绍了专为Hexo优化的Markdown编辑器HexoEditor。该编辑器预览效果与Hexo生成页面高度相似，支持快速执行Hexo命令。软件开源，可从GitHub获取安装程序及中英文手册。配置包括通用、编辑、Hexo路径设置、渲染主题（支持GitHub和Next）以及图片云存储（如SM.MS、腾讯云等）。还提供右键快捷操作Hexo命令。",587,"\u002Fimages\u002F2021\u002Fhexo-editor\u002Fhexo-editor.jpg",[3629,3771],"Hexo",[3629],{"path":3601,"stem":3605,"title":5,"description":3598,"wordCount":3611,"publish":3603,"update":7,"cover":3597,"tags":3774,"categories":3775,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},[3608,19,420],[3596],{"path":3777,"stem":3778,"title":3779,"description":3780,"wordCount":3781,"publish":3782,"update":7,"cover":3783,"tags":3784,"categories":3786,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002F2021\u002Fgithub-actions","posts\u002F2021\u002Fgithub-actions","使用Github Action实现全自动部署","本文介绍使用GitHub Action实现Hexo博客全自动部署的流程。需先获取GitHub与Coding的个人访问令牌，创建存放源码的私有仓库，并在站点配置中设置部署仓库地址和令牌。接着在.github\u002Fworkflows目录创建自动部署工作流文件，配置检出、安装Node与Hexo、缓存依赖、生成静态文件和部署步骤。随后更新远程仓库分支，添加.gitignore屏蔽项并推送源码，最后通过Actions查看部署状态。",910,"2021-01-26","\u002Fimages\u002F2021\u002Fgithub-actions\u002Fgithub-actions.jpg",[3785],"博客优化",[3785],{"path":3788,"stem":3789,"title":3790,"description":3791,"wordCount":3792,"publish":3782,"update":7,"cover":3793,"tags":3794,"categories":3795,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002F2021\u002Fhexo-auto-open-editor","posts\u002F2021\u002Fhexo-auto-open-editor","Hexo添加文章时自动打开编辑器","本文介绍Hexo新建文章后自动打开编辑器的方法。通过监听Hexo的new事件并在scripts目录下添加脚本，利用child_process.exec执行系统命令，Windows使用start、macOS使用open -a启动指定编辑器并打开新文章路径。用户需替换脚本中的编辑器绝对地址，保存后执行hexo new即可自动打开对应文件。",269,"\u002Fimages\u002F2021\u002Fhexo-auto-open-editor\u002Fhexo-auto-open-editor.webp",[3785],[3785],{"path":3797,"stem":3798,"title":3799,"description":3800,"wordCount":3801,"publish":3802,"update":7,"cover":3803,"tags":3804,"categories":3809,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002F2021\u002Fhttp-canary-ca","posts\u002F2021\u002Fhttp-canary-ca","解决部分安卓11HttpCanary无法安装证书及其他诸多问题","本文分享安卓11下HttpCanary证书安装失败等问题的解决方法，需root或虚拟机。MIUI系统点击安装根证书无反应时，将指定缓存路径的HttpCanary.pem复制为HttpCanary.jks并重启应用，再以root权限安装到系统；无效则先导出带.0证书再安装。抓https失败或提示证书不可信，可安装Xposed框架和JustTrustMe插件关闭SSL认证。资源可从酷安或应用商店获取，免费版与付费版主要区别为插件支持。",506,"2021-01-16","\u002Fimages\u002F2021\u002Fhttp-canary-ca\u002Fhttp-canary-ca.png",[3805,3806,3807,3808],"Android","HttpCanary","抓包","问题",[3807],{"path":3811,"stem":3812,"title":3813,"description":3814,"wordCount":3815,"publish":3816,"update":7,"cover":3817,"tags":3818,"categories":3821,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002F2020\u002Fmysql-basics","posts\u002F2020\u002Fmysql-basics","MySQL 基础","本文介绍MySQL关系型数据库管理系统基础知识，包括数据库、数据库管理系统、数据库系统和数据库应用系统的概念，及其数据结构化、共享性高、冗余度低、独立性强和统一管理等特点；简述数据库的创建、查看、打开、修改和删除操作，以及数据表的创建、修改、删除和表数据的添加、更新、删除方法，并提及图形化管理工具。",1825,"2020-06-05","\u002Fimages\u002F2020\u002Fmysql-basics\u002Fmysql-basics.png",[3819,3820],"mysql","数据库",[3596],{"path":3823,"stem":3824,"title":3825,"description":3826,"wordCount":3827,"publish":3828,"update":7,"cover":3829,"tags":3830,"categories":3833,"series":7,"seriesOrder":7,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002F2020\u002Fpython-tkinter","posts\u002F2020\u002Fpython-tkinter","Python图形用户界面(Tkinter)","本文简介Python常用GUI库，重点说明Tkinter的标准控件、共同属性及pack、grid、place三种几何布局管理器。使用Tkinter需导入模块、创建控件、添加交互并编写函数、进入主事件循环。文中以简单登录界面为例，演示标签、输入框、按钮的放置，以及为按钮设置回调函数进行输入校验和登录提示。",965,"2020-05-25","\u002Fimages\u002F2020\u002Fpython-tkinter\u002Fpython-tkinter.jpg",[3831,3832],"Python","GUI",[3596],{"path":3835,"stem":3836,"title":3837,"description":3838,"wordCount":3839,"publish":3840,"update":3841,"cover":7,"tags":3842,"categories":3845,"series":3846,"seriesOrder":1064,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002Fmarkdown\u002Fcollapse","posts\u002F1.markdown\u002F05.collapse","在正文中使用折叠内容","本文说明正文中折叠内容的使用方法：折叠块适合放置补充说明、较长代码或可选阅读内容，标题始终可见，点击整行展开，各折叠块独立记录状态。支持默认收起，也可通过 open 属性设置初始展开。折叠内部可包含 Markdown、列表、代码、表格、图片等，目录或锚点访问内部标题会先展开所属折叠块。还支持嵌套折叠，外层使用三个冒号、内层使用两个冒号，内外层独立控制；访问嵌套目标可一次展开沿途两层。",428,"1970-01-01","2026-09-26",[3843,3844],"Markdown","MDC",[3846],"文章示例",{"path":3848,"stem":3849,"title":3850,"description":3851,"wordCount":3852,"publish":3840,"update":3659,"cover":7,"tags":3853,"categories":3855,"series":3846,"seriesOrder":873,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002Fmarkdown\u002Fvideo","posts\u002F1.markdown\u002F04.video","在文章中嵌入视频","本文介绍在文章与关于页中嵌入Bilibili和YouTube视频的MDC组件用法，无需API密钥或手写iframe。播放器按16:9自适应宽度，接近可视区域时加载，默认不自动播放。Bilibili可通过BV号或视频链接指定分P与开始时间，YouTube可通过11位视频ID或链接指定开始时间，标题由title参数设置。组件会过滤分享追踪参数与自动播放设置，无效参数仅显示提示，不影响正文。",597,[3843,3844,3854],"视频",[3846],{"path":3857,"stem":3858,"title":3859,"description":3860,"wordCount":3861,"publish":3840,"update":3862,"cover":7,"tags":3863,"categories":3865,"series":3846,"seriesOrder":851,"pin":3602,"wip":6,"theme":3609},"\u002Fposts\u002Fmarkdown\u002Fmarkdown-extended","posts\u002F1.markdown\u002F03.markdown-extended","Markdown 扩展功能","本文介绍Markdown扩展功能。已实现多风格提醒框，支持GitHub、Obsidian、VitePress、Docusaurus四种主题及折叠嵌套，可通过参数或全站配置设置；同时提供GitHub仓库卡片、Bilibili\u002FYouTube视频卡片与正文图片预览。图片画廊与作品集仍在计划中，当前采用标准图片语法配合图注和链接。GitHub仓库卡片在构建时获取公开仓库数据快照，不可用字段显示短横线。后续将实现图片画廊与作品集。",1822,"2026-09-27",[3843,3844,3864],"功能规划",[3846],{"path":3867,"stem":3868,"title":3869,"description":3870,"wordCount":3871,"publish":3840,"update":3862,"cover":7,"tags":3872,"categories":3874,"series":3846,"seriesOrder":845,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002Fmarkdown\u002Fmdc-tutorial","posts\u002F1.markdown\u002F02.mdc-tutorial","MDC 教程","本文介绍 MDC（Markdown Components）在 Nuxt Content 中的语法与用法，涵盖块级容器、行内属性、Props 传递、插槽、嵌套、绑定文章数据，以及代码块与代码组、图片预览、GitHub 仓库卡片、视频卡片、提醒框和文章自动提醒等已接入功能。文末说明自定义组件需实现并注册，并解答组件不显示、插槽误识别等常见问题。",2594,[3844,3873,3676],"Nuxt Content",[3846],{"path":3876,"stem":3877,"title":3878,"description":3879,"wordCount":3880,"publish":3840,"update":3671,"cover":7,"tags":3881,"categories":3883,"series":3846,"seriesOrder":216,"pin":3602,"wip":3610,"theme":3609},"\u002Fposts\u002Fmarkdown\u002Fmarkdown","posts\u002F1.markdown\u002F01.markdown","Markdown 教程","本文为 Markdown 教程，系统介绍常用语法：段落与换行、标题与目录生成、引用、无序\u002F有序\u002F任务列表、强调与行内代码、普通\u002F引用式\u002F自动链接、图片、代码块、表格、分隔线与转义，并说明本站 Nuxt Content 环境下文章文件位置、frontmatter 要求及后续扩展内容。",1449,[3843,3882],"写作",[3846],1791108779435]