JavaWeb入門到實戰
1.基本概念
1.1前言
Java Web,是用Java技術來解決相關web互聯網領域的技術棧。web包括:web服務端和web客戶端兩部分。Java在客戶端的應用有java applet,不過使用得很少,Java在服務器端的應用非常的豐富,比如Servlet,JSP和第三方框架等等。Java技術對Web領域的發展注入了強大的動力。
1.2web應用程序
可以提供瀏覽器訪問的程序;
- a.html、b.html.….多個web資源,這些web資源可以被外界訪問,對外界提供服務;
- 你們能訪問到的任何一個頁面或者資源,都存在於這個世界的某一個角落的計算機上。
- URL
- 這個統一的web資源會被放在同一個文件夾下,web應用程序>Tomcat:服務器、
- 一個web應用由多部分組成(靜態web,動態web)
- html,css
- jsp,servlet
- Java程序
- jar包
- 配置文件(Properties)
Web應用程序編寫完畢后,若想提供給外界訪問;需費一個服務器來統一管理。
1.3靜態web
靜態網站特點:
1. 靜態網站是最初的建站方式,瀏覽者所看到的每個頁面是建站者上傳到服務器上的一個 html ( htm )文件,這種網站每增加、刪除、修改一個頁面,都必須重新對服務器的文件進行一次下載上傳。網頁內容一經發布到網站服務器上,無論是否有用戶訪問,每個靜態網頁的內容都是保存在網站服務器上的,也就是說,靜態網頁是實實在在保存在服務器上的文件,每個網頁都是一個獨立的文件;
2. 靜態網頁的內容相對穩定,因此容易被搜索引擎檢索;
3. 靜態網頁沒有數據庫的支持,在網站制作和維護方面工作量較大,因此當網站信息量很大時完全依靠靜態網頁制作方式比較困難;
4. 靜態網頁的交互性較差,在功能方面有較大的限制。如:不能實現用戶注冊和用戶登錄的功能
靜態web原理圖如下圖所示:

1.4動態web
所謂 “ 動態 ” ,並不是指網頁上簡單的 GIF 動態圖片或是 Flash 動畫,動態網站的概念現在還沒有統一標准,但都具備以下幾個基本特征:
1. 交互性:網頁會根據用戶的要求和選擇而動態地改變和響應,瀏覽器作為客戶端,成為一個動態交流的橋梁,動態網頁的交互性也是今后 Web 發展的潮流。
2. 自動更新:即無須手動更新 HTML 文檔,便會自動生成新頁面,可以大大節省工作量。
3. 因時因人而變:即當不同時間、不同用戶訪問同一網址時會出現不同頁面。
動態web原理圖如下圖所示:

2.Tomcat
2.1 Tomcat文件夾信息

2.2 核心配置文件

可以配置啟動的端口號
- tomcat的默認端口號為:8080
- http:80 https: 443
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
可以配置主機的名稱
- 默認的主機名為: localhost->127.0.0.1
- 默認網站應用存放的位置為:webapps
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
可以在這修改訪問地址:
C:\Windows\System32\drivers\etc/hosts

高難度面試題:
請你談談網站是如何進行訪問的?
1.輸入一個域名,回車
2.檢查本機的 C:\Windows\System32\drivers\etc/hosts 配置文件下有沒有這個域名映射;
1.有: 直接返回對應的ip地址,這個地址中,有我們需要訪問的web程序,可以直接方法
127.0.0.1 www.jihu.com
2.沒有 : 去DNS服務器找,找到的話就返回,找不到就返回找不到;

2.3發布一個web網站
將自己寫的網站,放到服務器(Tomcat)中指定的web應用的文件夾(webapps)下,就可以訪問了
--webapps :Tomcat服務器的web目錄
-ROOT
-jihu :網站的目錄名
- WEB-INF
-classes : java程序
-lib:web應用所依賴的jar包
-web.xml :網站配置文件
- index.html 默認的首頁
- static
-css
-style.css
-js
-img
-.....
3.Http
3.1Http簡介
HTTP協議是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫,是用於從萬維網(WWW:World Wide Web )服務器傳輸超文本到本地瀏覽器的傳送協議。
HTTP協議工作於客戶端-服務端架構為上。瀏覽器作為HTTP客戶端通過URL向HTTP服務端即WEB服務器發送所有請求。Web服務器根據接收到的請求后,向客戶端發送響應信息。

3.2主要特點
1、簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與服務器聯系的類型不同。由於HTTP協議簡單,使得HTTP服務器的程序規模小,因而通信速度很快。
2、靈活:HTTP允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
3.無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答后,即斷開連接。采用這種方式可以節省傳輸時間。
4.無狀態:所謂http是無狀態協議,言外之意是說http協議沒法保存客戶機信息,也就沒法區分每次請求的不同之處。關於http無狀態阻礙了交互式應用程序的實現。比如記錄用戶瀏覽哪些網頁、判斷用戶是否擁有權限訪問等。於是,兩種用於保持HTTP狀態的技術就應運而生了,一個是Cookie,而另一個則是Session。
5、支持B/S及C/S模式。
3.3HTTP值URL
HTTP使用統一資源標識符(Uniform Resource Identifiers, URI)來傳輸數據和建立連接。URL是一種特殊類型的URI(URL則通過描述是哪個主機上哪個路徑上的文件來唯一確定一個資源,也就是定位的方式來實現的URI),URL,全稱是UniformResourceLocator, 中文叫統一資源定位符,是互聯網上用來標識某一處資源的地址。以下面這個URL為例,介紹下普通URL的各部分組成:
http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
從上面的URL可以看出,一個完整的URL包括以下幾部分:
1.協議部分:該URL的協議部分為“http:”,這代表網頁使用的是HTTP協議。在Internet中可以使用多種協議,如HTTP,FTP等等本例中使用的是HTTP協議。在"HTTP"后面的“//”為分隔符
2.域名部分:該URL的域名部分為“www.aspxfans.com”。一個URL中,也可以使用IP地址作為域名使用
3.端口部分:跟在域名后面的是端口,域名和端口之間使用“:”作為分隔符。端口不是一個URL必須的部分,如果省略端口部分,將采用默認端口
4.虛擬目錄部分:從域名后的第一個“/”開始到最后一個“/”為止,是虛擬目錄部分。虛擬目錄也不是一個URL必須的部分。本例中的虛擬目錄是“/news/”
5.文件名部分:從域名后的最后一個“/”開始到“?”為止,是文件名部分,如果沒有“?”,則是從域名后的最后一個“/”開始到“#”為止,是文件部分,如果沒有“?”和“#”,那么從域名后的最后一個“/”開始到結束,都是文件名部分。本例中的文件名是“index.asp”。文件名部分也不是一個URL必須的部分,如果省略該部分,則使用默認的文件名
6.錨部分:從“#”開始到最后,都是錨部分。本例中的錨部分是“name”。錨部分也不是一個URL必須的部分
7.參數部分:從“?”開始到“#”為止之間的部分為參數部分,又稱搜索部分、查詢部分。本例中的參數部分為“boardID=5&ID=24618&page=1”。參數可以允許有多個參數,參數與參數之間用“&”作為分隔符。
3.4Http請求
客戶端發送請求(Request)給服務器
以向百度發起請求為例:
Request URL:https://www.baidu.com/ 請求地址
Request Method:GET get方法/post方法
Status Code:200 OK 狀態碼:200
Remote(遠程) Address:14.215.177.39:443
Accept:text/html
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.9 語言
Cache-Control:max-age=0
Connection:keep-alive
1.請求行
- 請求行中的請求方式:GET
- 請求方式:Get,Post,HEAD,DELETE,PUT,TRACT…
- get:請求能夠攜帶的參數比較少,大小有限制,會在瀏覽器的URL地址欄顯示數據內容,不安全,但高效
- post:請求能夠攜帶的參數沒有限制,大小沒有限制,不會在瀏覽器的URL地址欄顯示數據內容,安全,但不高效。
2.請求頭
Accept:告訴瀏覽器,它所支持的數據類型
Accept-Encoding:支持哪種編碼格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language:告訴瀏覽器,它的語言環境
Cache-Control:緩存控制
Connection:告訴瀏覽器,請求完成是斷開還是保持連接
HOST:主機..../.
3.5Http響應
- 服務器發出響應給客戶端
以百度為例
Cache-Control:private 緩存控制
Connection:Keep-Alive 連接
Content-Encoding:gzip 編碼
Content-Type:text/html 類型
1.響應體
Accept:告訴瀏覽器,它所支持的數據類型
Accept-Encoding:支持哪種編碼格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language:告訴瀏覽器,它的語言環境
Cache-Control:緩存控制
Connection:告訴瀏覽器,請求完成是斷開還是保持連接
HOST:主機..../.
Refresh:告訴客戶端,多久刷新一次;
Location:讓網頁重新定位;
2.響應狀態碼
狀態代碼有三位數字組成,第一個數字定義了響應的類別,共分五種類別:
1xx:指示信息--表示請求已接收,繼續處理
2xx:成功--表示請求已被成功接收、理解、接受
3xx:重定向--要完成請求必須進行更進一步的操作
4xx:客戶端錯誤--請求有語法錯誤或請求無法實現
5xx:服務器端錯誤--服務器未能實現合法的請求
常見狀態碼:
200 OK //客戶端請求成功
400 Bad Request //客戶端請求有語法錯誤,不能被服務器所理解
401 Unauthorized //請求未經授權,這個狀態代碼必須和WWW-Authenticate報頭域一起使用
403 Forbidden //服務器收到請求,但是拒絕提供服務
404 Not Found //請求資源不存在,eg:輸入了錯誤的URL
500 Internal Server Error //服務器發生不可預期的錯誤
503 Server Unavailable //服務器當前不能處理客戶端的請求,一段時間后可能恢復正常
其他部分請參考鏈接: http協議一篇就夠了
3.6 Get和Post的區別
-
GET提交的數據會放在URL之后,以?分割URL和傳輸數據,參數之間以&相連,如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的數據放在HTTP包的Body中.
-
GET提交的數據大小有限制(因為瀏覽器對URL的長度有限制),而POST方法提交的數據沒有限制.
-
GET方式需要使用Request.QueryString來取得變量的值,而POST方式通過Request.Form來獲取變量的值。
-
GET方式提交數據,會帶來安全問題,比如一個登錄頁面,通過GET方式提交數據時,用戶名和密碼將出現在URL上,如果頁面可以被緩存或者其他人可以訪問這台機器,就可以從歷史記錄獲得該用戶的賬號和密碼.
4.Maven
4.1 maven簡介
Maven是一個采用純Java編寫的開源項目管理工具。Maven采用了一種被稱之為project object model (POM)概念來管理項目,所有的項目配置信息都被定義在一個叫做POM.xml的文件中,通過該文件,Maven可以管理項目的整個聲明周期,包括編譯,構建,測試,發布,報告等等。目前Apache下絕大多數項目都已經采用Maven進行管理。而Maven本身還支持多種插件,可以方便更靈活的控制項目。一句話:Maven是一個項目管理和構建工具,主要做編譯、測試、報告、打包、部署等操作完成項目的構建。Maven不僅是構建工具,還是一個依賴管理工具和項目管理工具,它提供了中央倉庫,能幫我自動下載構件。
4.2 下載安裝maven
maven官網:https://www.apache.org

下載完畢后,解壓即可;
4.3 配置環境變量
在系統變量中添加 M2_HOME

在系統變量的path中添加 %M2_HOME%\bin

測試Maven環境是否按裝成功,保證必須配置完畢

4.4 配置阿里雲鏡像和本地倉庫
配置鏡像(鏡像(Mirroring)是一種文件存儲形式,是冗余的一種類型,一個磁盤上的數據在另一個磁盤上存在一個完全相同的副本即為鏡像。),使用默認倉庫下載jar包會比較慢,所以配置一個阿里雲鏡像
打開maven安裝目錄下的conf\settings.xml 添加如下信息
<mirrors>
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
</mirror>
</mirrors>
添加本地倉庫路徑:
<localRepository>D:\222\abo\repository</localRepository>

4.5 pom.xml的結構
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>ch07-spring-mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!--單元測試 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<!--目的是吧src/main/java目錄中的xml文件包含到輸出結果中。 輸出到classes目錄中 -->
<resources>
<resource>
<directory>src/main/java</directory> <!--所在目標-->
<includes> <!--包括目錄下的.properties, .xml文件都會掃描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<!--指定jdk的版本-->
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
4.6web.xml中webapp版本問題
自動生成的webapp是2.3版本的,最新版的版本在tomcat中可以找到
<?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_4_0.xsd"
version="4.0"
metadata-complete="true">
</web-app>
5.Servlet
Pom.xml
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1-b03</version>
</dependency>
6.Cookie 、Session
6.1會話
會話:用戶打開一個瀏覽器,點擊了很多超鏈接,訪問多個web資源,關閉瀏覽器,這個過程可以稱之為會話;
有狀態會話:一個同學來過教室,下次再來教室,我們會知道這個同學,曾經來過,稱之為有狀態會話;
一個網站,怎么證明你來過?
客戶端 服務端
- 服務端給客戶端一個 信件,客戶端下次訪問服務端帶上信件就可以了; cookie
- 服務器登記你來過了,下次你來的時候我來匹配你; seesion
6.2 保存會話的兩種技術
cookie
- 客戶端技術 (響應,請求)
session
- 服務器技術,利用這個技術,可以保存用戶的會話信息? 我們可以把信息或者數據放在Session中!
常見常見:網站登錄之后,你下次不用再登錄了,第二次訪問直接就上去了!
6.3Cookie
1.由服務器創建一個cookie,並設置數據和屬性,再由服務器發送給客戶端,客戶端在本地保存該cookie
2.下次訪問時帶上該cookie,服務器就能知道你先前來過,並可以通過cookie獲取數據2.
Cookie[] cookies = req.getCookies(); //獲得cookie
cookie.getName() //獲得cookie中的key
cookie.getValue() //獲得cookie中的value
new Cookie("lastLoginTime", System.currentTimeMillis() + ""); //新建一個cookie
cookie.setMaxAge(24*60*60); //cookie的有效期為一天
resp.addCookie(cookie); //響應給客戶端一個cookie
cookie:一般會保存在本地的 用戶目錄下 appdata;
刪除cookie:
-
不設置有效期,關閉瀏覽器,自動失效
-
設置有效期時間為0
cookie中解決字符串亂碼的問題
//編碼
Cookie cookie1 = new Cookie("name", URLEncoder.encode("張三", "utf-8"));
//解碼
out.write(URLDecoder.decode(cookie.getValue(),"utf-8"));
例子
package com.jihu.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Date;
//保存用戶上一次訪問的時間
public class CookieDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//服務器,告訴你,你來的時間,把這個時間封裝成為一個信件,你下次帶來,我就知道你來了
//解決中文亂碼
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
PrintWriter out = resp.getWriter();
//cookie,服務器端從客戶端獲取的
Cookie[] cookies = req.getCookies(); //這里返回數組,說明cookie可能存在多個
//判斷cookie是否存在
if (cookies != null){
//如果存在
out.write("你上一次訪問的時間是:");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
//獲取cookie的名字
if (cookie.getName().equals("lastLoginTime")){
//獲取cookie的值
long lastLoginTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastLoginTime);
out.write(date.toLocaleString());
//out.write(URLDecoder.decode(cookie.getValue(),"utf-8"));
}
}
}else{
out.write("這是您第一次訪問本站");
}
//服務給客戶端響應一個cookie
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");
//Cookie cookie1 = new Cookie("name", URLEncoder.encode("張三", "utf-8"));
//cookie的有效期為一天
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
6.4 Session (重點)
什么是session:
- 服務器會給每一個用戶(瀏覽器)創建一個session對象;
- 一個session獨占一個瀏覽器,只要瀏覽器沒有關閉,這個session就存在;
- 用戶登錄之后,整個網站它都可以訪問! --> 保存用戶的信息保存購物車的信息
例子
SessionDemo01
public class SessionDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解決亂碼問題
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
//得到session
HttpSession session = req.getSession();
//給session中存東西
//session.setAttribute("name","張二哈");
session.setAttribute("name",new Person("二哈",20));
//獲取session的id
String sessionId = session.getId();
//判斷session是不是新創建
if (session.isNew()){
resp.getWriter().write("session創建成功,ID:"+sessionId);
}else {
resp.getWriter().write("session已經在服務器中存在了,ID:"+sessionId);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
}
SessionDemo02
public class SessionDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解決亂碼問題
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
//得到session
HttpSession session = req.getSession();
//String name = (String) session.getAttribute("name");
Person name = (Person) session.getAttribute("name");
//System.out.println(name);
System.out.println(name.toString());
PrintWriter out = resp.getWriter();
out.println(name);
out.flush();
out.close();
}
}
SessionDemo03(手動注銷session)
public class SessionDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.removeAttribute("name");
//手動注銷session
session.invalidate();
}
}
刪除session
session的存活時間可以在web.xml中進行配置
<!--設置session默認的失效時間-->
<session-config>
<!--15分鍾后session自動失效,以分鍾為單位-->
<session-timeout>1</session-timeout>
</session-config>
6.5 cookie和seesion的相同點和不同點
相同的:
cookie和session都是為了解決http協議無狀態的特征
區別:
-
cookie數據是存放在客戶端本地的,session數據是存放在服務器的,但是服務端的session的實現對客戶端的cookie有依賴關系的;
-
cookie不是很安全,別人可以分析存放在本地的cookie並進行cookie欺騙,考慮到安全應當使用session;
-
session會在一段時間內存放在服務器,如果session過多,會導致服務器壓力過大,性能降低。如果考慮服務器性能方面應該使用cookie
-
cookie的大小是有限制的
-
一個用戶在一個站點上可以有多個cookie,但是只有一個session
-
session對象由服務創建
