一. eclipse創(chuàng)建web工程
- 新建工程
- 添加flod文件夾坏瞄,命名WEB-INF
- WEB-INF中添加classes文件夾、lib文件夾和web.xml文件
- 修改字節(jié)碼文件輸出路徑為WEB-INF/classes阶捆。項(xiàng)目-屬性-Java Build Path-source
(一)intellij idea 創(chuàng)建web工程
- new project-java-java EE-webapplication,填寫項(xiàng)目名
- 右鍵項(xiàng)目名胁住,open module setting- sources選擇WEB-INF 快捷鍵commadn+N 新建文件夾classes和lib趁猴;Paths輸出路徑為新建的classes;dependencies “+” -1 jar-lib文件夾彪见,“+”-2library 選擇tomacat包
- tomcat配置儡司。 run-edit configurations- ‘+’-選tomcat-local,
server標(biāo)簽頁(yè)第一次需要導(dǎo)入tomcat路徑,之后不需要余指。Deployment-"+" 添加工件捕犬,application context可以添加上下文名稱,回到server標(biāo)簽頁(yè)酵镜,on "update" action和 on frame deactivation 都選update classes and resource,
有時(shí)端口被占用碉碉,改下2個(gè)端口號(hào)
二. HTTP協(xié)議
- 規(guī)定數(shù)據(jù)傳輸格式。
- HTTP1.0規(guī)范淮韭,多次請(qǐng)求資源垢粮,需建立多次連接,發(fā)送多次請(qǐng)求和接收多次響應(yīng)靠粪,關(guān)閉多次連接蜡吧。
- HTTP1.1規(guī)范毫蚓,一次連接可以多次請(qǐng)求和響應(yīng),一次關(guān)閉昔善。
- HTTP消息結(jié)構(gòu):一個(gè)請(qǐng)求行元潘、若干請(qǐng)求頭和實(shí)體內(nèi)容,一些請(qǐng)求頭和實(shí)體內(nèi)容可選君仆,后2者之間用空行隔開(kāi)
<1>Accept:mime類型
<2>Accept-Charset:支持的字符集
<3>Accept-Encoding:編碼方式
<4>Accept-Language:支持的語(yǔ)言
<5>Referer:當(dāng)前頁(yè)面由哪個(gè)頁(yè)面訪問(wèn)過(guò)來(lái)
<6>Content-Type:請(qǐng)求正文的mime類型
<xxx>
三. Helloservlet
- 右鍵項(xiàng)目中src文件夾翩概,新建包
- 右鍵新建的包,新建java類文件
- 新建的公共類繼承HttpServlet 報(bào)錯(cuò)返咱,根據(jù)提示導(dǎo)入包钥庇,再導(dǎo)入接口的抽象方法
四. Servlet請(qǐng)求流程
- 瀏覽器發(fā)送請(qǐng)求,地址鏈接http://主機(jī)ip/上下文路徑/資源名稱
- 服務(wù)器解析洛姑,從server.xml中找到上下文路徑匹配的Path上沐,當(dāng)前項(xiàng)目根路徑下/WEB-INF 找到web.xml皮服,找到和資源名稱匹配的Servlet類的全限定名稱楞艾,有個(gè)映射過(guò)程。
- 反射機(jī)制創(chuàng)建Servlet對(duì)象
Servlet obj = Class.forName("全限定類名").newInstance();
- 創(chuàng)建ServletConfig對(duì)象龄广,使用Servlet對(duì)象調(diào)用init方法硫眯,
obj.init(config);
- 創(chuàng)建req和resp對(duì)象,并調(diào)用service方法择同,
obj.service(req,resp);
- 在service方法中給瀏覽器做響應(yīng)
特點(diǎn):非第一次請(qǐng)求過(guò)程两入,步驟1,2后敲才,http無(wú)狀態(tài)裹纳,但是有緩存,故可從Servlet實(shí)例池中取出Servlet對(duì)象紧武,5剃氧,6
五. 表單輸入,后臺(tái)亂碼問(wèn)題
首選解決方法:在Run-Edit configurations-Startup/Connection 中Run中添加environment variables
JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8.
- 表單方法為post時(shí)阻星,可以在獲取參數(shù)之前設(shè)置字符編碼格式
req.setCharacterEncoding("UTF-8");
但是必須在獲取所有參數(shù)中任意一個(gè)參數(shù)的語(yǔ)句之前
- 表單方法為get時(shí)朋鞍,目前測(cè)試沒(méi)問(wèn)題,有問(wèn)題的話是因?yàn)槟J(rèn)編碼格式是ISO-8859-1,先獲取參數(shù)妥箕,然后用該格式解碼滥酥,再用UTF-8格式編碼
String age = req.getParameter("age");
byte[] data = age.getBytes("ISO-8859-1");
age = new String(data,"UTF-8");
(eclipse)或者修改tomcat的配置文件server.xml,修改其中端口那一行
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
修改為
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
URIEncoding="UTF-8"
URIEncoding缺省情況下畦幢,為"ISO-8859-1"的編碼格式
六. 配置文檔和注解
- 配置文檔
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1" metadata-complete="false">
<!--是否忽略注解-->
<servlet>
<servlet-name>MappingServlet</servlet-name>
<servlet-class>com.txm._01_mapping.MappingServlet</servlet-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MappingServlet</servlet-name>
<url-pattern>/map2</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MappingServlet</servlet-name>
<url-pattern>/map1</url-pattern>
</servlet-mapping>
</web-app>
- 注解
@WebServlet(value="/map",loadOnStartup = 0,initParams = @WebInitParam(name="encoding",value="UTF-8"))
- 比較
(1). 從開(kāi)發(fā)角度:注解簡(jiǎn)單
(2). 從維護(hù)角度上:注解維護(hù)困難坎吻,使用注解又把硬編碼再次拉回到代碼中
開(kāi)發(fā)中:通用配置一般使用xml完成,維護(hù)性好宇葱,清晰瘦真,特殊配置返奉,使用注解。
在web中吗氏,和其他框架做集成芽偏,就只能用配置方式。
七. Servlet線程不安全問(wèn)題
Servlet優(yōu)點(diǎn):動(dòng)態(tài)網(wǎng)頁(yè)弦讽,跨平臺(tái)的污尉,單例的(速度快)
缺點(diǎn):多線程并發(fā)Servlet線程不安全,輸出界面不友好
根本原因:多個(gè)線程并發(fā)訪問(wèn)同一份資源
解決方案:不要使用成員變量往产,單例情況下被碗,若網(wǎng)絡(luò)延遲,成員變量賦值再讀取仿村,可能讀到的不是自己賦的值锐朴。
八. Cookie,客戶端共享數(shù)據(jù)的技術(shù)蔼囊,參數(shù)傳遞焚志,會(huì)話跟蹤。
- 作用把需要共享的信息畏鼓,保留在客戶端(瀏覽器)中酱酬。不同于在鏈接中直接傳遞參數(shù),信息出現(xiàn)在地址欄云矫,不安全膳沽。但是依然可以利用開(kāi)發(fā)工具查看set-Cookie信息。
- 語(yǔ)法
當(dāng)前回話需要設(shè)置cookie让禀,響應(yīng)添加cookie挑社,此次回話過(guò)程中,訪問(wèn)只要獲取cookie巡揍,響應(yīng)不需要再次添加cookie痛阻。
//LoginServlet.java
Cookie c = new Cookie("username",username);
resp.addCookie(c);
//ListServlet.java
Cookie[] c = req.getCookie();//獲取的是Cookie數(shù)組
String username = c[i].getValue();
- Cookie不支持中文和安全性
利用加密和解密方式,同時(shí)解決上訴兩個(gè)問(wèn)題
//LoginServlet.java
Cookie c = new Cookie("name", URLEncoder.encode(username,"UTF-8"));
req.addCookie(c);
//ListServlet.java
Cookie[] c = req.getCookie();//獲取的是Cookie數(shù)組
String username = URLDecoder.decode(c[0].getValue());
- Cookie 路徑和域
整個(gè)應(yīng)用可用 c.setPath("/");
多個(gè)二級(jí)域名可用c.setDomain(".baidu.com");
九. Session服務(wù)器端的數(shù)據(jù)共享技術(shù)吼肥,不使用會(huì)話跟蹤
- 服務(wù)器器開(kāi)辟一個(gè)空間存儲(chǔ)客戶端信息录平,響應(yīng)時(shí)傳回這個(gè)Session的id給瀏覽器,瀏覽器下次訪問(wèn)時(shí)缀皱,再傳回這個(gè)id斗这,用于識(shí)別認(rèn)證,服務(wù)器就可以根據(jù)這個(gè)id取出數(shù)據(jù)啤斗。
- 操作
//1.獲取或創(chuàng)建session
HttpSession session = req.getSession();
//2.把共享數(shù)據(jù)存儲(chǔ)在Session中表箭,鍵值對(duì)形式
//session.setAttribute(String name, Object value);
session.setAttribute("username","will");
//3.從session中取出共享數(shù)據(jù)
Object val = session.getAttribute("username");
//4.修改session中的共享數(shù)據(jù)
//重新設(shè)置一個(gè)同名的屬性名
session.setAttribute("username","tom");
//5.刪除知道屬性值
session.removeAttribute("username");
//6.拓展
User user = new User("name","password");
session.setAttribute("User_in_Session",user);//習(xí)慣名字為"XXX_In_Session"
/*習(xí)慣把放入Session的對(duì)象(User類)钮莲,讓它實(shí)現(xiàn)序列號(hào)接口免钻,則當(dāng)多臺(tái)服務(wù)集群的時(shí)候彼水,彼此之間可以共享session數(shù)據(jù)。序列化极舔,對(duì)象轉(zhuǎn)為二進(jìn)制凤覆,反序列化則是把二進(jìn)制數(shù)據(jù)恢復(fù)成對(duì)象,二者都是對(duì)象流拆魏。
*/
. 銷毀Session對(duì)象(退出盯桦,注銷登錄)
操作中的刪除方法只能刪除一個(gè)指定名稱的屬性
session.invalidate();銷毀整個(gè)Session對(duì)象
----------------分割線-------------------