JavaWeb
基本概念
web開發:
- web ---- 網頁
- 靜態web
- html css 提供給所有人看的 數據始終不會發生變化
- 動態web
- 技術棧 servlet/jsp asp php
- java中動態web資源開發技術統稱爲javaWeb
服務器是一種被動的操作,用來處理用戶的一些請求和給用戶一些響應信息
web服務器:
IIS windows自帶
tomcat
Tomcat
啓動關閉 bin/startup.sh shutdown.sh
HTTP:
百度:
Request URL: https://www.baidu.com/
Request Method: GET
Status Code: 200 OK
Remote Address: 36.152.44.96:443
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cache-Control: max-age=0
Connection: keep-alive
- 請求行
- 請求方式:GET POST HEAD DELETE
- get:請求能夠攜帶的參數比較少,大小有限制,會在url地址欄顯示數據內容,不安全但是高效
- post:請求能夠攜帶的參數無限制,大小沒有限制,不會在url地址顯示數據內容,安全,但不高效
- 請求方式:GET POST HEAD DELETE
- 消息頭
Accept: 告訴瀏覽器 支持的數據類型
Accept-Encoding: 支持哪種編碼
Accept-Language: 語言環境
Cache-Control: 緩存控制
Connection: 告訴瀏覽器 請求完成是斷開還是保持連接
HTTP響應
200 請求響應成功
3xx 請求重定向
4xx 找不到資源 404
5xx 服務器代碼錯誤 500 502網關錯誤
常見面試題
當瀏覽器地址欄輸入地址並回車的一瞬間到頁面能夠展示回來,經歷了什麼
Maven項目架構管理工具
阿里雲鏡像加速
setting.xml
pom.xml
jar:java應用
war:javaweb應用
properties 配置
build 項目構建用的東西
Servlet
什麼是Servlet
- Servlet是開發動態web的一門技術
- Servlet就是一個接口,Servlet只需要編寫一個類實現Servlet,把開發好的java類部署到web服務器中
helloServlet
Servelt接口有兩個默認的實現類 HttpServlet
- 構建一個Maven項目,刪掉裏面的src目錄,以後在這個項目裏建立moudel,這個空的工程就是maven主工程
- 關於Maven父子工程的理解:
父項目中會有<modules> <module>servlet-01</module> </modules>
父項目中的java子項目可以直接使用
- Maven環境優化
- 修改web.xml爲最新的
- 將maven結構搭建完整
- 編寫servlet ,實現Servlet,或者繼承HttpServlet
public class HelloServlet extends HttpServlet {
//由於get或者post只是請求實現的不同的方式 可以相互調用 業務邏輯都一樣
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.print("Hello,Servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 編寫Servlet的映射
爲什麼需要映射:我們寫的是Java程序,但是需要通過瀏覽器訪問,而瀏覽器需要連接web服務器,所以我們需要在web服務中註冊我們寫的Servlet,還需要給一個瀏覽器能訪問的路徑
<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="true">
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.wang.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/helloServlet</url-pattern>
</servlet-mapping>
</web-app>
- 配置Tomcat
注意:配置項目發佈的路徑就可以了 - 啓動測試
Servlet原理
Servlet是由Web服務器調用,web服務在收到瀏覽器請求之後會:
Mapping問題
- 一個Servlet可以指定一個映射路徑
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/helloServlet</url-pattern>
</servlet-mapping>
- 一個Servlet可以指定多個映射路徑
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/helloServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/helloServlet1</url-pattern>
</servlet-mapping>
- 一個Servlet可以指定通用映射路徑
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/helloServlet/*</url-pattern>
</servlet-mapping>
- 默認請求路徑
可以替換掉默認首頁
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
- 指定一些後綴或者前綴等等
可以自定義後綴實現請求映射
注意:*前面不能加項目映射的路徑
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
- 優先級問題
指定了固有的映射優先級最高,找不到就會找默認請求路徑
默認請求路徑是ErrorServlet,當訪問/helloServlet的時候,頁面跳轉HelloServlet,但是其它時候就跳轉ErrorServlet
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.wang.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/helloServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ErrorServlet</servlet-name>
<servlet-class>com.wang.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ErrorServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
ServletContext
web容器在啓動的時候,他會爲每個web程序都創建一個對應的ServletContext對象,它代表了當前的web應用
- 共享數據
- 在這個Servlet中保存的數據可以在其它Servlet中使用
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Hello");
// this.getInitParameter(); 初始化參數
// this.getServletConfig(); Servlet配置
// this.getServletContext(); Servlet上下文
ServletContext context = this.getServletContext();
String username = "username";
context.setAttribute("username", username); //將一個數據保存在ServletCOntext中 kv對
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
// HelloServlet中的username可以在GetServelt中獲取到(需要先加載HelloServlet)
String username = (String) context.getAttribute("username");
System.out.println(this.getClass().getName() + ":" + username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>Hello</servlet-name>
<servlet-class>com.wang.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>GetContext</servlet-name>
<servlet-class>com.wang.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GetContext</servlet-name>
<url-pattern>/getContext</url-pattern>
</servlet-mapping>
獲取初始化參數
<!-- 配置一些web應用初始化參數-->
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://aliyun:3306/mybatis</param-value>
</context-param>
<servlet>
<servlet-name>ServletDemo03</servlet-name>
<servlet-class>com.wang.servlet.ServletDemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo03</servlet-name>
<url-pattern>/servletDemo03</url-pattern>
</servlet-mapping>
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
System.out.println(url); //jdbc:mysql://aliyun:3306/mybatis
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
請求轉發(請求轉發的時候不跳轉url 只是頁面跳轉)
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
RequestDispatcher requestDispatcher = context.getRequestDispatcher("/servletDemo03"); //轉發的請求路徑
requestDispatcher.forward(req, resp); //會進入servletDemo03界面 但是url還是在servletDemo04
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
讀取資源文件
Properties
- 在java目錄下新建properties
- 在resources目錄下新建properties
發現:都被打包到了同一路徑下,classes,我們俗稱爲這個路徑爲classPath
如果將properties放在java目錄下,資源可能會導出失敗,在pom.xml中配置
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
默認不需要配置resources目錄
思路:需要一個文件流
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
InputStream is = context.getResourceAsStream("/WEB-INF/classes/db.properties");
Properties properties = new Properties();
properties.load(is);
String user = (String) properties.get("user");
System.out.println(user);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
HttpServletRequest
HttpServletRequest代表客戶端的請求,用戶通過Http協議訪問服務器,HTTP請求中的所有細信息會被封裝到HttpServletRequest,通過這個HttpServletRequest的方法,獲得客戶端的所有信息
- 獲取前端傳遞的參數
- 請求轉發
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
// 獲取參數
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbies = req.getParameterValues("hobby");
System.out.println(username);
System.out.println(password);
System.out.println(Arrays.toString(hobbies));
// 請求轉發
req.getRequestDispatcher("/success.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
HttpServletResponse
web服務器接收到客戶端的http請求,針對這個請求,分別創建一個代表請求的HttpServletRequest對象,代表響應的一個HttpServletResponse;
- 如果想要獲取客戶端請求過來的參數:找HttpServletRequest
- 如果想要給客戶端響應一些信息,找HttpServletResponse
- 簡單分類
負責向瀏覽器發送數據的方法:
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
向瀏覽器發送響應頭的方法
void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
常見應用:
- 向瀏覽器輸出信息
- 下載文件
- 獲取下載文件的路徑
- 下載的文件名
- 設置想辦法讓瀏覽器支持下載我們需要的東西
- 獲取下載文件的輸入流
- 創建緩衝區
- 獲取OutputStream對象
- 將FileInputStream流寫入到buffer緩衝區 使用OutputStream將緩衝區中的數據輸出到客戶端
- 關閉資源
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 獲取下載文件的路徑
String realPath = this.getServletContext().getRealPath("/1.jpg");
System.out.println("文件路徑:" + realPath);
// 2. 下載的文件名
String fileName = realPath.substring(realPath.lastIndexOf("//") + 1);
// 3. 設置想辦法讓瀏覽器支持下載我們需要的東西
resp.setHeader("Content-disposition", "attachment;filename" + fileName);
// 4. 獲取下載文件的輸入流
FileInputStream in = new FileInputStream(realPath);
// 5. 創建緩衝區
int len = 0;
byte[] buffer = new byte[1024];
// 6. 獲取OutputStream對象
ServletOutputStream out = resp.getOutputStream();
// 7. 將FileInPutStream流寫入到buffer緩衝區 使用OutputStream將緩衝區中的數據輸出到客戶端
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
// 8. 關閉資源
in.close();
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 驗證碼
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 如何讓瀏覽器五秒自動刷新一次
resp.setHeader("refresh", "5");
//在內存中創建一個圖片
BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = (Graphics2D) image.getGraphics(); //筆
// 設置背景顏色
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, 80, 20);
//給圖片寫數據
graphics.setColor(Color.BLUE);
graphics.setFont(new Font(null, Font.BOLD, 20));
graphics.drawString(makeNum(), 0, 20);
//告訴瀏覽器這個請求用圖片的方式打開
resp.setContentType("image/jpeg");
//網站存在緩存 不讓瀏覽器緩存
resp.setDateHeader("expires", -1);
resp.setHeader("Cache-Control", "no-cache");
resp.setHeader("Pragma", "no-cache");
//把圖片寫給瀏覽器
ImageIO.write(image, "jpg", resp.getOutputStream());
}
//生成隨機數
private String makeNum() {
Random random = new Random();
String num = String.valueOf(random.nextInt(9999999));
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 7 - num.length(); i++) {
sb.append("0");
}
num = sb.toString() + num;
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 實現重定向
一個web資源收到客戶端請求後,會通知客戶端去訪問另外一個web資源,這個過程叫重定向
public class RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
重定向等價於這兩步
resp.setHeader("Location", "/image");
resp.setStatus(HttpServletResponse.SC_FOUND);
*/
resp.sendRedirect("/image"); //重定向
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
重定向和轉發的區別
- 相同點:頁面跳轉
- 不同點:
- 轉發 url不變 307
- 重定向 url跳轉 302
public class RequestTest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("進入請求");
//處理請求
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username+":"+password);
resp.sendRedirect("/success.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<html>
<body>
<h2>Hello World!</h2>
<%-- 這裏提交的路徑需要尋找到項目的路徑--%>
<%--${pageContext.request.contextPath} 當前項目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
用戶名: <input type="text" name="username"><br>
密碼:<input type="password" name="password"><br>
<input type="submit">
</form>
</body>
</html>
<servlet>
<servlet-name>request</servlet-name>
<servlet-class>com.wang.servlet.RequestTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>request</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
Cookie Session
cookie
- 客戶端技術(響應請求)
session - 服務器技術,利用這個技術可以保存用戶的會話信息,我們可以把信息或者數據放在session中
常見場景:網站登錄之後下次不用登錄,第二次訪問自動登錄
Cookie
- 從請求中拿到cookie信息
- 服務器響應給客戶端cookie
Cookie[] cookies = req.getCookies(); //獲得Cookie
cookie.getName(); //獲得Cookie的key
cookie.getValue(); //獲得Cookie的value
Cookie cookie = new Cookie("lastLoginTime", String.valueOf(System.currentTimeMillis())); //新建一個cookie
cookie.setMaxAge(24 * 60 * 60); //設置cookie有效期
resp.addCookie(cookie);
public class CookieDemo01 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();
if (cookies != null) {
out.write("上次訪問的時間是");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
//獲取cookie的名字
if (cookie.getName().equals("lastLoginTime")) {
long lastLoginTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastLoginTime);
out.write(date.toLocaleString());
}
}
} else {
out.write("這是你第一次訪問本站");
}
//服務器給客戶端響應一個cookie
Cookie cookie = new Cookie("lastLoginTime", String.valueOf(System.currentTimeMillis()));
cookie.setMaxAge(24 * 60 * 60);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 一個Cookie只能保存一個信息 key-value
- 一個web站點可以給瀏覽器發送多個cookie,300個cookie大概是瀏覽器上限,每個站點最多存放20個
- cookie大小有限制,4Kb
刪除Cookie:
- 不設置有效期,關閉瀏覽器自動失效
- 設置有效期時間爲0
// 網絡編程解決亂碼
String encode = URLEncoder.encode("我是中文", "utf-8");
String decode = URLDecoder.decode(encode, "utf-8");
Session
什麼是session
- 服務器會給每一個用戶(瀏覽器)創建一個Session對象
- 一個Session獨佔一個瀏覽器,只要瀏覽器沒有關閉,這個Session就存在
- 用戶登錄之後,整個網站都可以訪問
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", "nameTest");
session.getAttribute("name");
// 手動註銷
session.removeAttribute("name");
//獲得session的id
String id = session.getId();
//判斷session是不是新的
if (session.isNew()) {
resp.getWriter().write("session創建成功,id" + id);
} else {
resp.getWriter().write("session已經在服務器中存在,id" + id);
}
//session在創建的時候做了什麼
// Cookie cookie = new Cookie("JSESSIONID", id);
// resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<!-- 設置session默認的失效時間 15分鐘-->
<session-config>
<session-timeout>15</session-timeout>
</session-config>
使用場景:
- 保存一個登錄用戶的信息
- 購物車信息
- 在整個網站中經常會使用的數據,保存在session中
Session和Cookie的區別:
- Cookie是把用戶的數據寫給用戶的瀏覽器,瀏覽器保存
- Session是把用戶的數據寫到用戶獨佔的Session中,服務器端保存(保存重要的信息,減少服務器資源浪費)
- Session對象由服務器創建
JSP
什麼是JSP
Java Server Pages:Java服務器端頁面,也和Servlet一樣,用於動態web技術
最大的特點:
- 寫JSP就像在寫HTML
- 區別:
- HTML給用戶提供靜態的數據
- JSP頁面可以嵌入JAVA代碼,提供動態數據
JSP原理
思路:JSP是怎麼執行的
- 服務器內部:
tomcat中有一個work目錄
IDEA中使用Tomcat的會在IDEA中生成一個work目錄(工作空間 仍然依託於自己的tomcat)
/Users/wangyinghao/Library/Caches/JetBrains/IntelliJIdea2020.1/tomcat/Unnamed_kuangshen-javaweb/work/Catalina/localhost/ROOT/org/apache/jsp
瀏覽器向服務器發送請求,不管訪問什麼資源,其實都是在訪問Servlet
JSP最終也會被轉換成一個Java類
JSP本質就是一個Servlet
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/9.0.22
* Generated at: 2020-05-31 03:39:28 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private static final java.util.Set<java.lang.String> _jspx_imports_packages;
private static final java.util.Set<java.lang.String> _jspx_imports_classes;
static {
_jspx_imports_packages = new java.util.HashSet<>();
_jspx_imports_packages.add("javax.servlet");
_jspx_imports_packages.add("javax.servlet.http");
_jspx_imports_packages.add("javax.servlet.jsp");
_jspx_imports_classes = null;
}
private volatile javax.el.ExpressionFactory _el_expressionfactory;
private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public java.util.Set<java.lang.String> getPackageImports() {
return _jspx_imports_packages;
}
public java.util.Set<java.lang.String> getClassImports() {
return _jspx_imports_classes;
}
public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
if (_el_expressionfactory == null) {
synchronized (this) {
if (_el_expressionfactory == null) {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
}
}
}
return _el_expressionfactory;
}
public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
if (_jsp_instancemanager == null) {
synchronized (this) {
if (_jsp_instancemanager == null) {
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
}
}
return _jsp_instancemanager;
}
//初始化
public void _jspInit() {
}
//銷燬
public void _jspDestroy() {
}
//JspService
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
//request 請求 response 響應
if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
final java.lang.String _jspx_method = request.getMethod();
if ("OPTIONS".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
return;
}
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允許 GET、POST 或 HEAD。Jasper 還允許 OPTIONS");
return;
}
}
// 內置對象
final javax.servlet.jsp.PageContext pageContext; //頁面上下文
javax.servlet.http.HttpSession session = null; //session
final javax.servlet.ServletContext application; //applicationContext
final javax.servlet.ServletConfig config; //config
javax.servlet.jsp.JspWriter out = null; //out
final java.lang.Object page = this; //page
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
// 輸出頁面前增加的代碼
response.setContentType("text/html"); //設置響應的頁面類型 html
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
// 以上的這些對象可以在JSP頁面中直接使用
// ${pageContext}
out.write("<html>\n");
out.write("<body>\n");
out.write("<h2>Hello World!</h2>\n");
out.write("</body>\n");
out.write("</html>\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
在JSP頁面中,只要是JAVA代碼就會被原封不動的輸出;如果是HTML代碼,就會被轉換成
out.write("<html>\r\n");
JSP基礎語法
<html>
<body>
<h2>Hello World!</h2>
<%--JSP表達式--%>
<%--作用 將程序的輸出輸出到客戶端--%>
<%=new java.util.Date()%>
<hr/>
<%--腳本片段--%>
<%
int sum = 0;
for (int i = 0; i < 100; i++) {
sum += i;
}
out.println("<h1> Sum=" + sum + "</h1>");
%>
<%--代碼中嵌入html--%>
<%
for (int i = 0; i < 5; i++) {
%>
<h1>Hello,world <%=i%></h1>
<%
}
%>
<%--EL表達式 ${i}--%>
<%--JSP聲明--%>
<%--會被編譯到JSP生成Java類的類中 而不是_jspService中--%>
<%!
static {
System.out.println("Loading servlet");
}
private int globalVar = 0;
public void test(){
System.out.println("test");
}
%>
</body>
</html>
9大內置對象
- PageContext 存東西
- Request 存東西
- Response
- Session 存東西
- Application ServletContext 存東西
- config ServletConfig
- out
- page
- exception
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--內置對象--%>
<%
pageContext.setAttribute("name1", "name1"); //保存的數據只在一個頁面有效
request.setAttribute("name2", "name2"); //保存的數據只在一次請求中有效 請求轉發會攜帶這個數據
session.setAttribute("name3", "name3"); // 保存的數據只在一次會話中有效 從打開瀏覽器到關閉瀏覽器
application.setAttribute("name4", "name4"); //保存的數據在服務器中有效 從打開服務器到關閉服務器
%>
<%
// 通過pageContext取,我們通過尋找的方式
String name1 = (String) pageContext.findAttribute("name1");
String name2 = (String) pageContext.findAttribute("name2");
String name3 = (String) pageContext.findAttribute("name3");
String name4 = (String) pageContext.findAttribute("name4");
// pageContext有個類似JVM的雙親委派機制的特性 從底層到高層(作用域) page-->request-->session-->application
// pageContext.setAttribute() scope爲作用域 也可以提升pageContext的作用域
public void setAttribute(String name, Object attribute, int scope) {
switch(scope) {
case 1:
this.mPage.put(name, attribute);
break;
case 2:
this.mRequest.put(name, attribute);
break;
case 3:
this.mSession.put(name, attribute);
break;
case 4:
this.mApp.put(name, attribute);
break;
default:
throw new IllegalArgumentException("Bad scope " + scope);
}
%>
<%--通過el表達式輸出--%>
<h1>取出的值爲:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
</body>
</html>
request:客戶端向服務器發送請求,產生的數據,用戶看完就沒用的,比如:用戶看新聞
session:客戶端向服務器發送請求,產生的數據用戶用完一會還會用,比如:購物車
application:客戶端向服務器發送請求,產生的數據,一個用戶用完其他用戶還可能使用,比如:聊天數據
JSP標籤 JSTL標籤 EL表達式
EL表達式: ${}
- 獲取數據
- 執行運算
- 獲取web開發的常用對象
JSP標籤
<jsp:forward page="jsptag2.jsp">
<jsp:param name="name" value="nameTest"/>
<jsp:param name="age" value="ageTest"/>
</jsp:forward>
<%--取出參數--%>
<%=request.getParameter("name")%>
<%=request.getParameter("age")%>
JSTL標籤
JSTL標籤庫的使用就是爲了彌補HTML標籤的不足:自定義了許多標籤,功能和java一樣
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--導入JSTL核心庫--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<hr/>
<form action="coreif.jsp" method="get">
<%-- EL表達式獲取表單中的數據--%>
<input type="text" name="username" value="${param.username}">
<input type="submit" value="登錄">
</form>
<%--判斷如果提交的用戶名是管理員 則登錄成功--%>
<c:if test="${param.username == 'admin'}" var="isAdmin">
<c:out value="管理員歡迎您"></c:out>
</c:if>
<c:out value="${isAdmin}"></c:out>
<%
ArrayList<String> people = new ArrayList<>();
people.add(0,"張三");
people.add(1,"李四");
request.setAttribute("list",people);
%>
<c:forEach var="people" items="${list}">
<c:out value="${people}"></c:out><br>
</c:forEach>
</body>
</html>
JavaBean
實例類
JavaBean有特定的寫法:
- 必須要有一個無參構造
- 屬性必須私有化
- 必須有對應的get/set方法
一般用來和數據庫的字段做映射
ORM:對象關係映射 - 表–>類
- 字段–>屬性
- 行記錄–>對象
<%@ page import="com.wang.pojo.People" %><%--
Created by IntelliJ IDEA.
User: wangyinghao
Date: 2020/5/31
Time: 5:13 下午
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
// People people = new People();
// people.setId(1);
// people.setAddress("上海");
// people.setAge(10);
// people.setName("wyh");
%>
<jsp:useBean id="people" class="com.wang.pojo.People" scope="page"/>
<jsp:setProperty name="people" property="address" value="上海"/>
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="people" property="age" value="10"/>
<jsp:setProperty name="people" property="name" value="wyh"/>
姓名:<jsp:getProperty name="people" property="name"/>
</body>
</html>
MVC三層架構
Model:
- 業務處理:業務邏輯 Service
- 數據持久層:CRUD Dao
View - 展示數據
- 提供鏈接發起Servlet請求
Controller - 接收用戶的請求:req請求 session信息…
- 交給業務層處理對應的代碼
- 控制視圖的跳轉
登錄-->接收用戶的登錄請求-->處理用戶的請求(獲取用戶登錄的參數,username pwd)-->交給業務層處理登錄業務(判斷用戶名密碼是否正確:事務)-->Dao層查詢用戶名和密碼是否正確-->數據庫
Filter
過濾器,用來處理網站的數據
public class CharacterEncodingFilter implements Filter {
//服務器啓動的時候 init就已經初始化 隨時等待監聽
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init");
}
//Chain 鏈
// 過濾所有的代碼 在過濾特定請求的時候都會執行 web.xml配置
// 必須要讓過濾器繼續執行 filterChain.doFilter(servletRequest, servletResponse);
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html;charset=UTF-8");
System.out.println("doFilter執行前");
filterChain.doFilter(servletRequest, servletResponse); //讓我們的請求繼續走 如果不寫程序就到這裏被攔截停止
System.out.println("doFilter執行後");
}
//web服務器關閉的時候銷燬
public void destroy() {
System.out.println("destroy");
}
}
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.wang.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!-- 只要是/下的任何請求都會經過這個過濾器-->
<url-pattern>/*</url-pattern>
</filter-mapping>