文章目錄 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 { @Override public void service ( ServletRequest servletRequest
, ServletResponse servletResponse
) throws ServletException , IOException { System . out
. println ( "控制臺日志: 服務器被訪問了" ) ; servletResponse
. getWriter ( ) . print ( "hello servlet" ) ; } @Override public void init ( ServletConfig servletConfig
) throws ServletException { } @Override public ServletConfig getServletConfig ( ) { return null ; } @Override public String getServletInfo ( ) { return null ; } @Override public 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" ) ; } @Override public void init ( ServletConfig servletConfig
) throws ServletException { System . out
. println ( "init" ) ; } @Override public void service ( ServletRequest servletRequest
, ServletResponse servletResponse
) throws ServletException , IOException { System . out
. println ( "service" ) ; } @Override public void destroy ( ) { System . out
. println ( "destroy" ) ; } @Override public ServletConfig getServletConfig ( ) { System . out
. println ( "getServletConfig" ) ; return null ; } @Override public 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> /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 {
@Override public void service ( ServletRequest servletRequest
, ServletResponse servletResponse
) throws ServletException , IOException { System . out
. println ( "goodServlet" ) ; HttpServletRequest request
= ( HttpServletRequest ) servletRequest
; HttpServletResponse response
= ( HttpServletResponse ) servletResponse
; 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
) ; } } private void doPost ( HttpServletRequest request
, HttpServletResponse response
) { } 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 { @Override protected void doPost ( HttpServletRequest req
, HttpServletResponse resp
) throws ServletException , IOException { doGet ( req
, resp
) ; } @Override protected 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 { @Override protected void doPost ( HttpServletRequest req
, HttpServletResponse resp
) throws ServletException , IOException { doGet ( req
, resp
) ; } @Override protected 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 { @Override protected void doPost ( javax. servlet. http. HttpServletRequest request
, javax. servlet. http. HttpServletResponse response
) throws javax. servlet. ServletException, java. io. IOException { doGet ( request
, response
) ; } @Override protected 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>
< body> < 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. * ;
@WebServlet ( urlPatterns
= "/MyServlet" )
public class MyServlet extends HttpServlet { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException {
String agent
= request
. getHeader ( "user-agent" ) ; String referer
= request
. getHeader ( "referer" ) ; System . out
. println ( agent
) ; System . out
. println ( referer
) ; HashMap < String , String > map
= new HashMap < > ( ) ; Iterator < String > it
= map
. keySet ( ) . iterator ( ) ; while ( it
. hasNext ( ) ) { String key
= it
. next ( ) ; String value
= map
. get ( key
) ; } Enumeration < String > it2
= request
. getHeaderNames ( ) ; while ( it2
. hasMoreElements ( ) ) { String name
= it2
. nextElement ( ) ; String value
= request
. getHeader ( name
) ; System . out
. println ( name
+ "->" + value
) ; } } private 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>
< 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 ;
@WebServlet ( urlPatterns
= "/ParamServlet" )
public class ParamServlet extends HttpServlet { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { request
. setCharacterEncoding ( "utf-8" ) ; doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException {
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
) ) ; Map < String , String [ ] > map
= request
. getParameterMap ( ) ;
Set < String > set
= map
. keySet ( ) ; for ( String key
: set
) { String [ ] value
= map
. get ( key
) ;
} }
}
如下選中的是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>
< body> 人事
< a href = " /ShiServlet?msg=有人來面試" > 發送郵件
</ a>
</ 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 { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { String msg
= request
. getParameter ( "msg" ) ; System . out
. println ( "shi:" + msg
) ; System . out
. println ( "shi:我現在沒空,叫周楠同學幫我面試" ) ; request
. setAttribute ( "extra" , "比我帥的不要~~" ) ;
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 { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { String msg
= request
. getParameter ( "msg" ) ; System . out
. println ( "zhou:" + msg
) ; Object extra
= request
. getAttribute ( "extra" ) ; System . out
. println ( "zhou:" + extra
) ; System . out
. println ( "周楠同學放下手機,難得做點事情: 面試" ) ; response
. getWriter ( ) . print ( "this boy is ok,about 3k~~" ) ; }
}
10.登陸案例(1):成功和失敗頁面相當于兩個模塊
File - New - Project - Java Enterprise。 如下想到Junit包失效。
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 ( ) ; public static JdbcTemplate getTemplate ( ) { JdbcTemplate template
= new JdbcTemplate ( ds
) ; return template
; }
}
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 { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { String username
= request
. getParameter ( "userName" ) ; String password
= request
. getParameter ( "password" ) ; String sql
= "select * from user where username = ? and password = ?" ; JdbcTemplate template
= JdbcUtil . getTemplate ( ) ; User user
= template
. queryForObject ( sql
, new BeanPropertyRowMapper < > ( User . class ) , username
, password
) ; if ( user
!= null ) { request
. getRequestDispatcher ( "/success.html" ) . forward ( request
, response
) ; } else { request
. getRequestDispatcher ( "/error.html" ) . forward ( request
, response
) ; } }
}
package com. itheima. bean ; public class User { private Integer id
; private String username
; private String password
; @Override public 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>
< 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 { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { System . out
. println ( "服務器被訪問了" ) ;
response
. setStatus ( 302 ) ;
}
}
請求報文分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 { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { System . out
. println ( "服務器被訪問了" ) ;
response
. setContentType ( "text/html;charset=utf-8" ) ; 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 { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { request
. setCharacterEncoding ( "utf-8" ) ; doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { String msg
= request
. getParameter ( "msg" ) ; System . out
. println ( "shi:" + msg
) ; response
. setStatus ( 302 ) ; response
. setHeader ( "location" , "/ZhouServlet?msg=xx" ) ; }
}
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 { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { String msg
= request
. getParameter ( "msg" ) ; System . out
. println ( "zhou:" + msg
) ; System . out
. println ( "這個哥們還不錯" ) ; 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>
< body> < 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 { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { String file
= request
. getParameter ( "file" ) ; response
. setHeader ( "content-disposition" , "attachment;filename=x" + file
) ;
ServletContext servletContext
= request
. getServletContext ( ) ; 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),重定向,文件下载) 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。