u 背景知識介紹javascript
J2EE的13種技術php
java->servlet->jsp [技術老是有一個演變過程]css
zip粘貼到word設置html
u 回顧一下咱們現有的技術java
java 基礎(面向對象,集合,界面,線程,文件,網絡)mysql
jdbc (java 的數據庫編程)程序員
oracle / mysql / sqlserverweb
html css javascript (web 開發) ->網頁設計面試
xml算法
serlvet+jsp ->java web開發[使用java技術作 web開發]
u java ee 體系的介紹
u servlet項目演示
u web 開發介紹
① 靜態頁面 (html)
② 動態頁面
1. 用戶能夠輸入數據,和頁面交互(註冊,購物,發帖子,付款...)
2. 不一樣時間打開頁面,內容是變化.
3. 目前比較流行的左動態頁面的技術 ( servlet/jsp , php , asp.net , asp, cgi )
u 動態網頁技術的比較(瞭解)
u bs 和 cs的比較
(1)BS:browser server 瀏覽器服務器
(2)cs client server 客戶服務
u 爲何須要的web服務器/web到底是幹什麼的?
模擬一個web服務器 MyWebServer.java
import java.io.*;
import java.net.*;
public class MyWebServer
{
publicstatic void main(String []args) throws Exception{
ServerSocketss=new ServerSocket(80);
Sockets=ss.accept();
//提示一句話
System.out.println("在 9999 上等待鏈接...");
OutputStreamos=s.getOutputStream();
BufferedReaderbr=new BufferedReader(new FileReader("d:\\hello.html"));
Stringbuf="";
while((buf=br.readLine())!=null){
os.write(buf.getBytes());
}
//關閉流
br.close();
os.close();
s.close();
}
}
u 經過tomcat來說解BS結構
u 安裝tomcat服務器
(1) 解壓便可
(2) 配置
①在環境變量中添加
JAVA_HOME= 指向你的jdk的主目錄(並非bin文件目錄)
② 在不配置JAVAHOME的前提下啓動tomcat
在startup.bat的第25行中添加set JAVA_HOME=JKD路勁
(3) 啓動tomcat服務器
到 tomcat 主目錄下 bin/startup.bat
(4) 驗證是否安裝成功
http://localhost:8080(8080是默認端口若是該端口已經被佔用須要修改端口)
u tomcat安裝後問題解決
(1)tomcat沒法正常啓動的緣由分析
1. JAVA_HOME 配置錯誤,或者沒有配置
2. 若是你的機器已經佔有了8080 端口,則沒法啓動,
解決方法
(1) 你能夠8080 先關閉
netstat –an
netstat –anb 來查看誰佔用該8080
(2) 主動改變tomcat的端口.
到conf/server.xml 文件中修改
<ConnectorconnectionTimeout="20000" port="8088"(去修給config->server.xml的端口號)protocol="org.apache.coyote.http11.Http11NioProtocol"redirectPort="8443"/>
(3) 可以正常啓動,可是會導航到另一個頁面.
去修改工具->管理加載項,把默認的導航給禁用便可.
(4) 在訪問 tomcat時候,必定保證 tomcat 服務器是啓動
u tomcat的目錄結構文件
bin: 啓動和關閉tomcat的bat文件
conf: 配置文件
-->server.xml : 該文件用於配置和 server 相關的信息, 好比 tomcat啓動端口後,配置Host, 配置Context 即web應用
-->web.xml : 該文件配置與 web應用(web應用就至關因而一個 web站點)
-->tomcat-users.xml: 該文件用戶配置tomcat 的用戶密碼 和 權限
lib 目錄: 該目錄放置運行tomcat 運行須要的jar包
logs 目錄:存放日誌, 當咱們須要去查看日誌的時候,頗有用!,當咱們啓動tomcat錯誤時候,能夠查詢信息.
webapps 目錄: 該目錄下,放置咱們的web應用(web 站點), 好比:
創建 web1 目錄 下面放置咱們的html 文件 jsp 文件..圖片... 則 web1就被當作一個web應用管理起來(☞ 特別說明tomcat 6.0之後支持 tomcat 5 版本 還有別的設置)
work: 工做目錄: 該目錄用於存放jsp被訪問後 生成的對應的 server文件 和.class文件
u 如何去訪問一個 web 應用的某個文件
u 首頁面設置及目錄規範結構
如今咱們要求:把hello.html文件設置成該 web應用的首頁,則須要把web應用的目錄格式作的更加規範:
①在web文件夾下配置WEB-INF文件夾
②在 web.xml 文件中添加配置的代碼:
<welcome-file-list>
<welcome-file>hello1.html</welcome-file>
</welcome-file-list>
③經過http://localhost:8088/web1來訪問hello1.html
web-inf目錄下的 classes目錄未來是存放 class文件
lib 目錄未來時存放 jar文件
web.xml 配置當前這個web應用的信息.
u tomcat如何去管理虛擬目錄
需求: 當咱們把 web 應用放到 webapps目錄,tomcat會自動管理,若是咱們但願tomcat能夠管理其它目錄下的web應用?->虛擬目錄配置
我在d 盤有一個web應用.
u 虛擬目錄配置步驟:
① 找到server.xml文件
② 編輯host節點 添加Context path
在server.xml中添加:<Contextpath="/myweb2"docBase="d:\web2"/>
myweb2:是訪問時輸入的web名,實際取出的是web2中的資源
"d:\web2":絕對路徑下web2中存放資源如:hello2.html
實際訪問時輸入的地址:http://localhost:8088/myweb2/hello2.html
絕對路徑:從根分區找某個文件
相對路徑:從該文件位置去找另外一個文件
③ 須要重啓tomcat,才能生效.(由於是採用的dom技術講信息加載到內存中)
u context 的幾個屬性的說明
path:
docbase:
reloadable ;若是設爲ture ,表示 tomcat 會自動更新 web應用,這個開銷大,建議在開發過程當中,能夠設爲true, 可是一旦真的發佈了,則應當設爲false;
upackWAR: 若是設爲 ture ,則自動解壓,不然不自動解壓.
①:打war包 cd:d/web2 而後jar –cvf web2.war *
②:
瀏覽打好的war包 Deploy發佈後會在webapps中自動生存改文件
u 配置域名
咱們看和一個如何配置本身的主機名:
咱們在實際訪問網站的過程當中,不可能使用http://localhost:8080/web應用/資源名 的方式去訪問網站,實際上使用相似
http://news.sina.com.cn 的方式去訪問網站,這個又是怎麼實現的呢?
看看ie瀏覽器訪問一個web站點的流程.
實現的步驟以下:
(1)在C:\WINDOWS\system32\drivers\etc 下的host文件添加127.0.0.1 www.sina.com.cn
(2) 在tomcat的server.xml文件添加主機名
<Host name="www.sina.com" appBase="d:\web3」>
<Contextpath="/" docBase="d:\web3" />
</Host>
(3) 在d:\web3 加入了一個 /WEB-INF/web.xml 把 hello2.html設爲首頁面
若是連端口都不但願帶,則能夠吧tomcat的啓動端口設爲80便可.
(4) 重啓生效
u tomcat體系的再說明
圖:
如何配置默認主機:
在tomcat/conf/server.xml文件
<Engine name="Catalina" defaultHost="主機名">
u 爲何須要servlet技術?
好比需求:咱們但願用戶能夠貼,用戶還能夠回覆 ....這樣一些和用戶能夠交互的功能,用普通的java技術就完成不了, sun 就開發了 servlet技術供程序員使用.
u servlet的介紹
① servlet 其實就是java程序(java類)
② 該 java 程序(java 類)要遵循servlet開發規範
③ serlvet是運行在服務端
④ serlvet 功能強大,幾乎能夠完成網站的全部功能
⑤ 是學習jsp基礎
u tomcat 和 servlet 在網絡中的位置
u servlet的生命週期是怎樣的/servlet到底是怎樣工做的
UML 時序圖幫助你們理解
參看execel
面試題: 請簡述servlet的生命週期(工做流程)
答:
標準版本:
①WEB服務器首先會檢查是否已經裝載並建立了該servlet實例對象。若是是直接進行第④步,不然執行第②步。
②裝載並建立該Servlet的一個實例對象。
③調用Servlet實例對象的init()方法。
④建立一個用於封裝HTTP請求消息的HttpServletRequest對象和一個表明HTTP響應消息的HttpServletResponse對象,而後調用service()方法並將請求和響應做爲參數傳遞進去。
⑤WEB應用被中止或重啓以前,Servlet引擎將卸載Servlet,在卸載以前調用Servlet的destroy()方法
1. 當serlvet 第一次被調用的時候,會觸發init函數,該函數會把servlet實例裝載到內存.init函數只會被調用一次
2. 而後去調用servlet 的 service 函數
3. 當第二次後訪問該servlet 就直接調用 service 函數.
4. 當 web應用 reload 或者 關閉 tomcat 或者 關機 都會去調用destroy函數,該函數就會去銷燬serlvet
5. Servlet的生命週期
當客戶端第一次向web服務器發出一個servlet請求時,web服務器將會建立一個該servlet的實例,而且調用servlet的init()方法;若是當服務器已經存在了一個servlet實例,那麼,將直接使用此實例;而後再調用service()方法,service()方法將根據客戶端的請求方式來決定調用對應的doXXX()方法;當 web應用reload 或者 關閉tomcat 或者 關機,web服務器將調用destroy()方法,將該servlet從服務器內存中刪除。
生命全過程:
1.加載
2.實例化
3.初始化
4.處理請求
5.退出服務
u 開發servlet有三種方法
(1) 實現 Servlet接口
(2) 經過繼承 GenericServlet
(3) 經過繼承 HttpServlet
u ①實現servlet接口的方式
需求以下: 請使用實現接口的方式,來開發一個Servlet ,要求該Servlet 能夠顯示Hello,world,同時顯示當前時間.
步驟
1. 在webapps下創建一個web應用 hspWeb1
2. 在hspWeb1 下創建 WEB-INF->web.xml[web.xml能夠從ROOT/WEB-INF/web.xml拷貝]
3. 在WEB-INF 下創建 classes目錄(咱們的Servlet 就要在該目錄開發.),創建 lib文件夾
4. 開發MyServlet.java
package com.hsp;
import javax.servlet.*;
import javax.servlet.http.*; 爲了能將servlet-api.jar包引入,須要配置環境變量
變量值; E:\tomcat\apache-tomcat-6.0.20\lib\servlet-api.jar 記得帶上文件名
import java.io.*;
class MyFirstServlet implements Servlet
{
//該函數用於初始化servlet,就是把該servlet裝載到內存中
//該函數只會被調用一次
publicvoid init(ServletConfig config)
throws ServletException{
}
//獲得ServletConfig對象
publicServletConfig getServletConfig(){
returnnull;
}
//該函數是服務函數,咱們的業務邏輯代碼就是寫在這裏
//該函數每次都會被調用
publicvoid service(ServletRequest req,
ServletResponse res)
throws ServletException,
java.io.IOException{
}
//該函數時獲得servlet配置信息
publicjava.lang.String getServletInfo(){
returnnull;
}
//銷燬該servlet,從內存中清除,該函數被調用一次
publicvoid destroy(){
}
}
5. 根據Servlet規範,咱們還須要部署Servlet
<?xml version="1.0"encoding="ISO-8859-1"?>
<!--
Licensed to the Apache Software Foundation(ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
TheASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except incompliance with
theLicense. You may obtain a copy of theLicense at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributedunder the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Seethe License for the specific language governing permissions and
limitations under the License.
-->
<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_2_5.xsd"
version="2.5">
<!--根據serlvet規範,須要將Servlet部署到web.xml文件,該部署配置能夠從examples下拷貝-->
<servlet>
<!--servlet-name 給該Servlet取名, 該名字能夠本身定義:默認就使用該Servlet的名字-->
<servlet-name>MyFirstServlet</servlet-name>③
<!--servlet-class要指明該Servlet 放在哪一個包下的,形式是包/包/../類-->
<servlet-class>com.hsp.MyFirstServlet</servlet-class>注意:後面不要帶.java④
</servlet>
<!--Servlet的映射-->
<servlet-mapping>
<!--這個Servlet-name要和上面的servlet-name名字同樣-->
<servlet-name>MyFirstServlet</servlet-name>②
<!--url-pattern這裏就是未來訪問該Servlet的資源名部分-->
<url-pattern>/ABC</url-pattern>①
</servlet-mapping>
</web-app>
服務器調用流程:http://localhost:8088/ABC--->①--->②--->③--->④
6. 在瀏覽器中測試
在瀏覽器中輸入
http://localhost:8088/hspweb1/ABC
7. 分析一下本身寫可能出現的錯誤
(1) <servlet-name>MyFirstServlet</servlet-name>名字不同 (啓動tomcat錯誤)
(2) <servlet-class>com.hsp.MyFirstServlet</servlet-class> 寫成MyFirstServlet.java,會報告500
(3) 資源名本身寫錯
http://localhost:8088/hspweb1/錯誤的資源url-pattern
404 錯誤
補充: 若是使用javac 去編譯一個java文件,則須要帶命令參數
javac –d . java文件
補充: 如何不重啓tomcat,就指定去 reload 一個web應用,方法:
進入到 tomcat 的 manager:
點擊reload便可.
課堂練習
本身使用 實現Servlet接口的方法,開發一個Servlet,該servlet 能夠輸出本身的名字
在顯示當前日期.
u ②使用GenericServlet開發servlet
瞭解便可:
案例 :
package com.hsp;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class MyGenericServlet extends GenericServlet
{
public void service(ServletRequest req,
ServletResponse res)
throws ServletException,
java.io.IOException{
res.getWriter().println("hello,world,iam geneirc servlet");
}
}
將該Servlet部署到web.xml文件中:
<!--根據serlvet規範,須要將Servlet部署到web.xml文件,該部署配置能夠從examples下拷貝-->
<servlet>
<!--servlet-name 給該Servlet取名, 該名字能夠本身定義:默認就使用該Servlet的名字-->
<servlet-name>MyGenericServlet</servlet-name>
<!--servlet-class要指明該Servlet 放在哪一個包下的,形式是包/包/../類-->
<servlet-class>com.hsp.MyGenericServlet</servlet-class>
</servlet>
<!--Servlet的映射-->
<servlet-mapping>
<!--這個Servlet-name要和上面的servlet-name名字同樣-->
<servlet-name>MyGenericServlet</servlet-name>
<!--url-pattern這裏就是未來訪問該Servlet的資源名部分,默認命名規範:
就是該Servlet的名字-->
<url-pattern>/MyGenericServlet</url-pattern>
</servlet-mapping>
u ③使用繼承 HttpServlet 的方法來開發Serlvet
(1) 在軟件公司 90%都是經過該方法開發.
(2) 舉例說明; 仍是顯示 hello,world 當前日期
代碼:
packagecom.hsp;
importjavax.servlet.*;
importjavax.servlet.http.*;
importjava.io.*;
public class MyHttpServlet extends HttpServlet
{
//在HttpServlet 中,設計者對post 提交和 get提交分別處理
//回憶 <formaction="提交給?"method="post|get"/>,默認是get
protectedvoid doGet(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException,
java.io.IOException{
resp.getWriter().println("iam httpServet doGet()");
}
protectedvoid doPost(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException,
java.io.IOException{
resp.getWriter().println("iam httpServet doPost() postname="+req.getParameter("username"));
}
}
還有一個login.html
<html>
<body>
<formaction="/hspWeb1/MyHttpServlet" method="post">
u:<inputtype="text" name="username"/>
<inputtype="submit" value="login"/>
</body>
</html>
u 小結 get 提交 和 post的提交的區別
① 從安全看 get<post 由於get 會把提交的信息顯示到地址欄
② 從提交內容看 get<post get 通常不要大於2k, post理論上無限制,可是在實際 開發中,建議不要大於64k
③ 從速度看 get>post
④ Get能夠保留uri中的參數,利於收藏
u 使用ide來開發servlet
使用ide (eclipse[java se]+myeclipse[插件 能夠支持jsp/servlet/struts/hibernate/spring..])開發servlet
需求:使用 ide 開發一個servlet ,該servlet顯示 hello,world, 和當前日期
u 開發步驟:
(1) 創建web工程
(2) 在Src 目錄下建立了一個包 com.hsp.servlet
(3) 開發一個Servlet
MySerlvet 的代碼:
publicvoid doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("hello"+newjava.util.Date().toString() );
}
publicvoid doPost(HttpServletRequest request,HttpServletResponse response)
throwsServletException, IOException {
this.doGet(request,response);
}
(4) 配置tomcat
點擊add 選擇要發佈到那個服務器便可:
(5) 啓動tomcat
1. 使用咱們的老方法
2. 從eclipse 啓動 tomcat
(6) 在使用eclipse 開發servlet 可能會出現一個很麻煩事情,版本不一致錯誤.
java.lang.UnsupportedClassVersionError: Bad version number in .class file (unableto load class com.hsp.servlet.MyServlet1)
緣由是由於 tomcat 使用jdk 和 servlet 使用的 jdk不同,
解決方法就是統一便可.
請你們使用eclipse 並配置繼承 HttpServlet 開發一個servlet, 顯示hello, 和當前日期.
u Servlet的細節問題
① 一個已經註冊的Servlet能夠被屢次映射即:
<servlet>
<description>This is thedescription of my J2EE component</description>
<display-name>This is thedisplay name of my J2EE component</display-name>
<!-- servlet的註冊名 -->
<servlet-name>MyServlet1</servlet-name>
<!--servlet類的全路徑(包名+類名) -->
<servlet-class>com.hsp.servlet.MyServlet1</servlet-class>
</servlet>
<!-- 對一個已經註冊的servlet的映射 -->
<servlet-mapping>
<!--servelt的註冊名 -->
<servlet-name>MyServlet1</servlet-name>
<!--servlet的訪問路徑 -->
<url-pattern>/MyServlet1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MyServlet1</servlet-name>
<url-pattern>/hsp</url-pattern>
</servlet-mapping>
② 當映射一個servlet時候,能夠多層 好比
<url-pattern>/servlet/index.html</url-pattern> ok
從這裏還能夠看出,後綴名是 html 不必定就是 html,多是假象.
③ 使用通配符在servlet映射到URL中
有兩種格式:
第一種格式 *.擴展名 好比 *.do *.ss
第二種格式 以 / 開頭 同時以 /* 結尾 好比 /* /news/*
通配符練習題:
l Servlet1映射到 /abc/*
l Servlet2映射到 /*
l Servlet3映射到 /abc
l Servlet4映射到 *.do
問題(面試題):
l 當請求URL爲「/abc/a.html」,「/abc/*」和「/*」都匹配,哪一個servlet響應
Servlet引擎將調用Servlet1。
l 當請求URL爲「/abc」時,「/abc/*」和「/abc」都匹配,哪一個servlet響應
Servlet引擎將調用Servlet3。
l 當請求URL爲「/abc/a.do」時,「/abc/*」和「*.do」都匹配,哪一個servlet響應
Servlet引擎將調用Servlet1。
l 當請求URL爲「/a.do」時,「/*」和「*.do」都匹配,哪一個servlet響應
Servlet引擎將調用Servlet2。
l 當請求URL爲「/xxx/yyy/a.do」時,「/*」和「*.do」都匹配,哪一個servlet響應
Servlet引擎將調用Servlet2。
在匹配的時候,要參考的標準:
(1) 看誰的匹配度高,誰就被選擇
(2) *.do 的優先級最低
④ Servlet單例問題
當Servlet被第一次訪問後,就被加載到內存,之後該實例對各個請求服務.即在使用中是單例.
由於 Servlet是單例,所以會出現線程安全問題: 好比:
售票系統. 若是不加同步機制,則會出現問題:
這裏我給你們一個原則:
(1) 若是一個變量須要多個用戶共享,則應當在訪問該變量的時候,加同步機制
synchronized(對象){
//同步代碼
}
(2)若是一個變量不須要共享,則直接在 doGet() 或者 doPost()定義.這樣不會存在線程安全問題
⑤ servlet中的 <load-on-startup> 配置
需求: 當咱們的網站啓動的時候,可能會要求初始化一些數據,(好比建立臨時表), 在好比:
咱們的網站有一些要求定時完成的任務[ 定時寫日誌,定時備份數據.. 定時發送郵件..]
解決方法: 能夠經過<load-on-startup> 配合 線程知識搞定.
先說明<load-on-startup>: 經過配置<load-on-startup> 咱們能夠指定某個Servlet 自動建立.
咱們來模擬一個定時發送電子郵件的功能:
實現思路:
sendEmailTable
id content sendtime
1 「hello」 2011-11-11 20:11
2 「hello2」 2012-11-1110:00
看看如何線程去完成任務:
這裏的代碼請參考項目:
SendMailThread.java
package com.hsp.model;
publicclass SendEmailThread extends Thread{
@Override
publicvoid run() {
int i=0;
try {
while(true){
//每休眠一分鐘,就去掃表sendmail, 看看那份信件應當被髮出
Thread.sleep(10*1000);
System.out.println("發出第"+(++i)+"郵件");//javamail
}
} catch (Exceptione) {
e.printStackTrace();
// TODO: handle exception
}
}
}
MyInitServlet1.java
publicvoid init() throwsServletException {
// Put yourcode here
System.out.println("MyInitServlet1 的init被調用..");
//完成一些初始化任務
System.out.println("建立數據庫,表,讀取參數");
//建立一個線程
SendEmailThread sendEmailThread=new SendEmailThread();
sendEmailThread.start();
}
說明:
<!-- 1表示該servlet被 init的順序 -->
<load-on-startup>1</load-on-startup>
u ServletConfig對象
該對象主要用於 讀取 servlet的配置信息.
案例:
<servlet>
<servlet-name>ServletConfigTest</servlet-name>
<servlet-class>com.hsp.servlet.ServletConfigTest</servlet-class>
<!-- 這裏能夠給servlet配置信息,這裏配置的信息,只能被該servlet 讀取 -->
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</servlet>
如何使用
Stringencoding=this.getServletConfig().getInitParameter("encoding");
補充說明:這種配置參數的方式,只能被某個Servlet獨立使用.如但願讓全部的Servlet都去讀取某個參數,這樣配置:
<!-- 若是這裏配置參數,可被全部servlet讀取 -->
<!--
<context-param>
<param-name></param-name>
<param-value></param-value>
</context-param>
-->
u 若是要把全部的參數都讀取,則使用 以下方法 :
Enumeration<String>names=this.getServletConfig().getInitParameterNames();
while(names.hasMoreElements()){
String name=names.nextElement();
System.out.println(name);
System.out.println(this.getServletConfig().getInitParameter(name));
}
補充,如何去修改Servlet的配置模板.
u 編寫項目
1. 先完成用戶登陸
2. 添加在主界面,添加一個超連接,能夠返回登陸界面重寫登陸
u http協議的再介紹
① http協議是創建在tcp/ip協議基礎上
② http協議全稱 超文本傳輸協議
③ http協議1.0 , 1.1版本 ,目前通用的是1.1版本
http1.0 稱爲短鏈接
http1.1 稱爲長鏈接.
所謂長,和短指的是 持續時間的 長鏈接 1.1 30s ,短鏈接是發送完數據就斷掉.
u http的請求部分:
基本結構:
GET /test/hello.html HTTP/1.1 [請求行]
Accept: */* [消息名] 消息名:內容
Referer: http://localhost:8080/test/abc.html
Accept-Language: zh-cn
User-Agent: Mozilla/4.0
Accept-Encoding: gzip, deflate
Host: http://www.sohu.com:80
Connection: Keep-Alive [消息頭格式 (消息名: 內容 )
特別說明: 並非每一次請求的消息頭都同樣.]
空行
發送的內容 [格式 : 內容名字=內容體]
u 請求方式
請求行中的GET稱之爲請求方式,請求方式有:POST,GET,HEAD,OPTIONS,DELETE,TRACE,PUT
經常使用的有:POST,GET
u get和post
參看ppt,和之前的筆記
GET News/abc.jsp
u http請求消息頭
1) Accept: text/html,image/* [告訴服務器,我能夠接受文本,網頁,圖片]
2. Accept-Charset: ISO-8859-1 [接受字符編碼 iso-8859-1]
3. Accept-Encoding: gzip,compress [能夠接受 gzip,compress壓縮後數據.]
4. Accept-Language: en-us,zh-cn [瀏覽器支持中,英文]
5. Host: www.sohu.com:80 [我要找主機是www.sohu.com:80]
6. If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT [ 告訴服務器,個人緩衝中有這個資源文件,該文件的時間是。。。]
7. Referer: http://www.sohu.com/index.jsp [告訴服務器,我來自哪裏,該消息頭,經常使用於防止盜鏈]
8. User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)[告訴服務器,瀏覽器內核]
9. Cookie [cookie??]
10. Connection:close/Keep-Alive [保持鏈接,發完數據後,我不關閉鏈接]
11. Date: Tue, 11 Jul 2000 18:23:51 GMT [瀏覽器發送該http請求的時間]
關於Referer的實際案例:
//獲取用戶瀏覽器Referer
String referer=request.getHeader("Referer");
if(referer==null||!referer.startsWith("http://localhost:8088/servletPro")){
response.sendRedirect("/servletPro/Error");
return;
}
紅色的部分能夠根據實際狀況來修改.
u http的響應
基本結構:
狀態行:
格式:HTTP版本號 狀態碼 緣由敘述
舉例:HTTP/1.1200 OK
狀態碼 含義
100-199 表示成功接收請求,要求客戶端繼續提交下一次請求才能完成整個處理過程
200-299 表示成功接收請求並完成整個處理過程,經常使用200
300-399 爲完成請求,客戶須要進行一步細化請求。例如:請求的資源已經移動一個新的地址,經常使用302,307
400-499 客戶端的請求有錯誤404
500-599 服務器端出現錯誤,經常使用500
u http響應的狀態行舉例說明
200 就是整個請求和響應過程沒有發生錯誤,這個最多見.
302: 表示當你請求一個資源的時候,服務器返回302 表示,讓瀏覽器轉向到另一個資源,好比: response.sendRedirect(「/web應用/資源名」)
案例:
response.setStatus(302);
response.setHeader("Location", "/servletPro/Servlet2");
// 上面兩句話等價 response.sendRedirect("/servletPro/Servlet2");
404: 找不到資源
500: 服務器端錯誤
u http響應消息頭詳解
n Location: http://www.baidu.org/index.jsp 【讓瀏覽器從新定位到url】
n Server:apache tomcat 【告訴瀏覽器我是tomcat】
n Content-Encoding: gzip 【告訴瀏覽器我使用 gzip】
n Content-Length: 80 【告訴瀏覽器會送的數據大小80節】
n Content-Language: zh-cn 【支持中文】
n Content-Type: text/html;charset=GB2312 [內容格式text/html; 編碼gab2312]
n Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT 【告訴瀏覽器,該資源上次更新時間】
n Refresh: 1;url=http://www.baidu.com 【過多久去,刷新到 http://www.baidu.com】
n Content-Disposition: attachment; filename=aaa.zip 【告訴瀏覽器,有文件下載】
n Transfer-Encoding: chunked [傳輸的編碼]
n Set-Cookie:SS=Q0=5Lb_nQ; path=/search[後面詳講]
n Expires: -1[告訴瀏覽器如何緩存頁面IE]
n Cache-Control: no-cache [告訴瀏覽器如何緩存頁面火狐]
n Pragma: no-cache [告訴瀏覽器如何緩存頁面]
n Connection: close/Keep-Alive [保持鏈接 1.1是Keep-Alive]
n Date: Tue, 11 Jul 2000 18:23:51 GMT
①定時刷新Refresh使用
response.setHeader("Refresh","5;url=/servletPro/Servlet2");
②文件下載Content-Disposition
publicvoid doGet(HttpServletRequest request, HttpServletResponseresponse)
throwsServletException, IOException {
response.setContentType("text/html");
//PrintWriterout = response.getWriter();
//演示下載文件
response.setHeader("Content-Disposition", "attachment; filename=winter.jpg");
//打開文件.說明一下web 站點下載文件的原理
//1.獲取到要下載文件的全路徑
String path=this.getServletContext().getRealPath("/images/Winter.jpg");
//System.out.println("path="+path);
//2建立文件輸入流
FileInputStream fis=new FileInputStream(path);
//作一個緩衝字節數組
byte buff[]=newbyte[1024];
int len=0;//表示實際每次讀取了多個個字節
OutputStreamos=response.getOutputStream();
while((len=fis.read(buff))>0){
os.write(buff, 0, len);
}
//缺點: 沒有進度條./圖標/
//關閉
os.close();
fis.close();
}
③緩存講解
提出問題:瀏覽器默認狀況下,會緩存咱們的頁面,這樣出現一個問題:若是咱們的用戶習慣把光標停留在地址欄,而後回車來取頁面,就會默認調用cache中取數據。
(1) 有些網站要求及時性很高,所以要求咱們不緩存頁面
代碼:
//指定該頁面不緩存 Ie
response.setDateHeader("Expires", -1);【針對IE瀏覽器設置不緩存】
//爲了保證兼容性.
response.setHeader("Cache-Control", "no-cache");【針對火狐瀏覽器等】
response.setHeader("Pragma", "no-cache");【其餘瀏覽器】
(2) 有些網站要求網頁緩存必定時間,好比緩存一個小時
response.setDateHeader("Expires", System.currentTimeMillis()+3600*1000*24);後面一個參數表示設置的緩存保持時間,-1表示永遠緩存
練習:
加入防止盜鏈下載.
u HttpServletResponse的再說明
getWriter()
getOutputStream();
區別
1. getWriter() 用於向客戶機回送字符數據
2. getOutputStream() 返回的對象,能夠回送字符數據,也能夠回送字節數據(二進制數據)
OutputStream os=response.getOutputStream();
os.write("hello,world".getBytes());
如何選擇:
若是咱們是回送字符數據,則使用 PrintWriter對象 ,效率高
若是咱們是回送字節數據(binarydate) ,則只能使用 OutputStream
☞ 這兩個流不能同時使用.
好比:
OutputStreamos=response.getOutputStream();
os.write("hello,world".getBytes());
PrintWriter out=response.getWriter();
out.println("abc");
就會報錯:
java.lang.IllegalStateException: getOutputStream() has already been called for this response
不能同時使用printWriter和outputstream的緣由
Web服務器會自動檢查並關閉流
從該圖,咱們也能夠看出. 爲何咱們沒有主動關閉流,程序也沒有問題的緣由.
固然:你主動關閉流,更好.
u 參數的傳遞方式sendRedirect()和session()
需求: 當用戶登陸成功後,把該用戶名字顯示在登陸成功頁面;
①使用sendRedirect()來傳遞字符參數
解決思路:
1. 使用java基礎 static
2. 使用sendRedirect()
代碼:
response.sendRedirect("/UsersManager/MainFrame?uname="+username+"&pwd="+password);
3. 使用session 傳遞[後面講]
這裏,咱們先預熱.
說明:
基本格式:
response.sendRedirect(「servlet的地址?參數名=參數值&參數名=參數值...」);
☞ 參照值是String , 參數名應當使用 字母組合
在接受數據的Servlet中:
String 參數=request.getParameter(「參數名」);
②使用session()來傳遞字符參數和對象
A.傳遞字符串
放入session request.getSession.setAttribute("loginUser",username);
取出session 在JSP中經過session取出request.getSession.getAttribute("loginUser");
B.傳遞對象
User user= new User();
user.setName(「xiaoli」);
user.setPassWord(「123」);
放入session request.getSession.setAttribute("userObj",userObj);
取出session User user=(User)request.getSession.getAttribute(「userObj」);
上機練習:
1. 實際運用到項目: 在wel頁面中顯示登陸用戶的姓名,就可使用該方法.讓咱們動手一塊兒來作作吧!
2. 請寫一篇關於HTTP協議的筆記,要求:
• 描述清楚HTTP請求頭、響應頭的格式
• 請求頭和響應頭中各個頭字段的含義
l 若是瀏覽器傳遞給WEB服務器的參數內容超過1K,應該使用那種方式發送請求消息?
l 請描述200、30二、30四、404和500等響應狀態碼所表示的意義。
l 請列舉三種禁止瀏覽器緩存的頭字段,並寫出相應的
u 中文亂碼處理
發生中文亂碼有三種狀況
① 表單form
(1) post
在服務器端設置成瀏覽器端的編碼方式。
解決方法: request.setCharacterEncoding("utf-8"); //gbk gb2312big5
(2) get
寫一個工具類:
package com.hsp.utils;
publicclass MyTools {
publicstatic String getNewString(String str) {
String newString="";
try {
newString=newString(str.getBytes("iso-8859-1"),"utf-8");
} catch (Exceptione) {
e.printStackTrace();
// 把iso-8859-1 轉換成 utf-8
}
return newString;
}
}
② 超連接
<a href=」http://www.sohu.com?name=函數後」>測試</a>
該方法和get處理方法同樣.
③ sendRedirect() 發生亂碼
response.sendRedirect(「servlet地址?username=順平」);
☞版本低致使的亂碼
特別說明,若是你的瀏覽器是 ie6 或如下版本,則咱們的 ② 和 ③中狀況會出現亂碼(當中文是奇數的時候)
解決方法是 :
Stringinfo=java.net.URLEncoder.encode("你好嗎.jpg", "utf-8");
<a href=」http://www.sohu.com?name=」+ info >測試</a>
response.sendRedirect(「servlet地址?username=」+info);
說明: 咱們應當儘可能使用post 方式提交;
☞返回瀏覽器顯示亂碼
在服務端是中文,在response的時候,也要考慮瀏覽器顯示是否正確,通常咱們經過
response.setContentType(「text/html;charset=utf-8」); ok
☞下載提示框中文亂碼
補充一個知識點: 當咱們下載文件的時候,可能提示框是中文亂碼
String temp=java.net.URLEncoder.encode("傳奇.mp3","utf-8");
response.setHeader("Content-Disposition","attachment;filename="+temp);
u HttpServletRequest對象的詳解
該對象表示瀏覽器的請求(http請求), 當web 服務器獲得該請求後,會把請求信息封裝成一個HttpServletRequest 對象
• getRequestURL方法返回客戶端發出請求時的完整URL。
• getRequestURI方法返回請求行中的資源名部分。
• getQueryString 方法返回請求行中的參數部分(參數名+值)。
該函數能夠獲取請求部分的數據好比
http://localhost/web名?username=abc&pwd=123
request.getQueryString(); 就會獲得 username=abc&pwd=123
getRemoteAddr方法返回發出請求的客戶機的IP地址
getRemoteHost方法返回發出請求的客戶機的完整主機名
getRemotePort方法返回客戶機所使用的網絡端口號
客戶機的端口號是隨機選擇的,web服務器的端口號是必定的
getLocalPort方法返回web服務器所使用的網絡端口號
getLocalAddr方法返回WEB服務器的IP地址。
getLocalName方法返回WEB服務器的主機名
u url 和 uri 的區別
好比:
Url=http://localhost:8088/servletPort3/GetinfoServlet完整的請求
Uri=/servletPort3/GetinfoServletweb應用的名稱+資源的名稱
練習題:
請在服務器這端,給瀏覽器回送該瀏覽器發送的具體請求內容是什麼?
韓順平
http://localhost:8088/web名/GetInfoServlet?abc=123&uu=90&iio=中國
大龍
http://localhost:8088/web名/GetInfoServlet?kkk=你好&email=dalong@sohu.com
你的請求是
kkk=你好
email=dalong@sohu.com
u 如何獲取用戶提交的內容(經過表單提交的內容)
代碼:
界面:
packagecom.hsp;
importjava.io.IOException;
importjava.io.PrintWriter;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
publicclass MyInfoForm extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out =response.getWriter();
out.println("<formaction='/servletPro3/RegisterCl' method='post'><br/>");
out.println("<inputtype='hidden' value='abc' name='hidden1'/>");
out.println("用戶名:<input type='text'name='username'/><br/>");
out.println("密 碼:<input type='password'name='pwd'/><br/>");
out.println("性 別:<input type='radio' name='sex' value='男'/>男<input type='radio' name='sex' value='女'/>女<br/>");
out.println("你的愛好:<input type='checkbox' name='hobby'value='音樂'>音樂 <input type='checkbox' name='hobby'value='體育'>體育 <input type='checkbox' name='hobby'value=\"旅遊\">旅遊<br/>");
out.println("所在城市:<select name='city'><optionvalue='bj'>北京</option><optionvalue='cq'>重慶</option></select><br/>");
out.println("你的介紹:<textarea cols='20' rows='10'name='intro' >請輸入介紹..</textarea><br/>");
out.println("提交照片:<input type='file'name='photo'><br/>");
//何時使用hidden傳輸數據 1.不但願用戶看到該數據 2. 不但願影響節目,同時使用該數據
out.println("<inputtype='submit' value='提交信息'/>");
out.println("</form>");
}
public void doPost(HttpServletRequestrequest, HttpServletResponse response)
throws ServletException,IOException {
this.doGet(request, response);
}
}
接受信息的Servlet:
package com.hsp;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
publicclass RegisterCl extends HttpServlet{
publicvoid doGet(HttpServletRequest request,HttpServletResponse response)
throwsServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
String u=request.getParameter("username");
String p=request.getParameter("pwd");
String sex=request.getParameter("sex");
//若是接受複選框的內容,則使用getparameterValues
String []hobbies=request.getParameterValues("hobby");
String city=request.getParameter("city");
String intro=request.getParameter("intro");
String hidden1=request.getParameter("hidden1");
out.println("用戶名="+u+"<br/>");
out.println("密 碼="+p+"<br/>");
out.println("性 別="+sex+"<br/>");
if(hobbies!=null){
for(int i=0;i<hobbies.length;i++){
out.println("愛好:"+hobbies[i]);
}
}else{
out.println("你沒有愛好");
}
out.println("<br/>所在城市:"+city);
out.println("<br/>我的介紹:"+intro);
out.println("<br/>隱藏控件數據:"+hidden1);
}
publicvoiddoPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException,IOException {
this.doGet(request,response);
}
}
練習題:請你們本身寫一個表單,提交數據(我的名字:電子郵件: 性別:你喜歡的城市 select(能夠選多個): 你的特長 (checkbox) 你的我的簽名, 用hidden傳輸重要數據)
u 請求轉發requeset.getRequestDispatcher(資源地址).forward(request,response);
資源地址:不須要項目名。由於它只是在WEB服務器內部轉發。
Request.getRequestDispatcher(資源地址).forward(request,response);
咱們如今使用請求轉發的方法來實現上次咱們使用 response.sendRedirect() 實現效果
使用 request提供的轉發方法.
Request中的Attribute在一次請求有效。一次請求:沒有返回到瀏覽器,就爲一次請求。
u 請求轉發的的(uml)圖
這裏咱們畫圖說明(uml)
1. 使用 forward 不能轉發到該web應用外的 url
2. 由於 forward 是發生在web服務器,因此 Servlet1 和 Servlet 2使用的是用一個request 和response.
l 使用sendRedirect() 方法不能經過request.setAttribute() 把 屬性傳遞給下一個Servlet
u 比較sendRedirect()和request.getRequestDispatcher().forward(request,response)
請問 sendRedirect() 和 forward 的區別是什麼
答:
(1) 叫法sendRedirect() 重定向,轉發 forward() 叫轉向
(2) 實際發生的位置不同
sendRedirect發生 瀏覽器
forward 發生 web服務器
(3) 用法不同
request.getRequestDispatcher(「/資源URI」).forward(request,response)
response.sendRedirect(「/web應用/資源URI」);
(4) 可以去URL範圍不同
sendRedirect能夠去 外邊URL
forward 只能去當前的WEB應用的資源
☞ 什麼是一次 http請求:
只要沒有中止,也沒有回到瀏覽器重定向,就算一次
好比;
☞ 若是轉發屢次,咱們的瀏覽器地址欄,保留的是第一次 轉向的那個ServletUrl
小練習:
使用uml 軟件,畫出 forward 和sendRedirect() 的流程.
u 用戶管理系統的繼續開發
u 用戶管理系統的框架圖 用戶管理框架圖.xls
① 增長到數據庫去驗證用戶功能
(1) 在oracle 數據庫中建立一張表
users
createtable users
(idnumber primary key,
usernamevarchar2(32) not null,
emailvarchar2(64) not null,
gradenumber default 1,
passwdvarchar2(32) not null)
初始化一些數據
insertinto users values(1,’aaaaa1’,’aaaa1@sohu.com’,1,’123’);
insertinto users values(2,’aaaaa2’,’aaaa2@sohu.com’,1,’123’);
insertinto users values(3,’aaaaa3’,’aaaa3@sohu.com’,1,’123’);
insertinto users values(4,’aaaaa4’,’aaaa4@sohu.com’,1,’123’);
insertinto users values(5,’aaaaa5’,’aaaa5@sohu.com’,5,’123’);
(2) 在LoginClServlet 中添加到數據庫驗證用戶的功能.
ok:
//到數據庫中取驗證
Connection ct=null;
ResultSet rs=null;
PreparedStatement ps=null;
try {
//1加載驅動
Class.forName("oracle.jdbc.driver.OracleDriver");
//2.獲得鏈接
ct=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:ORCLHSP","scott","tiger");
//3.建立PreparedSatement
ps=ct.prepareStatement("select * from users where id=? andpasswd=?");
//給? 賦值
ps.setObject(1, id);
ps.setObject(2, password);
//4.執行操做
rs=ps.executeQuery();
//5.根據結果左處理
if(rs.next()){
//說明該用戶合法
request.getRequestDispatcher("/MainFrame").forward(request, response);
}else{
request.getRequestDispatcher("/LoginServlet").forward(request, response);
}
} catch (Exceptione) {
e.printStackTrace();
// TODO: handle exception
}finally{
//關閉資源
if(rs!=null){
try {
rs.close();
} catch(SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
rs=null;
}
if(ps!=null){
try {
ps.close();
} catch(SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ps=null;
}
if(ct!=null){
try {
ct.close();
}catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ct=null;
}
}
② 若是輸入的用戶id 密碼不正確,則給出提示.
課後練習; 參看給出的用戶管理開發文檔,完成 1, 2, 3 頁面功能[分頁和安全性暫時不考慮.]
③ 用戶管理系統的界面添加圖片
④ 用戶管理系統添加分頁功能
思路:
定義四個分頁變量
pageNow 表示第幾頁,該變量是由用戶來決定,所以變化
pageSize 每頁顯示幾條記錄,由程序指定,也能夠由用戶定製
pageCount 表示共有多少頁, 該變量是計算出來->思考 怎樣肯定
rowCount 共有多少條記錄,該變量是查詢數據庫獲得
如何肯定pageCount
(1)
if(rowCount% pageSize==0){
pageCount=rowCount/pageSize;
}else{
pageCount=rowCount/pageSize+1;
}
試試: 好比 users表 9 條記錄 pageSize=3 =>pageCount=3
好比 users表 10 條記錄 pageSize=3 =>pageCount=4
(2)
上面的算法等價於
pageCount=rowCount% pageSize==0 ?rowCount/pageSize: rowCount/pageSize+1;
該運算稱爲三目運算
(3)
更簡單的算法是:
pageCount=(rowCount-1)/pageSize+1;
試試: 好比 users表 9 條記錄 pageSize=3 =>pageCount=3
好比 users表 11 條記錄 pageSize=3 =>pageCount=4
回憶: oracle 分頁的select
特別說明:若是某個web應用你不須要,請把該web應用從 webapps目錄下移走,不然tomcat啓動的速度會愈來愈慢.
上機練習題:
1. 完成本身項目的分頁
2. 再作一個 上一頁 1 2 3 4 5 6 下一頁 當前頁/總頁數
跳轉到 [ ] 頁 跳 【如何在servlet中使用js技術】
3. 思考題:
如何控制咱們的超連接只顯示10頁, << 1 2 3 4 5 6 7 8 9 10 >>
>> 顯示後面的10頁 << 顯示前10頁
如何控制直接輸入跳轉頁的時候,pageNow的值過大的問題?