2020-5-5-JAVAWEB

SylvesterZhang發表於2024-03-22

測試、反射、註解、Mysql、JDBC、Tomcat、servlet、HTTP、EL表示式、JSTL、Filter過濾器、代理模式、監聽器、Redis、Maven

測試

1黑白盒測試

黑盒測試:不需要寫程式碼,給輸入值,看程式能否給出期望的輸出值

白盒測試:需要寫程式碼,關注程式具體執行流程

2測試步驟

1)定義測試類

包名:cn.itcast.test

類名:CaculatorTest

2)定義測試方法

方法名:test測試方法名

返回值:void

引數:空

3)使用註解@Test

執行後結果為紅色,執行失敗;綠色,執行成功。

4)斷言

Assert.assertEquals(期望值,結果值)

5)初始化方法和釋放資源方法

@Before//修飾的方法在測試方法之前執行
public void init(){}
@After//修飾的方法在測試方法之後執行,一般用於釋放資源
public void close(){}

反射

將類的各部分封裝為其他類物件,多用於框架(半成品軟體,簡化編碼)的開發。優勢在於,一是可以在程式執行過程中操作這些物件,二是解耦程式,提高程式可擴充套件性

1獲取class物件的方式

1)class.forName(全類名)

多用於配置檔案

2)類名.class

多用於引數傳遞

3)物件.getClass()

多用於物件

同一位元組碼檔案在異常程式執行過程中,只會被載入一次,不論透過那隻方式獲取的Class物件都是同一個

2Class物件的功能

1)獲取成員變數

//獲取public修飾的成員變數
public Field[] getFields() throws SecurityException;
public Field getField(String name);

//獲取所有宣告的成員變數
public Field[] getDeclaredFields() throws SecurityException;
public Field getDeclaredField(String name);

2)獲取構造方法

public Constructor<?>[] getConstructors() throws SecurityException;
public Constructor<T> getConstructor(Class<?>... parameterTypes);
public Constructor<?>[] getDeclaredConstructors() throws SecurityException ;
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes);

3)獲取成員方法

public Method[] getMethods() throws SecurityException;
public Method getMethod(String name, Class<?>... parameterTypes);
public Method[] getDeclaredMethods() throws SecurityException;
public Method getDeclaredMethod(String name, Class<?>... parameterTypes);

4)獲取類名

public String getName();

5)獲取、改變成員變數的值

public Object get(Object obj) throws IllegalArgumentException, IllegalAccessException;
public void set(Object obj, Object value);

6)建立物件

(1)構造方法物件建立有參例項物件

public T newInstance(Object ... initargs);

(2)類物件建立例項無參物件

public T newInstance();
public class Person{
    public String name;
    private int age;

    public Person() {
        super();
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public void say(){
        System.out.println("我是"+this.name+",今年"+this.age+"歲了");
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

}
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

public class Hello{
    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        //獲取類物件
        Class ps=Person.class;

        //獲取類名
        System.out.println(ps.getName());

        //獲取宣告的成員變數
        Field[] fields=ps.getDeclaredFields();
        Field name=ps.getDeclaredField("name");
        Field age=ps.getDeclaredField("age");
        System.out.println(Arrays.toString(fields));
        System.out.println(name);
        System.out.println(age);

        //獲取宣告的構造方法
        Constructor[] c=ps.getDeclaredConstructors();
        System.out.println(Arrays.toString(c));
        Constructor c1=ps.getDeclaredConstructor(String.class,int.class);
        System.out.println(c1);

        //獲取宣告的成員方法
        Method[] mt=ps.getMethods();
        System.out.println(Arrays.toString(mt));
        Method m1=ps.getMethod("setAge", int.class);
        System.out.println(m1);
        Method m2=ps.getMethod("say");
        System.out.println(m2);

        //建立物件
        Object person=c1.newInstance("zhang",22);//構造方法物件建立有參物件
        System.out.println(person);
        Object person1=ps.newInstance();//類物件建立無參物件
        System.out.println(person1);

        //透過成員變數物件獲取成員變數值
        Object name_value=name.get(person);
        System.out.println(name_value);
        age.setAccessible(true);//忽略訪問許可權修飾符的安全檢測,無此語句會丟擲錯誤
        Object age_value=age.get(person);//age是私有屬性
        System.out.println(age_value);

        //透過成員變數物件設定成員變數值
        name.set(person,"zh");
        System.out.println(person);

        //透過成員方法物件執行物件的成員方法
        m2.invoke(person);
    }

}

2手寫框架案例

要求:不改變類的任何程式碼的前提下,建立任意類物件,並執行其中的方法

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

public class Hello{
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //讀取配置檔案
        Properties pro=new Properties();
        ClassLoader cl=Hello.class.getClassLoader();
        InputStream is=cl.getResourceAsStream("pro.Properties");
        pro.load(is);
        System.out.println(pro);//{ClassName=aaa.Person, MethodName=say}
        
        //建立類及物件,並執行方法
        Class ps = Class.forName(pro.getProperty("ClassName"));
        Constructor c = ps.getConstructor(String.class,int.class);
        Object person=c.newInstance("zhanghuan",22);
        Method m=ps.getMethod(pro.getProperty("MethodName"));
        m.invoke(person);//我是zhanghuan,今年22歲了
    }

}

註解

JDK1.5後的新特性,對元素進行說明註釋,用於編譯檢查、生成doc文件、程式碼分析

1自帶註解

@Override

檢測被該註解標註的方法是否是繼承自父類(介面)

@Deprecated

該註解標註的內容,表示已過時

@SuppressWarnings

壓制警告,可傳引數all,如@SuppressWarnings("all")

2自定義註解

1)格式

元註解
Public @interface MyAnno{

}

2)本質

註解的本質是一個介面,將其編譯後再進行反編譯,發現其是一個繼承自java.lang.annotation.Annotation的介面

3)屬性

指介面中定義的抽象方法,具有返回值

(1)返回值型別

int,String,列舉,註解及以上資料型別的陣列

(2)屬性賦值

使用屬性前需要給屬性賦值,設定default預設值的可不賦值

只有一個屬性需要賦值,且屬性名是value,可省略value並直接賦值

陣列賦值時,需用{}包裹,只有一個值時,{}可省略

4)元註解

對註解進行註釋

(1)@Target

描述註解的作用範圍,引數分別是ElementType.TYPE類,ElementType.METHOD方法,ElementType.FIELD成員變數

(2)@Retention

註解被保留的階段,引數常用RetentionPolicy.RUNTIME

(3)@Documented

註解是否被抽取到api文件中

(4)@Inherited

闡述了某個被標註的型別是被繼承的

3獲取類的註解

獲取到類的class物件時,呼叫該物件的getAnnotation(註釋名.class)方法

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
    public String name();
    public int age();
}
@MyAnno(name="zhanghuan",age=22)
public class Hello{
    public static void main(String[] args) {
        Class<Hello> hello=Hello.class;
        MyAnno an= hello.getAnnotation(MyAnno.class);
        //此方法相當於建立一個MyAnno的子類實現物件
        /*類似於以下的類
            class abc implements MyAnno{
                String name;
                int age;
                public abc(String name, int age) {
                    this.name = name;
                    this.age = age;
                }
                @Override
                public String name() {
                    return this.name;
                }
                @Override
                public int age() {
                    return this.age;
                }
            }
         */
        System.out.println(an.name());//zhanghuan
        System.out.println(an.age());//zhanghuan
    }

}

4測試案例

//定義註解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Check {
}
//定義類,並在需要測試的方法上標註註解
public class Calculator {
    @Check
    public static int add(int a,int b){
        return a+b;
    }
    @Check
    public static int subtract(int a,int b){
        return a-b;
    }
    @Check
    public static int multiply(int a,int b){
        return a*b;
    }
    @Check
    public static int divide(int a,int b){
        return a/b;
    }
}
//定義測試類
public class TestCalculator {
    public static void main(String[] args) throws ClassNotFoundException, IOException {
        Class cal=Class.forName("aaa.Calculator");
        Method[] m=cal.getMethods();
        BufferedWriter bw=new BufferedWriter(new FileWriter("bug.txt"));
        int num=0;
        for (Method method:
             m) {
            if(method.isAnnotationPresent(Check.class)){
                try {
                    Object result = method.invoke(cal.getInterfaces(), 10, 0);
                    System.out.println(result);
                }catch (Exception e){
                    num++;
                    bw.write(method.getName()+"()方法出異常了");
                    bw.newLine();
                    bw.write(e.toString());
                    bw.newLine();
                    bw.write("___________________________________");
                    bw.newLine();
                }
            }
        }
        bw.write("一共測出了"+num+"個異常");
        bw.close();
    }
}

Mysql

1資料檔案刪除

在mysql的安裝目錄可找到init檔案,開啟後找到有一行為datadir="c:\ProgrData\MySql\MySqlServer5.5\",找到該路徑,刪除裡面的檔案即可

2常用命令

//開啟服務視窗
Service.msc

//停止服務
net stop mysql

//開啟服務
net start mysql

//登陸伺服器
mysql -h127.0.0.1 -uroot -p

//登陸伺服器方式二
myql --host=ip --user=root --password=abc

//退出mysql
exit

3SQL結構化查詢語言

操作所有關係型資料庫的規則

1)語法規則

(1)SQL語言可單行、多行書寫,以分號結尾

(2)使用空格和縮排來則鞥去語句的可讀性

(3)mysql的SQL語言不區分大小寫,建議關鍵詞大寫

(4)註釋,--或#為單行註釋,其中#為mysql獨有;/**/為多行註釋

2)分類

(1)DDL(Data Defining langrage)定義語言

定義資料庫物件:資料庫,表,列等,如crete,drop,alter

(2)DML(Data Manipulation langrage)操作語言

對錶中資料進行增、刪、改,如insert,delete,update

(1)DQL(Data Query langrage)查詢語言

查詢表中記錄,如select where

(1)DCL(Data Control langrage)控制語言

定義訪問許可權和安全級別,如GRANT,REVOKE

5對資料庫的操作

1)建立

//建立一個名為db1的資料庫
create database db1;

//建立一個資料庫db1(如果db1不存在才建立)並設定字符集為gbk
create database if not exists db1 character set gbk;

2)查詢

//檢視所有資料庫
show databases;

//檢視資料庫db1的建立語句
show create database db1;

3)修改

//將資料庫db1的字符集修改為utf8
alter database db1 character set utf8;

4)刪除

//刪除資料庫db1
drop database db1;

//刪除資料庫db1(如果存在才刪除)
drop database if exists db1;

5)使用資料庫

//檢視正在使用的資料庫
select database();

//使用資料庫db1
use db1;

6對錶的操作

1)建立

//建立一個名為student的表
create table student(
	name vachar(20),
	age int(2)
);
//複製表student
create table stu like student;

資料型別

資料型別 說明
int 整數,有符號的整數範圍在正負21億之間。宣告時需要傳入一個引數size,即整數的長度
double 雙精度浮點數。宣告時需要傳入兩個引數,分別指小數點左側數的長度和小數點右側數的長度
varchar 可變長度字串,長度不超過255個字元。宣告時需要傳入字串的長度
date 包含年月日的日期
datetime 包含年月日時分秒的日期
timestamp 包含年月日時分秒的時間戳,插入資料時會自動擷取當前時間存入

2)查詢

//查詢所有表
show tables;

//查詢表結構
dest student;

3)修改

(1)修改表名

alter table 表名 rename to 新表名;

(2)修改字符集

alter table 表名 character set 字符集名稱;

(3)新增列

alter table 表名 add 列名 資料型別;

(4)修改列名稱及其資料型別

alter table 表名 modify 列名 新列名 新資料型別;

(5)刪除列

alter table 表名 drop 列名;

4)刪除

//刪除表student
drop table student

//刪除表student(如果存在才刪除)
drop table if exists student

7對資料操作

1)新增資料

insert into 表名(列名1,列名2) values(值1,值2);

注意

1.列名和值必須一一對應

2.表名後不寫列名,表示給所有列增加值

3.除數字外嗎,其他型別的值都需要用引號包裹

2)刪除資料

delet form 表名 [where條件]

注意

1.如果不加條件,表示刪除表中所有資料

2.如果要刪除表中所有資料,推薦使用TRUNCATE TABLE 表名,效率高,其原理是刪除表後再重新建立一張同名表

3)修改資料

update 表名 set 列名1=值1,列名2=值2 [where條件]

注意

如果不加條件,表中所有資料將會被修改

7查詢表中資料

1)語法

select
	欄位1,欄位2……
from 
	表1,表2……
where
	條件列表
goroup by
	分組欄位
having
	分組之後條件
order by
	排序
limit
	分頁

2)基礎查詢

(1)去除重複結果

SELECT DISTINCT adress from student;

(2)計算列

SELECT name,math,english,math+IFNULL(english,0) FROM student;

IFNULL(english,0)是指如果english為null,當作0來處理

(3)起別名

//AS來替代欄位名進行顯示,AS可省略
SELECT name AS 姓名,math AS 數學,english AS 英語,math+IFNULL(english,0) AS 總分 FROM student;

(4)條件查詢

除了常規的運算子

<,>,>=,<=,=,!=,<>

還有

//BWTWEEN AND
SELECT name,math,english FROM student where math BETWEEN 70 AND 80;
//AND
SELECT name,math,english FROM student where math>70 AND math<80;
//OR
SELECT name,math,english FROM student where math<70 OR math>80;
//IN
SELECT name,math,english FROM student where math IN (50,52,64);

如果資料內容是null,則不可以用判斷

//找出english是null的資料
SELECT name,math,english FROM student where english IS NULL;
//找出english不是null的資料
SELECT name,math,english FROM student where english IS NOT NULL;

模糊查詢LIKE

SELECT name,math,english FROM student where name LIKE "%傑_";
/*
%是多個字元的佔位符
_是單個字元的佔位符
*/

(5)排序查詢

//將結果math進行預設排序(升序)
SELECT name,math,english FROM student ORDER BY math;
//將結果math進行升序排列
SELECT name,math,english FROM student ORDER BY math ASC;
//將結果math進行降序排列
SELECT name,math,english FROM student ORDER BY math DESC;

注意

1.預設按升序排列

2.有多個排序條件,則前面條件值一樣時,才會使用後面的排序條件

(6)聚合函式

將一列資料作為一個整體,縱向計算。包含COUNT,MAX,MIN,SUM,AVG

//計數
SELECT COUNT(name) FROM student;
//求最大值
SELECT MAX(math) FROM student;
//求最小值
SELECT MIN(math) FROM student;
//求和
SELECT SUM(math) FROM student;
//求平均
SELECT AVG(math) FROM student;

注意

聚合函式計算時會排除掉值為null的資料

(7)分組查詢

一般和聚合函式合用

SELECT AVG(math) FROM student GROUP BY male;

where和having的區別

/*
1.where在執行分組操作前限定,having在執行分組操作後限定
2.where後不可跟聚合函式
3.having子句中可以使用欄位別名,而where不能使用
*/

SELECT SUM(math) AS 數學 FROM `student` GROUP BY male HAVING 數學>150;

(8)分頁

LIMIT 開始索引,每頁條數

公式:開始索引=(當前頁碼-1)*每頁條數

只有mysql的分頁是limit,其他資料庫軟體不一樣

8約束

對錶中資料進行限定,保證資料的正確性、有效性、完整性。分為:

主鍵約束(primarykey)、非空約束(notnull)、唯一約束(unique)、外來鍵約束(foreignkey)

1)非空約束

//建立表時新增索引
CREATE TABLE stu(
	id int NOTNULL,
	name varchar(20)
)

//建表後新增索引
ALTER TABLE stu MODIFY name VARCHAR(20) NOTNULL;

//刪除索引
ALTER TABLE stu MODIFY name VARCHAR(20);

2)唯一索引

//新增索引
ALTER TABLE stu MODIFY id INT UNIQUE;

//新增索引方式二
ALTER TABLE stu ADD UNIQUE(id);

//刪除索引
ALTER TABLE stu DROP INDEX id;

唯一索引裡的值可以為多個null

3)主鍵索引

//新增
ALTER TABLE student MODIFY id INT PRIMARY KEY;

//刪除
ALTER TABLE student DROP PRIMARY KEY;

//新增自增
ALTER TABLE student MODIFY id INT AUTO_INCREMENT;

//刪除自增
ALTER TABLE student MODIFY id INT;

非空且唯一

4)外來鍵約束

//建立方式一
CREATE TABLE employee(
	dep_id INT,
	CONSTRAINT enp_dep_fk FOREIGN KEY (dep_id) REFERENCES department(id)
);
//需要注意,department.id必須是主鍵,否則報錯;外來鍵名enp_dep_fk可省略

//建立方式二
ALTER TABLE employee ADD CONSTRAINT enp_dep_fk FOREIGN KEY (dep_id) REFERENCES department(id);

//刪除外來鍵
ALTER TABLE employee DROP FOREIGN KEY enp_dep_fk;

//建立帶級聯的外來鍵
ALTER TABLE employee ADD CONSTRAINT enp_dep_fk FOREIGN KEY (dep_id) REFERENCES department(id) ON UPDATE CASCADE ON DELETE CASCADE;

9資料庫設計的正規化

1)函式依賴

A屬性值可確定唯一B屬性值,則B依賴於A

2)完全依賴

A為屬性組,B屬性值的確定需依賴A屬性組中所有的屬性值

3)部分依賴

A為屬性組,B屬性值的確定需依賴A屬性組中部分的屬性值

4)傳遞依賴

C屬性值依賴於B屬性值,B屬性值依賴於A屬性值,那麼C屬性值傳遞依賴於A屬性值

5)碼

屬性或屬性組被其他屬性完全依賴,那麼這個屬性或屬性組稱為碼

6)主屬性和非主屬性

碼是主屬性,其他的屬性是非主屬性

正規化 特點
第一正規化 資料冗餘,存在函式依賴,出現新增異常和刪除異常
第二正規化 消除非主屬性對主屬性的部分函式依賴,但仍出現新增異常和刪除異常
第三正規化 所有主屬性不依賴於其他非主屬性,消除傳遞依賴

10備份和還原

1)備份

mysql dump -u使用者名稱 -p密碼 資料庫名稱 >路徑

2)還原

//登陸資料庫、建立資料庫、使用資料庫

//執行命令,其中a.sql是備份的資料庫檔案
source a.spl

9多表查詢

1)笛卡兒積

兩個集合A、B,取這兩個集合的所有組合情況

2)隱式內聯接

SELECT
	t1.time,t1.gender,t1.name
FROM
	emp t1,dep t2
WHRER
	t1.dept_id=t2.id;

內聯接查詢的是兩張表的交集

3)顯式內聯接

SELECT * FROM exp INNER JOIN dept ON emp.dep_id=dept.id;

4)左外聯接

SELECT 欄位列表 FROM 表1 LEFT JOIN 表2 ON 條件;

查詢的是左表所有的資料交集部分

5)右外聯接

SELECT 欄位列表 FROM 表1 RIGHT JOIN 表2 ON 條件;

查詢的是右表所有的資料交集部分

6)子查詢

(1)子查詢結果單列、單行

SELECT * FROM emp WHERE salary=(SELECT MAX(salary) FROM emp);

(2子查詢結果單列、多行

SELECT * FROM emp WHERE id IN (SELECT id FROM emp WHERE salary>5000);

(3)子查詢結果多列、多行

SELECT
	* 
FROM
	(SELECT * FROM emp WHERE salary>5000) t1,dep t2 
WHERE
	t1.dept_id=t2.id;

10事務

一個包含多個步驟的操作,要麼成功,要麼失敗

START TRANSACTION;//開啟事務
……
COMMIT;//提交

1)事務提交的兩種方式

(1)自動提交

mysql預設自動提交,一個增、刪、改操作時,會自動提交一次事務

(2)手動提交

需開啟事務再提交,oracle預設是手動提交

2)修改事務提交的方式

(1)檢視

SELECT @@autocommit;

1為自動提交,0為手動提交

(2)修改

SET @@autocommit=0;

3)事務的四大特徵

原子性:不可分割的最小單位,要麼成功要麼失敗

永續性:提交後會永續性儲存

隔離性:事務之間相互獨立

一致性:資料操作前後總量不變

4)事務隔離級別

(1)事務操作存在的問題

髒讀:一個事務讀取到另一個事務沒有提交的資料

不可重複讀:同一事務,兩次讀到的資料不同

幻讀:一個事務運算元據表中的所有記錄,另一個事務新增一條資料,則第一個事務讀不到自己的修改

(2)隔離級別

隔離級別 存在問題
read uncommitted 髒讀、不可重複讀、幻讀
read committed(oracle預設) 不可重複讀、幻讀
repeatable(mysql預設) 幻讀
serializable

級別從小到大,安全性越來越高,效率越來越低

(3)查詢隔離級別

SELECT @@tx_isolation;

(4)設定隔離級別

SET GLOBAL TRANSACTION ISOLATION LEVAL 級別字串;

11管理使用者

1)檢視使用者

USE mysql;
SELECT host,user,password FROM user;

2)建立使用者

CREATE user '使用者名稱'@'主機名' IDENTIFIED BY '密碼';

3)刪除使用者

DROP user '使用者名稱'@'主機名';

4)修改密碼

UPDATE user SET password=PASSWORD('新密碼') WHERE user='使用者名稱';

5)忘記root密碼

(1)停止mysql,net stop mysql;

(2)使用無驗證方式啟動mysql,mysql --skip -grant-tables

(3)在cmd中輸入mysql,無需輸入賬號密碼進入

(4)改密碼

(5)重啟mysql

6)檢視許可權

SHOW GRANTS FOR '使用者名稱'@'主機名';

7)授予許可權

GRANT 許可權列表 ON 資料庫名,表名 TO '使用者名稱'@'主機名';

//授予全部許可權
GRANT All ON *.* TO 'zhanghuan'@'%';

許可權分別是select,delete,update,all

8)撤銷許可權

REVOKE 許可權列表 ON 資料庫名,表名 FROM '使用者名稱'@'主機名';

JDBC

簡單來說,java語言運算元據庫。官方定義一套操作所有關係型資料庫的規則(介面),由各個資料庫廠商實現這套介面,提供給開發者驅動資料庫的jar包。

1快速入門

(1)匯入jar包

複製jar包到新建的libs資料夾,add as library

(2)註冊驅動

(3)獲取資料庫連線物件Connection

(4)定義sql

(5)獲取執行sql語句的物件statement

(6)執行sql,接收返回結果

(7)處理結果

(8)釋放資源

2常用物件

物件
DriverMannager 驅動管理物件
Connection 資料庫連線物件
Statement 執行sql的物件
ResultSet 結果集物件
PreparedSteatment 執行sql的物件

3DriverMannager

(1)註冊驅動

//driver類的成員方法
static void registerDriver(Driver driver);

mysql5之後的驅動可省略註冊

//原始碼摘取自driver
static {
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }
//寫入該句則完成註冊
Class.forName("com.mysql.jdbc.Driver");

(2)獲取資料庫連線

static Connection getConnection(String url,String user,String password);

url格式 jdbc:mysql://localhost:3306/db3,連線本機資料庫可省略localhost:3306

4Connection

(1)獲取執行sql的物件

Statement createStatement();
PreparedStatement PrepareStatement(String sql);

(2)獲取資料庫連線

開啟:setAutoCommit(boolean autoCommit),引數欸false,開啟事務

提交:commit()

回滾:rollback()

5Statement

(1)boolean execute(String sql)

執行任何sql語句,不常用

(2)int executeUpdate(String sql)

執行DML語句(insert,update,delete)。執行DDL時,返回值為0;返回值為影響的行數,可透過影響的行數判斷是否執行成功,返回值>0執行成功,反之執行失敗。

(3)ResultSet executeQuery(String sql)

執行DQL語句(select)

6ResultSet結果集物件

//遊標向下移動一行,判斷當前位置是否位於最後一行,如果是返回值false
boolean next();

//獲取資料,可傳入兩種型別的引數,傳入int型別時,該引數代表列號;傳入String型別時,該引數代表列名
int getInt(引數);
String getString(引數);
import java.sql.*;

public class TestCalculator {
    public static void main(String[] args) throws ClassNotFoundException {
        //註冊
        Class.forName("com.mysql.jdbc.Driver");
        try (Connection con = DriverManager.getConnection("jdbc:mysql:///test1","root","")) {//連線資料庫

            String sql="select * from student";
            //獲取執行sql的物件
            Statement st=con.createStatement();
            //執行sql語句
            ResultSet rs=st.executeQuery(sql);
            while (rs.next()){
                System.out.println(rs.getString(1)+" "+rs.getString(2)+" "+rs.getString(3)+" "+rs.getString(4)+" "+rs.getString(5));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

7PreparedSteatment

在拼接sql時,當有一些sql特殊關鍵字引數與字串拼接時,會造成安全問題,此時使用PreparedSteatment來解決

PreparedStatement Connection.PrepareStatement(String sql);
import java.sql.*;

public class TestCalculator {
    public static void main(String[] args) throws ClassNotFoundException {
        //註冊
        Class.forName("com.mysql.jdbc.Driver");
        try (Connection con = DriverManager.getConnection("jdbc:mysql:///test1","root","")) {//連線資料庫

            String sql="select * from student where id=?";
            
            //獲取執行sql的物件
            PreparedStatement st=con.prepareStatement(sql);
            //給問號賦值
            st.setString(1,"1");
            //執行sql語句
            ResultSet rs=st.executeQuery();
            while (rs.next()){
                System.out.println(rs.getString(1)+" "+rs.getString(2)+" "+rs.getString(3)+" "+rs.getString(4)+" "+rs.getString(5));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

8JDBCutils

(1)獲取配置檔案路徑

import java.net.URL;

public class JDBCutils {
    public static void main(String[] args) {
        ClassLoader cl=JDBCutils.class.getClassLoader();
        URL res=cl.getResource("jdbc.properties");//jdbc.properties檔案必須在根目錄下才可讀出
        String path=res.getPath();
        System.out.println(path);// /C:/Users/admin/IdeaProjects/untitled1/out/production/untitled1/jdbc.properties
    }
}

(2)完整實現

//配置檔案jdbc.properties
url=jdbc:mysql:///test1
user=root
password=
driver=com.mysql.jdbc.Driver
//JDBCutils
import java.io.FileReader;
import java.net.URL;
import java.sql.*;
import java.util.Properties;

public class JDBCutils {
    static  String url=null;
    static String user=null;
    static String password=null;
    static String driver=null;
    static{
        try {
            //獲取配置檔案路徑
            ClassLoader cl=JDBCutils.class.getClassLoader();
            URL res=cl.getResource("jdbc.properties");//jdbc.properties檔案必須在根目錄下才可讀出
            String path=res.getPath();

            //讀取配置檔案
            Properties p=new Properties();
            p.load(new FileReader(path));
            url=p.getProperty("url");
            user=p.getProperty("user");
            password=p.getProperty("password");
            driver=p.getProperty("driver");

            //註冊驅動
            Class.forName(driver);
        }catch (Exception e){
            System.out.println(e);
        }
    }
    public static Connection getConnection(){//獲取連線
        Connection con=null;
        try {
            con = DriverManager.getConnection(url, user, password);
        }catch (Exception e){
            System.out.println(e);
        }
        return con;
    }

    public static void close(ResultSet res, Statement st,Connection conn){//釋放資源
        if(res!=null){
            try {
                res.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(st!=null){
            try {
                st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
//使用JDBCutils
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class Hello{
    public static void main(String[] args) {
        Connection con=JDBCutils.getConnection();
        PreparedStatement st=null;
        ResultSet rs=null;

        String sql="select * from student where id=?";
        try{
            st = con.prepareStatement(sql);
            st.setString(1,"2");
            rs=st.executeQuery();
            while (rs.next()){
                System.out.println(rs.getString(1)+" "+rs.getString(2)+" "+rs.getString(3)+" "+rs.getString(4));
            }
        }catch (Exception e){
            System.out.println(e);
        }finally {
            JDBCutils.close(rs,st, con);
        }
    }

}

9事務

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Hello{
    public static void main(String[] args) {
        Connection con=JDBCutils.getConnection();
        Statement st=null;
        ResultSet rs=null;


        try{
            con.setAutoCommit(false);//開啟事務
            st = con.createStatement();
            int res1=st.executeUpdate("update employee set salary=salary+500 where id=1");
            System.out.println(res1);
            int res2=st.executeUpdate("update employee set salary=salary-500 where id=2");
            System.out.println(res2);
            con.commit();//提交事務
        }catch (Exception e){
            try {
                con.rollback();//回滾事務
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            System.out.println(e);
        }finally {
            JDBCutils.close(rs,st, con);
        }
    }

}

10資料庫連線池

當初始化後,容器被建立,容器會申請一些連線物件,當使用者訪問資料庫時,從池中取出連線物件進行連線;使用者訪問完後,將連線物件歸還給容器

(1)c3p0

//1.匯入兩個jar包,注意需先匯入mysql驅動包
//2.定義配置檔案,名稱c3p0.properties或c3p0-config.xml,放在src即可
//3.獲取連線物件new ComboPooledDataSource()
//4.獲取連線getConnection
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

public class Hello{
    public static void main(String[] args) {
        DataSource ds = new ComboPooledDataSource();//建立資料庫連線池
        Connection con=null;
        Statement st=null;
        ResultSet rs=null;
        try{
            con=ds.getConnection();//獲取連線
            System.out.println(con);
            st=con.createStatement();
            rs=st.executeQuery("select * from student");
            while (rs.next()){
                System.out.println(rs.getString(1));
            }
        }catch (Exception e){
            System.out.println(e);
        }finally {
            JDBCutils.close(rs,st,con);
        }
    }

}

配置檔案

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <!-- 這是預設配置資訊 -->
    <default-config>
        <!-- 連線四大引數配置 -->
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/test1</property>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="user">root</property>
        <property name="password"></property>
        <!-- 池引數配置 -->
        <property name="acquireIncrement">3</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">2</property>
        <property name="maxPoolSize">10</property>
    </default-config>

    <!-- 專門為oracle提供的配置資訊 -->
    <named-config name="oracle-config">
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb1</property>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="user">root</property>
        <property name="password">123</property>
        <property name="acquireIncrement">3</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">2</property>
        <property name="maxPoolSize">10</property>
    </named-config>
</c3p0-config>

(2)druid

//1.匯入jar包
//2.定義配置檔案
//3.載入配置檔案
//4.配置檔案手動傳入,並獲取連線物件
//5.獲取連線
import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;

public class Hello{
    public static void main(String[] args) throws IOException {
        Properties p=new Properties();
        p.load(Hello.class.getClassLoader().getResourceAsStream("druid.properties"));
        try {
            DataSource ds = DruidDataSourceFactory.createDataSource(p);//建立連線物件
            Connection con=ds.getConnection();//獲取連線
            Statement st=con.createStatement();
            ResultSet rs=st.executeQuery("select * from student");
            while (rs.next()){
                System.out.println(rs.getString(1));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

封裝工具類

# druid.properties檔案的配置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test1
username=root
password=
# 初始化連線數量
initialSize=5
# 最大連線數
maxActive=10
# 最大超時時間
maxWait=3000
//DRUIDutils
import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;

public class DRUIDutils {
    static Properties p=new Properties();
    static{
        try {
            p.load(DRUIDutils.class.getClassLoader().getResourceAsStream("druid.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static Connection getConnection(){//獲取連線
        Connection con=null;
        try {
            con=getDataSource().getConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return con;
    }
    public static DataSource getDataSource() throws Exception {//獲取datasource
        return DruidDataSourceFactory.createDataSource(p);
    }
    public static void close(ResultSet res, Statement st, Connection conn){//釋放資源
        if(res!=null){
            try {
                res.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(st!=null){
            try {
                st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    public static void close(Statement st, Connection conn){//釋放資源過載方法
        if(st!=null){
            try {
                st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

}
//測試DRUIDutils
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

public class Hello{
    public static void main(String[] args) throws IOException {
        Connection con=null;
        Statement st=null;
        ResultSet rs=null;
        try {
            con=DRUIDutils.getConnection();//獲取連線
            st=con.createStatement();
            rs=st.executeQuery("select * from student");
            while (rs.next()){
                System.out.println(rs.getString(1));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            DRUIDutils.close(rs,st,con);
        }
    }

}

(3)SpringJDBC

Spring框架對JDBC的簡單封裝,提供一個JDBCTemplate物件簡化JDBC的程式碼

//1.匯入jar包,共5個
//2.建立JdbcTemplate物件,依賴於資料來源DataSource
JdbcTemplate template=new JdbcTemplate(ds)
//3.呼叫JdbcTemplate的方法進行CRUD操作
import org.springframework.jdbc.core.JdbcTemplate;

public class Hello{
    public static void main(String[] args) throws Exception {
        JdbcTemplate template=new JdbcTemplate(DRUIDutils.getDataSource());
        String sql="update employee set salary=5000 where id=?";
        int rs=template.update(sql,1);//執行sql
        System.out.println(rs);
    }

}

常用CRUD操作

update();//執行DML語句,增刪改語句
queryFormap();//查詢結果封裝乘map集合,結果集長度只可是1
queryForList();//查詢結果封裝成list集合
query();//查詢結果封裝成JavaBean物件
queryForObject();//查詢結果封裝成物件,查詢聚合函式
import org.junit.jupiter.api.Test;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;
import java.util.Map;

public class Hello{
    public static void main(String[] args) throws Exception {
        JdbcTemplate template=new JdbcTemplate(DRUIDutils.getDataSource());
        String sql=null;

        //queryForMap
        sql="select * from student where id=1";
        Map<String, Object> m=template.queryForMap(sql);
        System.out.println(m);
        //{id=1, male=男, name=周杰倫, math=78, english=81}

        //queryForList
        //將每一條記錄封裝成一個map集合,再將map集合封裝到list集合中
        sql="select * from student";
        List<Map<String,Object>> list_of_map=template.queryForList(sql);
        System.out.println(list_of_map);

        //query
        //將資料封裝成javabean物件並返回一個javabean物件的list集合
        sql="select * from student";
        List<student> list_of_bean=template.query(sql,new BeanPropertyRowMapper<student>(student.class));
        System.out.println(list_of_bean);

        //queryForObject
        //執行包含聚合函式的sql
        sql="select count(*) from student";
        Long count=template.queryForObject(sql,Long.class);
        System.out.println(count);
    }
    @Test//可單獨執行方法
    public void run(){
        System.out.println("hello");
    }

}

Tomcat

1JAVAEE

java語言在企業計數規範的總和,一共規定了12項大的規範

2主流服務軟體

軟體名 特點
weblogic oracle公司,收費
websophere ibm公司,收費
jboss jboss公司,收費
tomcat apache組織,免費

3tomcat檔案目錄

目錄 功能
bin 二進位制執行檔案
conf 配置檔案
lib 依賴jar包
logs 日誌檔案
temp 臨時檔案
webapps 存放的web專案
work 執行時資料

4啟動和關閉

1)啟動

bin目錄下,執行startup.bat,在localhost:8080訪問

可能遇到問題

(1)黑視窗一閃而過

未正確配置java環境變數JAVA_HOME

(2)啟動報錯

8080埠被佔用,要麼殺程序,要麼在conf.server.xml修改埠號

2)關閉

bin目錄下,執行shutdown.bat或者在服務視窗ctrl+c

5部署

1)將專案放到webapps目錄下

專案可打包成war,將war包防止到webapps目錄下

2)配置conf/server.xml檔案

新增一行<Contex docBase="D\hello" path"/hehe/">

3)在conf/Catalina/localhost下建立任意名的xml檔案

檔案內容是<Contex docBase="D\hello" >,連線中訪問的path路徑就是xml的檔名

6動態專案的目錄結構

--專案根目錄
	--WEB-INF
	--web,xml//web專案的核心配置檔案
	--classes//放置位元組碼檔案的目錄
	--lib//放置依賴的jar包

7將tomcat部署到IDEA中

1)配置tomcat

run->edit configrations->templates->tomcat server->local

把tomcat的安裝路徑設定上

2)建立JAVAEE專案

file->new project->java enterprise

選中web application後點選下一步

輸入專案名點選下一步,然後執行


servlet

執行在伺服器上的小程式,本質上是一個介面

1快速開始

1.建立javaee專案
2.定義類,實現Servlet
3.實現抽象方法
4.配置url,如配置web.xml檔案
//建立一個實現Servlet的類
import javax.servlet.*;
import java.io.IOException;

public class abc implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("service……");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}
//web.xml將新建的實現類註冊進去,並配置url
<?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">
    <servlet>
        <servlet-name>demo01</servlet-name>
        <servlet-class>abc</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>demo01</servlet-name>
        <url-pattern>/demo01</url-pattern>
    </servlet-mapping>
</web-app>

2執行原理

1)伺服器接收客戶端瀏覽器的請求後,會解析請求的url路徑,獲取訪問的servlet資源路徑

2)查詢web.xml檔案是否由對應的內容,如果由有將其對應的類載入到記憶體,並執行其方法

3servlet生命週期

1)被建立

建立後會執行一次實現類的init方法,預設情況是在第一次訪問實現類對應的url時才會被建立,這裡可以在web.xml檔案中配置成伺服器啟動時建立

<?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">
    <servlet>
        <servlet-name>demo01</servlet-name>
        <servlet-class>abc</servlet-class>
        <load-on-startup>2</load-on-startup><!--正數或0表示服務啟動時載入類,負數表示訪問url時載入類-->
    </servlet>
    <servlet-mapping>
        <servlet-name>demo01</servlet-name>
        <url-pattern>/demo01</url-pattern>
    </servlet-mapping>
</web-app>

2)提供服務

每次呼叫servlet時,其service方法被執行一次

3)被銷燬

在servlet被銷燬前,執行destroy方法

總之,servlet是單例的,不要哦在servlet中定義變數,即使定義了,也不要修改值

4註解配置url

在servlet3.0中,支援註解配置url,不再需要web.xml

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

@WebServlet("/demo")//註解配置url
public class abc implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init……");
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("service……");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

5IDEA中的tomcat

1)IDEA為每一個tomcat部署的專案單獨建立一份配置檔案

2)IDEA會將工作空間裡的專案複製到tomcat上部署

3)WEB-INF目錄下的資源無法被訪問

4)端點除錯,需要使用小蟲子啟動

5servlet的實現類

1)GenericServlet

該類是servlet的實現類,有一個抽象方法service

//原始碼摘取
public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

2)HttpServlet

常需重寫doGet和doPost方法

//原始碼摘取
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String method = req.getMethod();
    long lastModified;
    if (method.equals("GET")) {
        lastModified = this.getLastModified(req);
        if (lastModified == -1L) {
            this.doGet(req, resp);
        } else {
            long ifModifiedSince;
            try {
                ifModifiedSince = req.getDateHeader("If-Modified-Since");
            } catch (IllegalArgumentException var9) {
                ifModifiedSince = -1L;
            }

            if (ifModifiedSince < lastModified / 1000L * 1000L) {
                this.maybeSetLastModified(resp, lastModified);
                this.doGet(req, resp);
            } else {
                resp.setStatus(304);
            }
        }
    } else if (method.equals("HEAD")) {
        lastModified = this.getLastModified(req);
        this.maybeSetLastModified(resp, lastModified);
        this.doHead(req, resp);
    } else if (method.equals("POST")) {
        this.doPost(req, resp);
    } else if (method.equals("PUT")) {
        this.doPut(req, resp);
    } else if (method.equals("DELETE")) {
        this.doDelete(req, resp);
    } else if (method.equals("OPTIONS")) {
        this.doOptions(req, resp);
    } else if (method.equals("TRACE")) {
        this.doTrace(req, resp);
    } else {
        String errMsg = lStrings.getString("http.method_not_implemented");
        Object[] errArgs = new Object[]{method};
        errMsg = MessageFormat.format(errMsg, errArgs);
        resp.sendError(501, errMsg);
    }

}

6url定義

1)/xx

2)/xx/xx

3)*.do


HTTP

定義的客戶端與服務端通訊的資料格式

特點:

基於TCP/IP協議,預設埠為80,基於請求、響應模型,無狀態

版本

1.0每次請求、響應會重新建立連線,1.1複用連線

1請求訊息的資料格式

1)請求行

2)請求頭

3)請求空行

4)請求體

2GET和POST

GET請求的引數在請求行的url中,url裡的資料長度有限制

POST請求的引數在請求體中,長度無限制

3請求頭中的refer

標記該請求的跳轉來源,用於防盜鏈和統計

4request物件基礎體系結構

ServletRequest	介面
	|繼承
HttpServletRequest	介面
	|繼承
org.appache.catalina.connector.RequestFacade	tomcat建立的實現類

5request的功能

1)獲取獲取請求訊息資料

import javax.servlet.*;
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("/demo1")
public class abc extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1)獲取請求方式
        String m=req.getMethod();
        System.out.println(m);//GET
        //2)獲取虛擬目錄
        String cp=req.getContextPath();
        System.out.println(cp);//
        //3)獲取servlet路徑
        String sp=req.getServletPath();
        System.out.println(sp);///demo1
        //4)獲取get請求引數
        String qs=req.getQueryString();
        System.out.println(qs);//null
        //5)獲取uri
        String uri=req.getRequestURI();
        StringBuffer url=req.getRequestURL();
        System.out.println(uri);//demo1
        System.out.println(url);//http://localhost:8081/demo1
        //6)獲取協議版本
        String ptc=req.getProtocol();
        System.out.println(ptc);//HTTP/1.1
        //7)獲取客戶機ip地址
        String rma=req.getRemoteAddr();
        System.out.println(rma);//0:0:0:0:0:0:0:1
    }

}

2)獲取請求頭資料

import javax.servlet.*;
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.Enumeration;

@WebServlet("/demo1")
public class abc extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Enumeration<String> headernames=req.getHeaderNames();
        while (headernames.hasMoreElements()){
            System.out.println(headernames.nextElement());//獲取請求頭的鍵
        }
        /*
        host
        connection
        cache-control
        upgrade-insecure-requests
        user-agent
        ……
         */
    }

}
import javax.servlet.*;
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.Enumeration;

@WebServlet("/demo1")
public class abc extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String agent=req.getHeader("user-agent");//獲取請求頭某個鍵對應的值
        System.out.println(agent);
        //Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36 Edg/81.0.416.62
    }

}

3)獲取請求體資料

import javax.servlet.*;
        import javax.servlet.annotation.WebServlet;
        import javax.servlet.http.HttpServlet;
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;

@WebServlet("/demo1")
public class abc extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("dopost....");
        BufferedReader br=req.getReader();//獲取字元輸入流
        char[] data=new char[1024];
        int len;
        while ((len=br.read(data))!=-1){
            System.out.println(data);
        }
        //username=2323&password=232323
    }


}
import javax.servlet.*;
        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("/demo1")
public class abc extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("dopost....");
        ServletInputStream sis=req.getInputStream();//獲取位元組輸入流
        byte[] b=new byte[1024];
        int len;
        while ((len=sis.read(b))!=-1){
            System.out.println(new String(b));
        }
        //username=2323&password=232323
    }

}

4)其他方法

import javax.servlet.*;
        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.Enumeration;
import java.util.Map;
import java.util.Set;

@WebServlet("/demo1")
public class abc extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //獲取引數值
        String username=req.getParameter("username");
        System.out.println(username);//zhanghuan
        
        //獲取引數值的陣列
        String[] vls=req.getParameterValues("hobby");
        System.out.println(Arrays.toString(vls));//[basketball, football]
        
        //獲取引數的鍵集合
        Enumeration<String> names=req.getParameterNames();
        while (names.hasMoreElements()){
            System.out.println(names.nextElement());
        }
        /*
        username
        password
        hobby
         */
        
        //獲取引數的鍵值對
        Map<String,String[]> mp=req.getParameterMap();
        Set<Map.Entry<String, String[]>> set=mp.entrySet();
        for(Map.Entry<String,String[]> i:set){
            System.out.println(i.getKey()+"="+Arrays.toString(i.getValue()));
        }
        /*
        username=[zhanghuan]
        password=[2323]
        hobby=[basketball, football]
         */
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

//不管是get方式還是post方式,這些獲取引數的方法都生效

5)亂碼問題

在tomcat8以上,get方式提交的值無亂碼問題,而post方式提交的值存在亂碼

需要在doPost方法里加上

req.setCharacterEncoding("utf-8");

6)請求轉移

一種在伺服器內部的資源跳轉方式,因此瀏覽器的url不會發生變化,由於在伺服器內部轉移,所以只能轉發到伺服器內部的servlet物件,轉發過程中是伺服器自發與客戶端瀏覽器無關

req.getRequestDispatcher("/demo2").forward(req,resp);

7)共享資料

域物件:一個有作用範圍的物件,可在範圍內共享資料

request域:一次請求範圍,一般用於請求轉發的多個資源中共享資料

//設定共享值
void setAttribute(String var1, Object var2);

//獲取共享值
Object getAttribute(String var1);

//刪除共享值
void removeAttribute(String var1);

//獲取整個web應用的域物件
ServletContext getServletContext();

6)登陸案例

//目錄結構
--src
	--dao
		userdao.java
	--doMain
		user.java
	--uitil
		JDBCutils.java
	--web
		loginServlet.java
	duoid.properties
--web
	--WEB-INFO
		--lib//這裡放jar包,如果放錯位置控制太不會報錯,頁面上會報500錯誤
	index.jsp
//JDBCutils.java
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;

public class JDBCutils {
    static Properties p=new Properties();
    static {
        try {
            InputStream is=JDBCutils.class.getClassLoader().getResourceAsStream("druid.properties");
            p.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static DataSource getDataSource() {
        DataSource ds=null;
        try {
            ds = DruidDataSourceFactory.createDataSource(p);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ds;
    }
    public static Connection getConnection(){
        Connection con=null;
        try {
            con=getDataSource().getConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return con;
    }
}
//Userdao.java
package dao;

import doMain.User;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import util.JDBCutils;

public class Userdao {
    private JdbcTemplate tmplate=new JdbcTemplate(JDBCutils.getDataSource());
    public User login(User loginuser){
        try {
            String sql="select * from user where username=? and password=?";
            User user=tmplate.queryForObject(sql,new BeanPropertyRowMapper<User>(User.class),loginuser.getUsername(),loginuser.getPassword());
            return user;
        } catch (DataAccessException e) {
            e.printStackTrace();
            return null;
        }
    }
}
//user.java
package doMain;

public class User {
    private Integer id;
    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}
//LoginServlet.java
package web;

import dao.Userdao;
import doMain.User;

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("/loginservlet")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        User loginuser=new User();
        loginuser.setUsername(req.getParameter("username"));
        loginuser.setPassword(req.getParameter("password"));
        Userdao dao=new Userdao();
        System.out.println(loginuser);
        User user=dao.login(loginuser);
        if(user==null){
            System.out.println("登陸失敗");
        }else {
            System.out.println("登陸成功");
        }
        System.out.println("dopost");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}
<!--index.jsp-->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>Login</title>
  </head>
  <body>
  <form action="/login_war_exploded/loginservlet" method="post">
    <input type="text" name="username" placeholder="username"><br>
    <input type="text" name="password" placeholder="password"><br>
    <input type="submit" value="提交">
  </form>
  </body>
</html>

7)BeanUtils

主要提供了對於JavaBean進行各種操作,比如物件,屬性複製等等。使用前需匯入匯入commons-beanutils-1.8.3 包和commons-logging-1.1.3 包

注意方法 描述
public static void setProperty(Object bean, String name, Object value) 設定指定屬性的值
public static String getProperty(Object bean, String name) 獲取指定屬性的值
public static void populate(Object bean, Map<String, ? extends Object> properties) 將map資料複製到javabean中
import doMain.User;
import org.apache.commons.beanutils.BeanUtils;
import org.junit.Test;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;


public class test {
    @Test
    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
        User user=new User();
        Map<String,String> map=new HashMap<>();//Map的第二個泛型可以是陣列,執行populate時會取陣列的第一個元素
        map.put("username","zhanghuan");
        map.put("password","123456");
        BeanUtils.populate(user,map);
        System.out.println(user);//User{id=null, username='zhanghuan', password='123456'}
    }
}
/*
JavaBean
1.類必須被public修飾
2.必須提供空引數構造器
3.成員變數必須使用private修飾
4.提供公共的setter和getter方法
*/

6響應

由響應行、響應頭、響應空行、響應體組成

1)響應行格式

協議/版本 響應狀態碼 狀態碼解釋

2)狀態碼錶示資訊

狀態碼 含義
1XX 伺服器接收客戶端訊息,但沒完成,等待一段時間後,傳送1XX狀態碼
2XX 成功
3XX 重定向,304表示訪問快取,302表示重定向
4XX 客戶端錯誤,404請求路徑沒有對應的資源,405請求方式沒有對應的doXX方法
5XX 伺服器錯誤,500伺服器內部錯誤

6)響應頭

(1)Content-Type

指定資料格式及編碼

(2)Content-disposition

指定以什麼格式開啟響應體,in-line當前頁面開啟,attachment;filename=xxx以附件形式開啟響應體,用於下載

7)響應體

傳輸的資料

8)獲取虛擬目錄

req.getContextPath();

9)重定向

package web;

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("/index")
public class indexServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //方式一
        /*
        resp.setStatus(302);
        resp.setHeader("location",req.getContextPath()+"/login");
         */
        
        //方式二
        resp.sendRedirect(req.getContextPath()+"/login");

    }
}

特點:

位址列裡的地址會發生變化,可訪問其他站點的資源,傳送了兩次請求

10)字元輸出流

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.io.PrintWriter;

@WebServlet("/login")
public class loginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //設定writer的字元編碼
        resp.setCharacterEncoding("utf-8");

        //給客戶端指定字元編碼方式一
        //resp.setHeader("Content-Type","text/html;charset=utf-8");

        //給客戶端指定字元編碼方式二
        resp.setContentType("text/html;charset=utf-8");

        //獲取writer
        PrintWriter pr=resp.getWriter();
        //向響應體寫入資料
        pr.write("這是登陸頁");
    }
}

11)驗證碼案例

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Random;

public class randomPic {
    static String[] strs=null;

    public static String getRandomString(){
        String str="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        String result_str="";
        Random rd=new Random();
        for (int i = 0; i <4 ; i++) {
            int num=rd.nextInt(61);
            result_str+=Character.toString(str.charAt(num));
        }
        return result_str;
    }

    public static void drawImg(String str,OutputStream os,int width,int height){
        Random rd=new Random();

        //建立畫布
        BufferedImage img=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        //建立畫筆
        Graphics g=img.createGraphics();
        //設定畫筆顏色
        g.setColor(Color.PINK);
        //用畫筆填充畫布
        g.fillRect(0,0,width, height);

        //在畫布上寫字串
        g.setColor(Color.BLUE);
        Font f=new Font(null,Font.PLAIN,25);
        g.setFont(f);//設定字型大小
        strs=str.split("");//獲取隨機字串
        for (int i = 0; i <strs.length ; i++) {
            g.drawString(strs[i],width/4*i+8,rd.nextInt(height/4)+height/2);
        }

        //在畫布上畫干擾線
        for (int i = 0; i <10 ; i++) {
            g.drawLine(rd.nextInt(width),rd.nextInt(height),rd.nextInt(width),rd.nextInt(height));
        }

        //將圖片寫入到流中
        try {
            boolean jpg = ImageIO.write(img, "jpg", os);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
import doMain.randomPic;

import javax.imageio.ImageIO;
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("/login")
public class loginServlet extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String str=randomPic.getRandomString();//獲取隨機字串
        System.out.println(str);
        ImageIO.setUseCache(false);//使用記憶體來儲存臨時檔案,無此句可能報錯
        randomPic.drawImg(str,resp.getOutputStream(),100,50);

    }
}

12)ServletContex

代表整個web應用,可以和程式容器(伺服器)通訊

該物件有3個功能:

獲取MIME型別,域物件,獲取檔案正式路徑

(1)獲取ServletContex物件

//1.透過req物件獲取
req.getServletContex();
//2.透過HttpServlet物件獲取
this.getServletContex();

(2)獲取MIME型別

MIME型別:網際網路通訊中定義的一種檔案型別,格式為:大型別/小型別

String getMimeType(String var1);

(3)域物件方法

//設定屬性
void setAttribute(String var1, Object var2);
//獲取屬性
Object getAttribute(String var1);
//刪除屬性
void removeAttribute(String var1);

(4)獲取正式路徑

String getRealPath(String var1);

注意:這裡獲取路徑的檔案預設是web目錄下的所有檔案,如果要獲取的檔案是src下的,需要進入WEB-INF/classes目錄下獲取

13)下載案例

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;
import java.io.InputStream;

@WebServlet("/download")
public class downloadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext sc=this.getServletContext();
        String contenttype=sc.getMimeType("2.jpg");
        resp.setContentType( contenttype);
        resp.setHeader("content-disposition","attachment;filename=2.jpg");
        //檔名如果是中文需要特殊將中文進行編碼

        String path=sc.getRealPath("/imgs/1.jpg");
        InputStream is= new FileInputStream(path);
        ServletOutputStream os=resp.getOutputStream();
        int len;
        byte[] b=new byte[1024];
        while ((len=is.read(b))!=-1){
            os.write(b,0,len);
        }
        os.close();
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

7cookie

客戶端會話技術

//建立cookie
Cookie c=new Cookie("name","zhanghuan");
//傳送cookie
response.addCookie(c);
//獲取cookie
Cookie[] cs=request.getCookies();

1)特點:

(1)一次可傳送多個cookie

(2)預設情況下,瀏覽器關閉cookie銷燬

(3)可設定cookie的存活時間

Cookie c=new Cookie("name","zhanghuan");
c.setMaxAge(30);//設定cookie存活時間為30秒
//setMaxAge的引數為int型別,負數表示刪除cookie,0表示瀏覽器關閉cookie銷燬

(4)cookie的鍵值對在tomcat8之後支援中文,但最好還是不要存中文,可對中文進行編碼

URLEncoder.encode(String s, String enc);//s是需要編碼的字串,enc是編碼格式,返回一個字串
URLDecoder.decode(String s, String enc);//s是需要解碼的字串,enc是解碼格式,返回一個字串

2)cookie共享問題

(1)預設情況下,同一伺服器下的不同專案不可共享,如果要共享需設定

setPath(String path);
//傳入path為“/”,表示共享

(2)預設情況下,不同伺服器下的專案不可共享,如果要共享需設定

setDomain(String path);
//與path匹配上的一級域名,可共享該cookie

8session

服務端會話技術

//建立session
HttpSession s=request.getSession();
//設定session
s.setAttribute("name","zhanghuan");
//獲取session值
s.getAttribute("name");
//刪除session
s.removeAttribute("name");

1)存活時間

在伺服器存放的session資料能保留30分鐘,伺服器關閉或session物件呼叫invalidate方法會銷燬session,要修改session在伺服器的存活時間,需要到conf目錄下的web.xml修改配置

<session-config>
	<session-timeout>30</session-timeout>
</session-config>

2)伺服器或瀏覽器關閉後對session的影響

(1)瀏覽器關閉

session依賴於cookie,瀏覽器關閉後未設定過期時間的cookie會被清除掉,再次開啟瀏覽器傳送請求後,伺服器讀取不到名為JSESSIONID的cookie,便把該次請求當作一個新請求並重新分配session;要解決這個問題,需要給名為JSESSIONID的cookie設定過期時間

(2)伺服器關閉

在IDEA中session會發生變化,在tomcat中會自動完成session的鈍化、活化操作,session不會發生變化

3)session和cookie的比較

session cookie
位置 伺服器 瀏覽器
可存入的資料大小 無限制 有限制
安全性 安全 不安全

9驗證碼登陸案例

//獲取動態驗證碼的servlet服務
package web;

import midware.randomPic;

import javax.imageio.ImageIO;
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 javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/getvalidpicServlet")
public class getvalidpicServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String str= randomPic.getRandomString();
        System.out.println(str);
        HttpSession s=request.getSession();
        s.setAttribute("validcode",str);
        ImageIO.setUseCache(false);
        randomPic.drawImg(str,response.getOutputStream(),100,50);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
<!--登陸頁面-->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <form action="<%=request.getContextPath()%>/login">
    <table>
      <tr>
        <td>使用者名稱</td>
        <td><input type="text" name="username"></td>
      </tr>
      <tr>
        <td>密碼</td>
        <td><input type="text" name="password"></td>
      </tr>
      <tr>
        <td>驗證碼</td>
        <td><input type="text" name="validcode"></td>
      </tr>
      <tr>
        <td colspan="2"><img id="vpic" alt=""></td>
      </tr>
      <tr>
        <td colspan="2"><input id="sub" type="submit"></td>
      </tr>
    </table>
  </form>
  </body>
</html>
<script>
  window.onload=function () {
    picsrc()
    document.getElementById("vpic").onclick=function () {
      picsrc()
    }
  }
  function picsrc() {
    var vpic=document.getElementById("vpic")
    var date=new Date()
    vpic.setAttribute("src","<%=request.getContextPath()%>/getvalidpicServlet?a="+date.getSeconds())
  }
</script>
//登陸的servl服務
package web;

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 javax.servlet.http.HttpSession;
import java.io.IOException;


@WebServlet("/login")
public class loginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //獲取傳過來的資料
        String username=req.getParameter("username");
        String password=req.getParameter("password");
        String validcode=req.getParameter("validcode");

        //獲取session中存放的驗證碼
        HttpSession s=req.getSession();
        String session_valid=(String)s.getAttribute("validcode");

        //響應
        resp.setCharacterEncoding("utf-8");
        resp.setHeader("Content-Type","text/html;charset=utf-8");
        if(validcode.equalsIgnoreCase(session_valid)){
            if(username.equals("zhanghuan") && password.equals("123")){
                resp.getWriter().write("歡迎你,"+"zhanghuan");
            }else{
                resp.getWriter().write("登陸失敗,賬號或密碼錯誤");
            }
        }else{
            resp.getWriter().write("登陸失敗,驗證碼錯誤");
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

10JSP

java服務端頁面,可定義html標籤,也可定義java程式碼,本質是一個servlet

1)指令

用於配置jsp頁面,匯入資原始檔

格式

<%@ 指令名 屬性名=屬性值…… %>

指令分類

(1)page

配置jsp頁面常用4個屬性

屬性 功能
contentType 設定頁面的MIME屬性
import 匯入java包
errorPage 發生錯誤時跳轉到另一個目標頁面
isErrorPage 標誌該頁面是否可使用exception物件

(2)incluede

頁面包含

<%@include file="abc.jsp"%>

(3)taglib

匯入標籤庫資源

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

2)指令碼

<% 程式碼 %>//定義內容在service方法中
<%! 程式碼 %>//定義內容在jsp轉換的java類中的成員位置
<%= 程式碼 %>//定義內容輸出到頁面上

3)註釋

<!---->//只能註釋html程式碼
<%---->//能註釋所有內容,註釋後的內容不會在頁面上出現

4)內建物件

不需要建立,可直接使用的物件

物件名 真實型別 說明
pageContex pageContex 可獲取其他8個物件,當前頁面資料共享
request HttpServletRequest 一次請求資料共享
session HttpSession 一次會話資料共享
application ServletContext 所有使用者資料共享
response HttpServletResponse 響應物件
page Object 當前頁面物件
out JspWriter 輸出物件
config ServletConfig Servlet配置物件
exception Throwable 異常物件

out和response.getWriter().write()都能輸出到頁面上,但後者輸出的內容在前者之前


MVC

解釋 實現元素 功能
M 模型 JavaBean 查詢資料庫,封裝物件
V 檢視 JSP 展示資料
C 控制器 Servlet 獲取使用者輸入,呼叫模型,將資料交給檢視進行展示

優點

耦合性低,方便維護,重用性高

缺點

使得專案架構複雜


EL表示式

Expression Langarage表示式語言,用於替換、簡化JSP中的java程式碼

忽略el表示式

1)設定jsp中page的屬性isELIgnored=""設定為true

2)\${ 表示式 }

1運算子

型別 詳細
算術運算子 + - * / div % mod
比較運算子 > < == >= <= !=
邏輯運算子 & and | or ! not
定運算子 empty

empty用於判斷字串、集合、陣列物件是否為null並且長度為0,是返回為true

${ empty list }
${ not empty list }

2域物件獲取值

//1.從指定域中獲取指定值
${域名稱.鍵名}

//2.依次從最小域中找是否有對應鍵的值
${鍵名}

3獲取物件屬性值

${物件.屬性名}

4隱式物件

el表示式有11個隱式物件,可透過pageContext獲取其他8個物件

${ pageContext.request.contextPath }

JSTL

JavaServer Pages Tag Library jsp標準標籤庫,用於替換、簡化JSP中的java程式碼

使用步驟:

1.匯入jstl的兩個java包

2.JSP中透過指令引入標籤庫<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

3.頁面中使用標籤

1if

相當於java中的if語句

<c:if test="true">
  該標籤內test屬性值為true,會顯示出來
</c:if>
<c:if test="false">
  該標籤內test屬性值為false,不會顯示出來
</c:if>

2choose

相當於java中的switch語句

<%
request.setAttribute("num",1);
%>
<c:choose>
  <c:when test="${num==1}">星期一</c:when>
  <c:when test="${num==2}">星期二</c:when>
  <c:when test="${num==3}">星期三</c:when>
  <c:when test="${num==4}">星期四</c:when>
  <c:when test="${num==5}">星期五</c:when>
  <c:when test="${num==6}">星期六</c:when>
  <c:when test="${num==7}">星期七</c:when>
  <c:otherwise>輸入錯誤</c:otherwise>
</c:choose>

3forEach

相當於java中的for語句

<%--1.完成重複性操作--%>
  <table>
    <th> 變數i的值</th>
    <th> 迴圈次數</th>
    <th> 迴圈索引</th>
    <c:forEach begin="1" end="5" var="i" step="1" varStatus="s">
      <tr>
        <td> ${i}</td>
        <td> ${s.count}</td>
        <td> ${s.index}</td>
      </tr>
    </c:forEach>
  </table>
  <%--執行結果
    變數i的值	迴圈次數	迴圈索引
    1	1	1
    2	2	2
    3	3	3
    4	4	4
    5	5	5
  --%>

<%--2.遍歷容器--%>
  <%
  String[] ar={"a","b","c"};
  request.setAttribute("ar",ar);
  %>
<c:forEach items="${ar}" var="str">
  ${str}<br>
</c:forEach>

Filter過濾器

訪問伺服器資源時,過濾器可以將請求攔截下來,完成同一特殊功能。用於完成一些通用操作,如:登陸驗證、統一編碼處理、敏感字元過濾等

1建立步驟

1)建立類實現Filter介面

2)實現抽象方法,在doFilter裡呼叫chain.doFilter(req, resp),放行請求

3)將該實現類進行註冊

<!--web.xml-->
<filter>
	<filter-name>allFilter</filter-name>
	<filter-class>allFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>allFilter</filter-name>
    <url-pattern>*</url-pattern>
</filter-mapping>
//另一種方式時在類上面新增註解
@WebFilter(filterName = "/*")

2生命週期方法

方法名 解釋
init 伺服器啟動後,會建立Filter物件,然後呼叫init方法,只執行一次,用於載入資源
doFilter 每次請求被攔截資源時,會執行,執行多次
destroy 在伺服器關閉後,Filter物件被銷燬;如果是正常關閉,會執行destroy方法,只執行一次,用於釋放資源

3攔截路徑配置

1)具體資源路徑

@WebFilter("/index.jsp")

2)攔截目錄

@WebFilter("/user/*")

3)字尾名攔截

@WebFilter("*.jsp")

4攔截方式配置

1)註解上配置

@WebFilter(value="*.jsp",dispatcherTypes=DispatcherType.REQUEST)

2)web.xml配置

<filter>
	<filter-name>allFilter</filter-name>
	<filter-class>allFilter</filter-class>
	<dispatcher>REQUEST</dispatcher>
</filter>

3)攔截型別

型別 含義
DispatcherType.REQUEST 直接訪問時過濾
DispatcherType.FORWARD 轉發訪問時過濾
DispatcherType.INCLUDE 包含時過濾
DispatcherType.ERROR 發生錯誤時過濾
DispatcherType.ASYNC 非同步時過濾

5多個過濾器執行的先後順序

1)註解配置的過濾器

安裝類名字串比較規則比較,值小的先執行

2)web.xml配置

誰定義在上面,誰先執行

6過濾器驗證登陸案例思路

請求過來時,看這個請求訪問的資源,如果是登陸相關的就透過,如果不是就判斷使用者登陸狀態;如果使用者已登陸,放行透過;為登陸,跳轉到登陸介面

代理模式

代理模式給某一個物件提供一個代理物件,並由代理物件控制對原物件的引用。通俗的來講代理模式就是我們生活中常見的中介

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

@WebFilter("/*")
public class allFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {

        ServletRequest proxy_req=(ServletRequest)Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //利用代理對引數進行過濾
                if(method.getName().equals("getParameter")){
                    String value=(String) method.invoke(req,args);
                    value=value.replaceAll("zhanghuan","張歡");
                    System.out.println(value);
                    return value;
                }
                return method.invoke(req,args);
            }
        });
        chain.doFilter(proxy_req,resp);
    }

    public void init(FilterConfig config) throws ServletException {

    }

}

監聽器

監聽觀察某個事件(程式)的發生情況,當被監聽的事件真的發生了的時候,事件發生者(事件源) 就會給註冊該事件的監聽者(監聽器)傳送訊息,告訴監聽者某些資訊,同時監聽者也可以獲得一份事件物件,根據這個物件可以獲得相關屬性和執行相關操作

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;//監聽ServletContext的建立和銷燬
import javax.servlet.annotation.WebListener;

@WebListener//註冊監聽器
public class ServletContexListener1 implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {//監聽到建立後執行
        System.out.println("ServletContext建立了……");
        
        //獲取初始化引數
        String str=sce.getServletContext().getInitParameter("name");
        System.out.println(str);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {//監聽到銷燬後執行

    }
}

註冊監聽器也可在web.xml中配置

<listener>
    <listener-class>com.ygj.control.onLineCount</listener-class>
</listener>

初始化引數

在web.xml中配置

<init-param>
    <param-name>username</param-name>
    <param-value>moonlit</param-value>
</init-param>

可透過HttpServlet.getInitParameter(String Param)拿到


Redis

非關係型資料庫,鍵值對資料,value有5種不同的資料型別,分別是字串(string),雜湊(hash),列表(list),集合(set),有序集合(sortedset)

1操作

型別 操作 命令 說明
字串(string) set key value
get key
del key
雜湊(hash) hset key field value
hget key field
hgetall key 獲取所有的field和value
hdel key field
列表(list) lpush key value
rpush key value
lrange key start end
lpop key
rpop key
集合(set) sadd key value
smembers key
srem key value
有序集合(sortedset) zadd key score value
zrange key start end
zrem key value
通用 keys * 檢視所有的鍵
type key 檢視某一鍵的資料型別
del key 刪除鍵

2持久化

將記憶體種的資料儲存到硬碟上

(1)RDB

預設方式,無需配置。一定時間間隔中,檢測key變化情況,然後持久化資料

save 900 1
save 300 10
save 60 10000
#   In the example below the behaviour will be to save:
#   after 900 sec (15 min) if at least 1 key changed
#   after 300 sec (5 min) if at least 10 keys changed
#   after 60 sec if at least 10000 keys changed

(2)AOF

日誌記錄方式,可以記錄每一條命令的操作,每一次命令操作後,持久化資料

# enable the append only mode: when this mode is enabled Redis will append
# every write operation received in the file appendonly.aof.
appendonly no#改為yes

# appendfsync always
appendfsync everysec#每秒持久化一次
# appendfsync no

3Jedis

透過java操作redis資料庫,需匯入2個jar包

(1)各型別資料操作

import redis.clients.jedis.Jedis;

import java.util.Map;

public class test01 {
    static Jedis j=new Jedis("localhost",6379);//空引數預設值"localhost",6379
    
    public static void main(String[] args) throws InterruptedException {
        string_value();
        hash_value();
        list_value();
        set_value();
        sortedset_value();
        j.close();//關閉連線

    }
    public static void string_value() throws InterruptedException {
        //設定鍵值對
        j.set("name","asdsdsd");
        System.out.println(j.get("name"));//asdsdsd

        //刪除鍵值對
        j.del("name");
        System.out.println(j.get("name"));//null

        //設定具有過期時間的鍵值對
        j.setex("age", 5, "25");
        System.out.println(j.get("age"));//25
        Thread.sleep(10000);
        System.out.println(j.get("age"));//null
        j.close();
    }
    public static void hash_value(){
        //設定
        j.hset("myhashset","name","zhanghuan");
        System.out.println(j.hget("myhashset","name"));//zhanghuan

        //獲取map
        Map<String,String> map=j.hgetAll("myhashset");
        System.out.println(map);//{name=zhanghuan, age=25}

        //刪除map下的鍵
        j.hdel("myhashset","name","age");
        System.out.println(j.hgetAll("myhashset"));//{}
    }
    public static void list_value(){
        //壓入
        j.lpush("mylist","a");
        j.rpush("mylist","b");
        System.out.println(j.lrange("mylist",0,-1));//[a, b]

        //彈出
        System.out.println(j.lpop("mylist"));//a
        System.out.println(j.rpop("mylist"));//b
    }
    public static void set_value(){
        //存
        j.sadd("myset","大毛");
        j.sadd("myset","小毛");

        //取
        System.out.println(j.smembers("myset"));//[小毛, 大毛]

        //刪除指定值
        j.srem("myset","大毛");
        System.out.println(j.smembers("myset"));//[小毛]sortedset
    }
    public static void sortedset_value(){
        //存
        j.zadd("mysortedset",10,"小黃");
        j.zadd("mysortedset",18,"小黑");
        j.zadd("mysortedset",14,"小白");

        //取
        System.out.println(j.zrange("mysortedset",0,-1));//[小黃, 小白, 小黑]

        //刪除
        j.zrem("mysortedset","小白");
        System.out.println(j.zrange("mysortedset",0,-1));//[小黃, 小黑]
    }
}

(2)封裝連線池物件

#jedis.properties
host=127.0.0.1
port=6379
MaxTotal=50
MaxIdle=10
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;


import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class JedisPoolUtils {
    private static JedisPool pool;
    static {
        //讀取配置檔案
        InputStream is=JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
        Properties p=new Properties();
        try {
            p.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }

        //建立配置物件
        GenericObjectPoolConfig<String> config=new GenericObjectPoolConfig<>();
        config.setMaxIdle(Integer.parseInt(p.getProperty("MaxIdle")));
        config.setMaxTotal(Integer.parseInt(p.getProperty("MaxTotal")));

        //生成連線池
        pool=new JedisPool(config,p.getProperty("host"),Integer.parseInt(p.getProperty("port")));
    }
    public static Jedis getJedis(){
        return pool.getResource();
    }
}

4省市二級聯動案例

1)資料庫

型別 欄位名 解釋
int CRI_ID id
varchar CRI_CODE 6位編碼,區分省、市,前3位代表省,第4位代表市,後2位代表取
varchar CRI_NAME 省、市、區名稱

2)目錄結構

-src
	-dao
		-impl
			cn_regionDaoimpl.java
		cn_regionDao.java
	-domain
		Cn_region.java
	-service
		-impl
			getCitiesServiceimpl.java
			getProvincesServiceimpl.java
		getCitiesService.java
		getProvincesService.java
	-utils
		JDBCutils.java
		JEDISPOOLutils.java
	-web
		getCitiesServlet.java
		getProvincesServlet.java
	duid.properties
	jedis.properties
	
web
	-WEB-INF
		-lib
		web.xml
	index.jsp

3)檔案內容

//cn_regionDaoimpl.java
package dao.impl;

import dao.cn_regionDao;
import doMain.Cn_region;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import utils.JDBCutils;

import java.util.ArrayList;
import java.util.List;

public class cn_regionDaoimpl implements cn_regionDao {
    static private JdbcTemplate template=new JdbcTemplate(JDBCutils.getDataSource());

    @Override
    public List<Cn_region> findAll() {

        List<Cn_region> list=template.query("select CRI_ID,CRI_CODE,CRI_NAME from cn_region_info",new BeanPropertyRowMapper<Cn_region>(Cn_region.class));
        return list;
    }

    @Override
    public List<Cn_region> getProvinces() {
        List<Cn_region> alllist=findAll();
        List<Cn_region> r_list=new ArrayList<Cn_region>();
        String CRI_CODE_last_3;//最後3位,用來判斷是否是省
        for (Cn_region item:
                alllist) {
            CRI_CODE_last_3=item.getCRI_CODE().substring(3,6);
            if(CRI_CODE_last_3.equals("000")){
                r_list.add(item);
            }
        }
        return r_list;
    }

    @Override
    public List<Cn_region> getCites(String province_code) {
        List<Cn_region> alllist=findAll();
        List<Cn_region> r_list=new ArrayList<Cn_region>();
        String CRI_CODE_first_3;//擷取前三位
        String CRI_CODE_4;//擷取第四位
        String CRI_CODE_last_2;//最後兩位
        for (Cn_region item:
                alllist) {
            CRI_CODE_first_3=item.getCRI_CODE().substring(0,3);
            CRI_CODE_4=item.getCRI_CODE().substring(3,4);
            CRI_CODE_last_2=item.getCRI_CODE().substring(4,6);
            if( CRI_CODE_first_3.equals (province_code) && !CRI_CODE_4.equals ("0") && CRI_CODE_last_2.equals("00")){
                r_list.add(item);
            }
        }
        return r_list;
    }

    @Override
    public List<Cn_region> getCity_areas() {
        return null;
    }
}

//cn_regionDao.java
package dao;

import doMain.Cn_region;

import java.util.List;

public interface cn_regionDao {
    public List<Cn_region> findAll();
    public List<Cn_region> getProvinces();
    public List<Cn_region> getCites(String province_code);
    public List<Cn_region> getCity_areas();
}
//Cn_region.java
package doMain;

public class Cn_region {
    private int CRI_ID;
    private String CRI_CODE;
    private String CRI_NAME;

    public int getCRI_ID() {
        return CRI_ID;
    }

    public String getCRI_CODE() {
        return CRI_CODE;
    }

    public String getCRI_NAME() {
        return CRI_NAME;
    }

    public void setCRI_ID(int CRI_ID) {
        this.CRI_ID = CRI_ID;
    }

    public void setCRI_CODE(String CRI_CODE) {
        this.CRI_CODE = CRI_CODE;
    }

    public void setCRI_NAME(String CRI_NAME) {
        this.CRI_NAME = CRI_NAME;
    }

    @Override
    public String toString() {
        return "Cn_region{" +
                "CRI_ID=" + CRI_ID +
                ", CRI_CODE='" + CRI_CODE + '\'' +
                ", CRI_NAME='" + CRI_NAME + '\'' +
                '}';
    }
}

//getCitiesServiceimpl.java
package service.impl;

import dao.impl.cn_regionDaoimpl;
import doMain.Cn_region;
import org.codehaus.jackson.map.ObjectMapper;
import redis.clients.jedis.Jedis;
import service.getCitiesService;
import utils.JEDISPOOLutils;

import java.io.IOException;
import java.util.List;

public class getCitiesServiceimpl implements getCitiesService {
    @Override
    public String findAll(String province_code){
        cn_regionDaoimpl dao=new cn_regionDaoimpl();
        List<Cn_region> list=dao.getCites (province_code);
        //序列化
        ObjectMapper maper=new ObjectMapper();
        String json= null;
        try {
            json = maper.writeValueAsString (list);
        } catch (IOException e) {
            e.printStackTrace ( );
        }
        return json;
    }

    @Override
    public String findAllJson(String province_code){
        //先從redis中查詢資料,如果沒有再從資料庫中查詢
        Jedis jedis= JEDISPOOLutils.getJedis ();
        String cities= jedis.hget ("cities",province_code);
        String json;
        if(cities==null || cities.length ()==0){
            json=findAll (province_code);
            jedis.hset("cities",province_code,json);
        }else {
            json=cities;
        }
        jedis.close ();
        return json;
    }
}

//getProvincesServiceimpl.java
package service.impl;

import dao.impl.cn_regionDaoimpl;
import doMain.Cn_region;
import org.codehaus.jackson.map.ObjectMapper;
import redis.clients.jedis.Jedis;
import service.getProvincesService;
import utils.JEDISPOOLutils;

import java.io.IOException;
import java.util.List;

public class getProvincesServiceimpl implements getProvincesService {
    @Override
    public String findAll() {
        cn_regionDaoimpl dao=new cn_regionDaoimpl();
        List<Cn_region> list=dao.getProvinces ();
        //序列化
        ObjectMapper maper=new ObjectMapper();
        String json= null;
        try {
            json = maper.writeValueAsString (list);
        } catch (IOException e) {
            e.printStackTrace ( );
        }
        return json;
    }

    @Override
    public String findAllJson(){
        //先從redis中查詢資料,如果沒有再從資料庫中查詢
        Jedis jedis=JEDISPOOLutils.getJedis ();
        String provinces= jedis.get ("provinces");
        String json;
        if(provinces==null || provinces.length ()==0){
            json=findAll ();
            jedis.set("provinces",json);
        }else {
            json=provinces;
        }
        jedis.close ();
        return json;
    }
}

//getCitiesService.java
package service;

import doMain.Cn_region;

import java.io.IOException;
import java.util.List;

public interface getCitiesService {
    public String findAll(String province_code);
    public String findAllJson(String province_code);
}

//getProvincesService.java
package service;

import doMain.Cn_region;

import java.io.IOException;
import java.util.List;

public interface getProvincesService {
    public String findAll();
    public String findAllJson();
}

//getCitiesServlet.java
package web;

import service.impl.getCitiesServiceimpl;


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("/getCitiesServlet")
public class getCitiesServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {

        //獲取省份id
        String province_id=request.getParameter ("province_id").substring (0,3);

        //獲取資料
        getCitiesServiceimpl getCitiesServiceimpl=new getCitiesServiceimpl();
        String json=getCitiesServiceimpl.findAllJson (province_id);

        //返回
        response.setCharacterEncoding ("utf-8");
        response.setHeader ("contentype","application/json;charset=utf-8");
        response.getWriter ().write (json);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        this.doPost (request, response);
    }
}

//getProvincesServlet.java
package web;

import service.impl.getProvincesServiceimpl;

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.List;

@WebServlet("/getProvincesServlet")
public class getProvincesServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //獲取資料
        getProvincesServiceimpl getProvincesServiceimpl=new getProvincesServiceimpl();
        String json=getProvincesServiceimpl.findAllJson ();

        //返回
        response.setCharacterEncoding ("utf-8");
        response.setHeader ("contentype","application/json;charset=utf-8");
        response.getWriter ().write (json);

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

<%--index.jsp--%>
<%--
  Created by IntelliJ IDEA.
  User: admin
  Date: 2020/5/1
  Time: 下午 06:32
  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>
  <div class="container">
    <div class="row">
      <div class="col-md-3">
        <div class="panel">
          <div class="panel-body">
            <select class="form-control" id="select1">
            <option value="0">請選則</option>
          </select>
          </div>
        </div>
      </div>
      <div class="col-md-3">
        <div class="panel">
          <div class="panel-body">
            <select class="form-control" id="select2">
              <option value="0">請選則</option>
            </select>
          </div>
        </div>
      </div>
    </div>
  </div>
  </body>
  <script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  <script>
    <%--"${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/getProvincesServlet"--%>
    $(function () {
      $.ajax({
        method:"post",
        url:"http://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/getProvincesServlet",
        success:function (data) {
          //cri_ID,cri_NAME,cri_CODE
          console.log(data)
          obj=JSON.parse(data)
          for(var i=0;i<obj.length;i++){
            $("#select1").append("<option value="+obj[i]["cri_CODE"]+">"+obj[i]["cri_NAME"]+"</option>")
          }
        }
      })
      $("#select1").change(function () {
        province_id=$(this).val()
        if($(this).val()!="0"){
          $.ajax({
            methd:"get",
            data:{"province_id":province_id},
            url:"http://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/getCitiesServlet",
            success:function (data) {
              obj=JSON.parse(data)
              $("#select2").children().remove()
              $("#select2").append('<option value="0">請選則</option>')
              for(var i=0;i<obj.length;i++){
                $("#select2").append("<option value="+obj[i]["cri_CODE"]+">"+obj[i]["cri_NAME"]+"</option>")
              }
            }
          })
        }else{
          $("#select2").children().remove()
          $("#select2").append('<option value="0">請選則</option>')
        }
      })
    })
  </script>
</html>


Maven

為解決專案開發過程中,匯入jar包衝突問題。透過匯入jar包的座標,編譯時從倉庫中找到對應的包完成編譯

1安裝及環境配置

1)解壓安裝包

2)配置環境變數

MAVEN_HOME指向解壓後的安裝包位置

注意:

maven執行需要java環境,確保環境變數中有JAVA_HOME

2倉庫

分為本地倉庫、遠端倉庫、中央倉庫。maven會先在本地倉庫找jar包,如未找到再去遠端倉庫找。

要為maven指定本地倉庫,需要在conf/setting.xml中配置

<localRepository>C:\Users\admin\Desktop\maven_repository</localRepository>

路徑中不要有中文

3)配置映象

修改目錄下conf下的setting.xml在mirrors標籤中,新增文末這一段

<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

3maven專案標準目錄結構

src/main/java	//核心程式碼部分
src/main/resources	//配置檔案部分
src/test/java	//測試程式碼部分
src/test/resources	//測試配置檔案部分
src/main/webapp	//靜態資源,如js,css,圖片等

4命令

命令 功能
mvn clean 刪除編譯資訊
mvn compile 編譯專案
mvn test 編譯測試程式碼
mvn package 專案編譯,並打成war包
man install 專案編譯,並打成war包,將專案複製到本地庫

5maven生命週期

生命週期 操作 命令
清理生命週期 清除專案編譯資訊 clean
預設生命週期 編譯 compile
測試 test
打包 package
安裝 install
釋出 deploy
站點生命週期

6專案物件模型pom和依賴管理模型dependency

1)專案物件模型pom

包含專案自身資訊,專案執行依賴的jar包,專案執行環境資訊(JDK,tomcat資訊)

2)依賴管理模型dependency

包含公司組織名稱、專案名、版本號

<dependency>
			<!-- junit的專案名稱 -->
			<groupId>junit</groupId>
			<!-- junit的模組名稱 -->
			<artifactId>junit</artifactId>
			<!-- junit版本 -->
			<version>4.9</version>
			<!-- 依賴範圍:單元測試時使用junit -->
			<scope>test</scope>
</dependency>

7idea下使用maven

1)配置整合環境

在settins搜尋maven,將maven的解壓目錄配置上即可

2)建立maven專案

(1)新建專案,選中maven,點選下一步,填寫專案資訊,在點選下一步至finish

(2)建立專案後,裡面缺少的標準目錄需要自行新增,並標記為標準目錄

(3)webapp的目錄,需要進行靜態標記。project structure->modules->web->web resource dirictory中加入包的目錄

注意

建立web專案,勾選create from archetype後,選中org.apache.maven.archetpes.maven-archetype-webapp

3)專案中匯入jar包

在pom.xml中配置

 <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
    </dependency>
  </dependencies>

注意

如果匯入jar包後,專案中仍無法識別匯入的包,可能與maven版本有關係

4)設定包的作用範圍

 <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <!--匯入的servlet和jsp的包要配置範圍provided-->

這裡的scope裡包含的就是包的作用範圍

依賴範圍 編譯 測試 執行 案例
compile 影響 影響 影響 spring-core
test 影響 junit
provided 影響 影響 servlet-api
runtime 影響 影響 jdbc驅動
system 影響 影響 本地的maven庫之外的庫

5)配置執行環境

 <build>
      <plugins>
          <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
            <configuration>
              <path>/</path> <!--專案訪問路徑。當前配置的訪問是localhost:9090/, 如果配置是/aa,則訪問路徑為localhost:9090/aa -->
              <port>9090</port>
              <uriEncoding>UTF-8</uriEncoding><!-- 非必需項 -->
            </configuration>
          </plugin>
      </plugins>
  </build>

執行時指向tomcat7:run,不然會報錯