日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

【Java12】tomcatservlet(nginx,web.xml,生命周期,适配器优化),requestresponse(请求转发,登陆案例(1),重定向,文件下载)

發布時間:2024/4/24 java 478 豆豆

文章目錄

  • 1.nginx的conf文件:以前網絡編程中B/S架構中服務器是用socket寫,用文件輸入流讀一個文件,讀到后socket通過outputstream寫出去,這些過程有了nginx后再也不用寫
  • 2.nginx反向代理與負載均衡:nginx是被廣泛使用的網頁服務器,在www.163.com的F12的Network中Headers中有server:nginx,使用nginx首當其沖,做反向代理,將請求分發到公司的多臺服務器上
    • 2.1 location匹配方式:location / 默認匹配所有請求,相當于第四優先級(最弱)
    • 2.2 反向代理寫法:http80,
    • 2.3 負載均衡寫法:基于反向代理
  • 3.服務器:軟件為tomcat或nginx,程序為servlet
  • 4.servlet:多態,web.xml
  • 5.servlet生命周期:LifecycleServlet
  • 6.servlet優化:GenericServelt/HttpServelt
  • 7.http協議和抓包:枚舉Enumeration,request.getHeaderNames()
  • 8.request對象:.getParameterMap(),post請求中文參數亂碼
  • 9.請求轉發:jrss,request.setAttribute()
  • 10.登陸案例(1):成功和失敗頁面相當于兩個模塊
  • 11.response對象:text/html,重定向(.setStatus,.setHeader)
  • 12.文件下載:request/response


1.nginx的conf文件:以前網絡編程中B/S架構中服務器是用socket寫,用文件輸入流讀一個文件,讀到后socket通過outputstream寫出去,這些過程有了nginx后再也不用寫

nginx軟件鏈接:https://pan.baidu.com/s/1zvF2irI6OenDKVfvSIOZmg ,提取碼:gsn9。

如果http協議是80端口的話,80端口會被隱藏,本機瀏覽器輸入http://localhost:80啟動服務端顯示如下,hello nginx是E\my81\index.html里內容。本機ipconfig顯示192.168.33.71。上面紅框瀏覽器(客戶端)是別人的電腦【局域網下同一網段】,上面兩個大框是服務端,瀏覽器和服務器三要素對應。

nginx作用:1.反向代理:s被代理1個公網ip,但有n臺s對外服務。
2.負載均衡:基于反向代理。
3.正向代理:我們電腦接入VPN 后,我們對外IP地址就會變成VPN服務器的公網IP。
4.動靜分離:網頁f12顯示js,css,img屬靜態數據。

線程通訊:volatile關鍵字,wait(),notify()
線程安全:synchronized關鍵字
計算密集型:進行(多核)
io密集型:線/協程(只1個核在做,占資源輕,io等待時間拿來用)

2.nginx反向代理與負載均衡:nginx是被廣泛使用的網頁服務器,在www.163.com的F12的Network中Headers中有server:nginx,使用nginx首當其沖,做反向代理,將請求分發到公司的多臺服務器上

原生nginx沒有集成很多插件,使用不方便。推薦使用openresty(在nginx基礎上集成了很多lua寫的插件),官網下載openresty后解壓后進一級目錄輸入nginx.exe回車運行服務端,瀏覽器輸入localhost默認:80端口。修改conf目錄下nginx.conf文件,刪除注釋。50x.html是錯誤頁面,暫時不用。


如下還是在nginx.conf文件里,stream類型執行下載,echo是插件。


2.1 location匹配方式:location / 默認匹配所有請求,相當于第四優先級(最弱)

1.如下最強級別=。



2.如下優先級第二,^~以什么開頭。如下/是路徑,不是轉義符。



3.如下優先級第三,正則表達式~。\w匹配數字、字母、下劃線,轉義字符\可以轉義很多字符,比如\n表示換行,\t表示制表符,字符\本身也要轉義,所以\\表示的字符就是\。如下/是路徑。



如下同優先級的,按匹配程度較高的先匹配。


同優先級并且匹配程度相同的話,寫在上面的優先執行。

2.2 反向代理寫法:http80,

如下是其他服務器,記住192…:80是it works頁面。



如下localhost先到本機127.0.0.0,再轉到192上面的這個服務器。

如下是apach返回的Not Found返回的信息,192…:80/a路徑沒有,不是nginx返回的信息,因為已經把請求轉到192…

1.默認拼接。


如下其實轉到了192...:80/a。

2.如下轉到192...:80/,兩個/省去后一個字母。

2.3 負載均衡寫法:基于反向代理


兩個ip+端口根據權重切換。

3.服務器:軟件為tomcat或nginx,程序為servlet

Web(World Wide Web)即全球廣域網,也稱為萬維網。

nginx不支持java規范,tomcat支持。tomcat8:https://tomcat.apache.org/download-80.cgi。免安裝,解壓即可用:鏈接:https://pan.baidu.com/s/1UJM9kbIHGIXkNXlYLpcoGw ,提取碼:g610。dos系統識別文件后綴名不能超過3位(先有dos后有windows),所以.htm。8080一般是用來連接代理的(8080不能省,只有80才能省)。 只有index.html是默認的,不用加在最后,localhost:8080/a.html。

如下javaee新建項目,apache-tomcat8…是前面tomcat軟件解壓路徑。如下不需要自己開啟tomcat,idea配置自動開啟。


如下New和上面一樣,關聯tomcat軟件解壓路徑。

如下將web文件夾當成前端static web項目,web文件夾里都可以訪問,除了web-info無法訪問(如【Mysql3】最后一節,-info文件夾放jar包),Toolbar工具欄。


如下是點烏龜運行后,瀏覽器自動打開的原理。改變路徑 / 寫法。

如上若還是不會默認打開谷歌,需要File - Settings - Tools - Web Browsers。

4.servlet:多態,web.xml


如下選中src右擊new - java class,name為com.itheima01.servlet.MyServlet,還有一件事配置web.xml如上圖所示。

package com.itheima01.servlet; import javax.servlet.*; import java.io.IOException;public class MyServlet implements Servlet { //javax.servlet.Servlet (x指extend,如果沒有提示,則上面tomcat項目配置失敗) //沒有main函數,右擊run不了,點烏龜@Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("控制臺日志: 服務器被訪問了"); servletResponse.getWriter().print("hello servlet"); //在網頁上打印(英文,中文會亂碼)} @Overridepublic void init(ServletConfig servletConfig) throws ServletException {}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic String getServletInfo() {return null;}@Overridepublic void destroy() {} }

如下點擊idea中烏龜,自動打開網頁,改變/my路徑。


tomcat+servlet原理(4步):以前解析xml文件(web.xml)用dom4j,將xml先讀到內存里在進行解析。第4步:mapping映射后,tomcat(中介即代理默認端口8080)底層會進行反射,當前類com.itheima01.servlet.MyServlet肯定是Servlet接口的implements實現類,可以向上轉型,父類Servlet調用方法執行子類重新的方法。

為什么tomcat底層用反射?tomcat底層設計不能和MyServlet耦合,只有全限定名和MyServlet有關(自己設定的),通用性。tomcat像管家中介(用戶,tomcat軟件【中介】,jdk的Servlet)在第3步等客人,第4步客人來了找my,tomcat根據客人請求找到my的住址com....MyServlet,把my叫醒進行service辦公。

如上在web.xml中,MyServlet01可以隨便命名但要上下一致,my是資源位置,/my(因為在當前項目,http…8080可以省略,url)和com…MyServlet(class,全限定名就是全類名就是包名加類名)對應關系。

5.servlet生命周期:LifecycleServlet

package com.itheima02.life; import javax.servlet.*; import java.io.IOException;public class LifecycleServlet implements Servlet {public LifecycleServlet(){ //不寫也可以,一個類默認有 空參構造System.out.println("LifecycleServlet");} //如下生命周期 5個重寫 @Overridepublic void init(ServletConfig servletConfig) throws ServletException {System.out.println("init");} @Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("service");} @Overridepublic void destroy() {System.out.println("destroy");}//11111111111111111111111111111111111111111111111111111111以下沒用@Overridepublic ServletConfig getServletConfig() {System.out.println("getServletConfig");return null;} @Overridepublic String getServletInfo() {System.out.println("getServletInfo");return null;} }

//web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"version="3.1"><servlet><servlet-name>MyServlet01</servlet-name><servlet-class>com.itheima01.servlet.MyServlet</servlet-class></servlet><servlet-mapping><servlet-name>MyServlet01</servlet-name><!-- <url-pattern>http://localhost:8080/my</url-pattern>--><url-pattern>/my</url-pattern></servlet-mapping><servlet><servlet-name>LifecycleServlet</servlet-name><servlet-class>com.itheima02.life.LifecycleServlet</servlet-class></servlet><servlet-mapping><servlet-name>LifecycleServlet</servlet-name><url-pattern>/life</url-pattern></servlet-mapping><servlet><servlet-name>GoodServlet</servlet-name><servlet-class>com.itheima03.good.GoodServlet</servlet-class></servlet><servlet-mapping><servlet-name>GoodServlet</servlet-name><url-pattern>/good</url-pattern></servlet-mapping><servlet><servlet-name>BetterServlet</servlet-name><servlet-class>com.itheima03.good.BetterServlet</servlet-class></servlet><servlet-mapping><servlet-name>BetterServlet</servlet-name><url-pattern>/better</url-pattern></servlet-mapping> </web-app>


如下默認調用空參構造創建實例(第一行)。

6.servlet優化:GenericServelt/HttpServelt

只留一個接口叫適配器設計模式。將service方法根據不同請求方式分化出兩個不同方法。

package com.itheima03.good; import javax.servlet.GenericServlet; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;public class GoodServlet extends GenericServlet { //ServletRequest : 請求(前端發送服務器的數據), 兼容大部分協議(包括http), 子接口: HttpServletRequest@Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { //這個service方法將下面3個方法(service2,doPost,doGet)都調用了System.out.println("goodServlet"); //沒有ServletRequest.getgetMethod() //因為不是所有的協議都有請求方式,所以要向下轉型成httpHttpServletRequest request = (HttpServletRequest) servletRequest; //協議: 必須是httpHttpServletResponse response = (HttpServletResponse) servletResponse;//request.getMethod(); //http協議有請求方式service2(request,response); }private void service2(HttpServletRequest request, HttpServletResponse response) { String method = request.getMethod(); //請求方式if("GET".equals(method)){doGet(request,response);}else if("POST".equals(method)){doPost(request,response);}}//以后再寫Servlet只要繼承GoodServlet(GoodServlet可以改名為HttpServlet),重寫doPost和doGet就行 //如下相當于 http協議中post請求方式的service方法,HttpServletRequest類比原ServletRequest類好用private void doPost(HttpServletRequest request, HttpServletResponse response) {}//如下相當于 http協議中get請求方式的service方法private void doGet(HttpServletRequest request, HttpServletResponse response) { } }

瀏覽器:localhost:8080/good,網頁無顯示,控制臺打印goodServlet。

package com.itheima03.good; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;public class BetterServlet extends HttpServlet { //sun公司已經封裝HttpServlet@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req,resp);}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {} }

如上解決了前二個問題。如下解決第三個問題,不用配置web.xml。

package com.itheima03.good; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;@WebServlet(urlPatterns = "/best") public class BestServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req,resp); }@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("被訪問了");} }



如下把上面BestServlet類設置為模板,使用:選中包(包下)-new-servlet。

如上模板如下:

#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end #parse("File Header.java")@javax.servlet.annotation.WebServlet(urlPatterns = "/${Entity_Name}") public class ${Class_Name} extends javax.servlet.http.HttpServlet {@Overrideprotected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {doGet(request,response);}@Overrideprotected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {} }

7.http協議和抓包:枚舉Enumeration,request.getHeaderNames()

http的request對象:由tomcat創建,并且里面數據由tomcat set進去,我們只需要get出來。

File-New-Project-Java Enterprise。

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head><!--111111111111111111111111111111111111111111111111111111111111111111111111111--> <body><!--http協議兩種主要請求協議1. get (默認, 只要看到可以發起請求,但是沒看到請求方式設置)2. post (需要收到設置)--><h1>get請求方式</h1><form action="http://localhost:8080/MyServlet" method="get"><input type="text" placeholder="請輸入用戶名" name="name"> <br><input type="text" placeholder="請輸入密碼" name="pwd"> <br><input type="submit"></form><h1>post請求方式</h1> <form action="/MyServlet" method="post"> <!-- 本服務器前面可以省略 --><input type="text" placeholder="請輸入用戶名" name="name"> <br><input type="text" placeholder="請輸入密碼" name="pwd"> <br><input type="submit"></form> </body> </html>

如上html文件建在web文件夾路徑下,如下創建的是servlet的模板。

package com.itheima01.http; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.*; /*** http://192.168.139.236:8080/MyServlet 或 MyServlet換成..請求報文.html** #request對象核心功能: 獲取前端的請求數據如下:* 1. 請求行* 請求方式 / 請求url / 協議* 方法:1. String getMethod() : 獲取請求方式的類型2. StringBuffer getRequestURL() : 獲取客戶端發出請求完整URL3. String getProtocol(): 獲取當前協議的名稱和版本 4. String getRemoteAddr() : 獲取IP地址** 2. 請求頭* 1. 獲取指定請求頭的信息: value = request.getHeader("name");2. 獲取所有的請求頭的name值:request.getHeaderNames();** 3. 請求參數* tomcat: 會根據不同的請求方式(自動get請求從url獲取參數,post請求從請求體里獲取參數),從不同的地方獲取參數并設置到request對象,這樣不需要知道過程,只有結果。**/ @WebServlet(urlPatterns = "/MyServlet") public class MyServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);} @Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //doGet方法相當于get請求方式下的service方法 // System.out.println("服務器被訪問了"); //idea下面顯示 // response.getWriter().print("hello http"); //在網頁上輸出// line(request); //請求行String agent = request.getHeader("user-agent"); //出bug執行的//用戶訪問我的網站突然崩潰,實際已獲取了用戶環境,在服務器所在地方可以模擬用戶String referer = request.getHeader("referer"); //防盜鏈System.out.println(agent);System.out.println(referer);//11111111111111111111111111111111111111111111111111111111111111111111111111111111HashMap<String, String> map = new HashMap<>();Iterator<String> it = map.keySet().iterator();while(it.hasNext()){String key = it.next();String value = map.get(key);} //如下枚舉Enumeration相當于上面迭代器 Enumeration<String> it2 = request.getHeaderNames(); //=號右邊等價于map.keySet().iterator()while(it2.hasMoreElements()){String name = it2.nextElement();String value = request.getHeader(name);System.out.println(name + "->" + value);}}//11111111111111111111111111111111111111111111111111111111111111111111111111111111private void line(HttpServletRequest request) { //請求行,抓包String method = request.getMethod();StringBuffer url = request.getRequestURL();String protocol = request.getProtocol();String remoteAddr = request.getRemoteAddr(); System.out.println(method);System.out.println(url.toString());System.out.println(protocol); System.out.println("訪問者的ip:" + remoteAddr);} }


如上瀏覽器網址中…報文.html是Referer中的上一次訪問頁面,因為已跳轉到如下下個頁面。

如下請求行中的請求url省略了如上的http://localhost:8080。cookie是瀏覽器緩存的一種。get請求中最后一行不是請求體,是谷歌瀏覽器工具抓包進行的參數強調渲染。

8.request對象:.getParameterMap(),post請求中文參數亂碼

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head><!--111111111111111111111111111111111111111111111111111111111111111111111111111--> <body><h1>get請求</h1><form action="/ParamServlet" method="get">用戶名: <input type="text" name="name"> <br>密碼: <input type="password" name="pwd"> <br>性別: <input type="radio" name="gender" value="boy"><input type="radio" name="gender" value="girl"><br>愛好:<input type="checkbox" name="hobby" value="smoke"> 抽煙<input type="checkbox" name="hobby" value="drink"> 喝酒<input type="checkbox" name="hobby" value="firehead"> 燙頭 <br><input type="submit"></form><h1>post請求</h1><form action="/ParamServlet" method="post">用戶名: <input type="text" name="name"> <br>密碼: <input type="password" name="pwd"> <br>性別: <input type="radio" name="gender" value="boy"><input type="radio" name="gender" value="girl"> <br>愛好:<input type="checkbox" name="hobby" value="smoke"> 抽煙<input type="checkbox" name="hobby" value="drink"> 喝酒<input type="checkbox" name="hobby" value="firehead"> 燙頭 <br><input type="submit"></form> </body> </html> package com.itheima02.param; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Arrays; import java.util.Map; import java.util.Set; /**請求參數: parameter ?n1=v1&n2=v2...方法:1. 根據name值獲取value值: String value = request.getParameter(name);2. 根據name值獲取多個value值:String[] value = request.getParameterValues(name);3. 獲取所有的請求參數,封裝到map中:Map<String, String[]> map = request.getParameterMap();name為String,value為String[]問題: post請求中文參數亂碼原因: 編解碼使用的字符集不一樣編碼: 瀏覽器 ( utf-8 )解碼: 服務器 (tomcat + servlet)ISO-8859-1 utf-8解決: tomcat的編碼表改成utf-81. 永久2. 臨時 (選用) request.setCharacterEncoding("utf-8"); 注意: 必須放在獲取參數之前【get請求 tomcat8以上被優化 不亂碼(post請求參數在請求體中,走io流)】**/ @WebServlet(urlPatterns = "/ParamServlet") public class ParamServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("utf-8");doGet(request, response);} @Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // request.setCharacterEncoding("utf-8");String name = request.getParameter("name");String pwd = request.getParameter("pwd");String gender = request.getParameter("gender");String[] hobbies = request.getParameterValues("hobby"); //復選框可重復System.out.println(name+"," + pwd + "," + gender + "," + Arrays.toString(hobbies));//11111111111111111111111111111111111111111111111111111111111111111111111111111111111Map<String, String[]> map = request.getParameterMap(); // System.out.println(map); //這個map沒有重寫tostring方法Set<String> set = map.keySet();for (String key : set) {String[] value = map.get(key); //value數組沒有重寫tostring方法,不能 // System.out.println(key + "=" + Arrays.toString(value));}} }


如下選中的是map遍歷出來的結果和下面第一行一樣。

9.請求轉發:jrss,request.setAttribute()

request表面上獲取請求數據,還有快遞員身份。

如下forward方法中request是郵件及內容,response是回應權限。A模塊指MyServlet,B模塊指ZhouServlet。一次請求鏈如下只有一去一回。

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head><!--111111111111111111111111111111111111111111111111111111111111111111111111111--> <body> 人事<!--<a href="http://localhost:8080/ShiServlet?msg=有人來面試">發送郵件</a>--><a href="/ShiServlet?msg=有人來面試">發送郵件</a> <!--點發送郵件后,地址欄修改為/Shi..,沒寫就是get請求--> </body> </html> package com.itheima03.transfer; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;@WebServlet(urlPatterns = "/ShiServlet") public class ShiServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1. 接收請求String msg = request.getParameter("msg");System.out.println("shi:" + msg);System.out.println("shi:我現在沒空,叫周楠同學幫我面試"); request.setAttribute("extra","比我帥的不要~~"); //添加備注,這行注掉不寫,ZhouServlet寫request.getAttribute會得到null//2. 請求轉發 // RequestDispatcher dispatcher = request.getRequestDispatcher("/ZhouServlet"); //比作郵件服務器或快遞員 // dispatcher.forward(request,response); //快遞員發貨request.getRequestDispatcher("/ZhouServlet").forward(request,response); //這行等價上面兩行} } package com.itheima03.transfer; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;@WebServlet(urlPatterns = "/ZhouServlet") public class ZhouServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //request和response兩個參數由A模塊傳遞來//1. 接收請求String msg = request.getParameter("msg");System.out.println("zhou:" + msg); Object extra = request.getAttribute("extra");System.out.println("zhou:" + extra);//2. 業務處理System.out.println("周楠同學放下手機,難得做點事情: 面試");//3. 響應數據response.getWriter().print("this boy is ok,about 3k~~");} }


10.登陸案例(1):成功和失敗頁面相當于兩個模塊


File - New - Project - Java Enterprise。

如下想到Junit包失效。

//JdbcUtil.java package com.itheima.utils; import com.mchange.v2.c3p0.ComboPooledDataSource; import org.springframework.jdbc.core.JdbcTemplate;public class JdbcUtil {private static ComboPooledDataSource ds = new ComboPooledDataSource(); //先new一個連接池public static JdbcTemplate getTemplate(){JdbcTemplate template = new JdbcTemplate(ds); //再new一個Template,把連接池交給給JdbcTemplate管理return template;} } //LoginServlet.java package com.itheima.login; import com.itheima.bean.User; import com.itheima.utils.JdbcUtil; import com.mchange.v2.c3p0.ComboPooledDataSource; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;@WebServlet(urlPatterns = "/LoginServlet") public class LoginServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);} @Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.接收請求String username = request.getParameter("userName"); //userName區分大小寫String password = request.getParameter("password");//2.業務處理 //如下只有兩種結果: 返回一行(一行是一個對象) 或 返回nullString sql = "select * from user where username = ? and password = ?";JdbcTemplate template = JdbcUtil.getTemplate(); //一定要封裝成JdbcUtil,不然new ComboPooledDataSource,每訪問一次就會創建一次連接池,內存崩。User user = template.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), username, password); //把如下注掉,用如上一行,即查不到數據,拋出異常,不抓異常,這樣會密碼錯誤直接跳轉500(500服務器錯誤,404地址輸錯),而不是error.html /*User user = null;try {user = template.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), username, password);} catch (DataAccessException e) {e.printStackTrace();}*/if(user != null){request.getRequestDispatcher("/success.html").forward(request,response); //登錄成功}else{request.getRequestDispatcher("/error.html").forward(request,response);}} } // User.java package com.itheima.bean;public class User {private Integer id; //和表字段一致private String username;private String password;@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +'}';}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;} } //login.html <!DOCTYPE html> <html lang="en"> <head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>登錄頁面</title><link href="css/bootstrap.min.css" rel="stylesheet"><link href="css/login.css" rel="stylesheet"><script src="js/jquery.js"></script><script src="js/bootstrap.js"></script> </head><!--1111111111111111111111111111111111111111111111111111111111111111111111111--> <body><div class="container text-center"><form class="form-signin" action="/LoginServlet"><h2 class="form-signin-heading">登錄頁面</h2><input type="text" name="userName" class="form-control" placeholder="用戶名" required autofocus><input type="password" name="password" class="form-control" placeholder="密碼" required><button class="btn btn-lg btn-primary btn-block" type="submit">登錄</button></form></div> </body> </html>

11.response對象:text/html,重定向(.setStatus,.setHeader)



package com.itheima01.http; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter;@WebServlet(urlPatterns = "/MyServlet") public class MyServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);} @Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("服務器被訪問了"); // int i = 1/0; //服務器崩了出異常,沒有try catch,狀態碼500 response.setStatus(302); //狀態碼設置,只有302需要我們手動設置 // response.setStatus(404); //這樣設置狀態碼是404,servlet優先級高于tomcat,但是訪問服務端依舊成功 // response.getWriter().print("hello response"); //前端網頁打印出//響應體輸出流設置,字節輸出流(寫) //待會下載文件案例中使用 // ServletOutputStream os = response.getOutputStream(); // os.write("abc".getBytes()); //01_響應報文.html中點擊“訪問MyServlet”超鏈接跳轉到顯示“abc”的新頁面//方便輸出字符數據,不用轉換為字節了,print和write一樣 // PrintWriter writer = response.getWriter(); // response.getWriter().print("xx"); } }

請求報文分get和post兩種,在響應報文里看到了非servlet設置的內容,那就是tomcat設置的。將前端改為href=“/MyServlet123”,則會出現404。servlet關了,tomcat自動設置為500狀態碼。

如下體中hello response長度一共為Content-Lenth為14,頭中GMT格林位置需+8小時為東八區北京時間。如下行和頭都是tomcat默認自動設置,體是我們servlet手動設置。想修改狀態碼,需要在servlet(對我們暴露的小程序)中修改。


如下響應頭分四種(藍色字),如下簡易API等同上行。


如下點擊后,5秒后跳轉到百度。

package com.itheima02.header; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;@WebServlet(urlPatterns = "/RefreshAndTypeServlet") public class RefreshAndTypeServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);} @Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("服務器被訪問了"); // response.setHeader("refresh","5;http://www.baidu.com");//11111111111111111111111111111111111111111111111111111111111111111111111111111111111111/** 問題: 響應體中文亂碼 。request.setCharacterEncoding("utf-8");* 原因: 編碼: 服務器(utf-8 : servlet:因為在servlet里寫的"哈哈",idea右下角顯示utf-8)* 解碼: 瀏覽器(iso-8859-1 : tomcat默認設置如下行) // response.setHeader("content-type","text/plain"); //在Response Headers(瀏覽器F12看出)中多出tomcat默認設置(不加這行不顯示):Content-Type: text/plain;charset=ISO-8859-1* 解決: servlet中手動設置覆蓋tomcat默認設置** windows系統: txt html jpg avi ...* 早期MIMEType : text/plain text/html image/jpeg (tomcat解壓包中web.xml中有對應說明)*/ // response.setHeader("content-type","text/plain;charset=utf-8"); //新頁面顯示 <h1>哈哈</h1> // response.setHeader("content-type","text/html;charset=utf-8"); //點擊網頁上RefreshAnd..跳轉新頁面顯示 哈哈response.setContentType("text/html;charset=utf-8"); //setContentType是簡易API,同上一行response.getWriter().print("<h1>哈哈</h1>"); } }

因為重定向不是一次請求鏈,所以超過域對象,不能用request傳遞數據。ZhouServlet收不到人事的msg,能收到ShiServlet的response.setHeader(…/ZhouServlet?msg=…)。

package com.itheima03.redirect; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;@WebServlet(urlPatterns = "/ShiServlet") public class ShiServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("utf-8");doGet(request, response);} @Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1. 接收請求String msg = request.getParameter("msg");System.out.println("shi:" + msg);//2. 重定向response.setStatus(302);response.setHeader("location","/ZhouServlet?msg=xx"); //不寫?msg=xx,ZhouServlet就收不到msg,寫了就能收到} } package com.itheima03.redirect; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;@WebServlet(urlPatterns = "/ZhouServlet") public class ZhouServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);} @Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1. 接收請求String msg = request.getParameter("msg");System.out.println("zhou:" + msg);//2. 業務處理System.out.println("這個哥們還不錯");//3. 響應數據response.setContentType("text/html;charset=utf-8");response.getWriter().print("這個哥們還可以,大約3K");} }




如下瀏覽器F12,第二行沒有帶參數,拿不到msg。

前面登陸成功請求轉發到成功.html頁面,失敗.html…。用請求轉發不合適,因為沒有傳遞數據,應該用重定向。請求轉發一次請求,地址指向第一次訪問位置如下(網址閱讀性太差,實際頁面應該為localhost:8080/success.html)。

如下紅框用重定向,登陸失敗邏輯錯誤,之后再改。

如下重定向,第一次請求收到302。

12.文件下載:request/response

首先服務器要有文件,在網絡編程做過文件上傳。在servlet里寫代碼覆蓋tomcat默認設置。

//02文件下載.html <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head><!--1111111111111111111111111111111111111111111111111111111111111111111111111--> <body><!--方案A:瀏覽器打開此網頁點擊后自動下載的話,說明tomcat默認設置,因為servlet一個字沒寫--><!-- <a href="dir/1.zip">1.zip</a> <br> <a href="dir/2.exe">2.exe</a> <br><a href="dir/3.txt">3.txt</a> <br><a href="dir/4.jpg">4.jpg</a> <br>--><a href="/DownloadServlet?file=1.zip">1.zip</a> <br><a href="/DownloadServlet?file=2.exe">2.exe</a> <br><a href="/DownloadServlet?file=3.txt">3.txt</a> <br><a href="/DownloadServlet?file=4.jpg">4.jpg</a> <br> </body> </html> package com.itheima04.down; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileInputStream; import java.io.IOException;@WebServlet(urlPatterns = "/DownloadServlet") public class DownloadServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String file = request.getParameter("file"); // 拿到1.zip之類//1. 告訴瀏覽器如何處理文件response.setHeader("content-disposition","attachment;filename=x" + file); //下載以x命名//2. 讀取服務器本地文件,寫出瀏覽器。絕對路徑 等會要改成 相對路徑//以前java工程: web/dir/文件(相對路徑,里面是1.zip,2.exe等需下載的文件)//web工程: main方法在tomcat里,造成和java工程相對路徑不一樣 // FileInputStream fis = new FileInputStream("E:/mywork/IdeaProjects/class897/web-day03/web/dir/" + file);//ServletContext servletContext1 = this.getServletContext(); //this是當前的servlet對象:servlet.getServletContext() //同下一行ServletContext servletContext = request.getServletContext(); //request小域對象可獲取ServletContext大域對象 String realPath = servletContext.getRealPath("dir/" + file); //絕對路徑換成相對路徑 FileInputStream fis = new FileInputStream(realPath);ServletOutputStream os = response.getOutputStream();int length;byte[] buffer = new byte[1024];while((length = fis.read(buffer)) != -1){os.write(buffer,0,length);}fis.close();os.close();System.out.println("文件下載完畢");} }

響應體交給瀏覽器,瀏覽器自動下載。

linux沒有盤符,所以不能用絕對路徑,不好部署。如下artifacts指整個項目,運行的是如下藍字編譯的內容(黃色文件夾),只要獲得web_war_exploded文件夾就能得到其他文件相對路徑。用serlvetContext = web_war_exploded文件夾路徑(exploded部署意思,如下紅線),如下右邊servletContext是生命周期最長的域對象,所以可以將數據傳到服務器任何地方。

request除了作為域對象還有本職工作即獲取請求數據,servletContext很像連接池(連接池一個就夠),服務器沒關,連接池不消毀。servletContext生命周期和web應用一樣長,所以也叫application應用,環境參數如相對路徑。request和session兩個域對象用的最多,pageContext太短,servletContext太長。重定向不能通過request傳遞數據,可以用servletContext傳遞數據,但是一般也不這么做,servletContext占用內存大。

上圖灰色WEB-INF文件夾中添加lib文件夾里放druid-1.0.9.jar包并右擊add as library【Mysql3】,點烏龜運行tomcat后,會生成黃色lib文件夾。黃色classes文件夾里代碼不能直接訪問,需用web.xml或用注解建立映射關系訪問:WEB-INF下是瀏覽器無法直接訪問,通過建立映射,url訪問,由tomcat訪問。

熱更新不做編譯,新增類必須停下來。


與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的【Java12】tomcatservlet(nginx,web.xml,生命周期,适配器优化),requestresponse(请求转发,登陆案例(1),重定向,文件下载)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。