JavaWeb學習筆記後端部分

bfs1201發表於2024-07-19

後端Web開發

Maven

Apache Maven 是一個專案管理和構建工具,它基於專案物件模型(POM)的概念,透過一小段描述資訊來管理專案的構建。

image-20240709155020079

Maven作用

依賴管理

image-20240709155147967

統一的專案結構

image-20240709154759785

專案構建

image-20240709154912556

倉庫

image-20240709161419270

image-20240709161132316

安裝Maven

image-20240709161751323

image-20240709162417610

image-20240709162705286

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

image-20240709163152423

image-20240709163127689

測試:

mvn -v

image-20240709163334394

配置Maven環境

image-20240709165900228

image-20240709165817714image-20240709165937198

image-20240709170419318

image-20240709165945726

建立Maven專案

image-20240709170135289

座標

image-20240709212930094

匯入Maven專案

image-20240709232811555

image-20240709232830925

依賴配置

image-20240710012523311

倉庫網址:https://mvnrepository.com/

依賴傳遞

image-20240710005706943

顯示關係圖

image-20240710012618346

A的依賴關係圖

image-20240710010730419

B的依賴關係圖

image-20240710010738544

C的依賴關係圖

image-20240710010744834

排除依賴

image-20240710010827016

image-20240710011430583

image-20240710011301251

依賴範圍

image-20240710012918023

生命週期

image-20240710014707654

image-20240710014840162

image-20240710020636804

在同一套生命週期中,當執行後面的階段時,前面的階段都會執行,上圖三套

image-20240710020733297

SpringBoot

入門

image-20240710174538624

image-20240710174645183

image-20240710174703884

入門程式碼

package com.itheima.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @RequestMapping("/Hello")
    public String hello() {
        System.out.println("Hello!!!");
        return "Hello world!!!";
    }
}

啟動

image-20240710174836709

image-20240710174857394

image-20240710174909693

HTTP協議

image-20240710175709918

請求協議

image-20240710192544415

相應協議

image-20240710194620705

image-20240710194642257

狀態碼大類
狀態碼分類 說明
1xx 響應中——臨時狀態碼,表示請求已經接受,告訴客戶端應該繼續請求或者如果它已經完成則忽略它
2xx 成功——表示請求已經被成功接收,處理已完成
3xx 重定向——重定向到其它地方:它讓客戶端再發起一個請求以完成整個處理。
4xx 客戶端錯誤——處理發生錯誤,責任在客戶端,如:客戶端的請求一個不存在的資源,客戶端未被授權,禁止訪問等
5xx 伺服器端錯誤——處理發生錯誤,責任在服務端,如:服務端丟擲異常,路由出錯,HTTP版本不支援等
常見的響應狀態碼
狀態碼 英文描述 解釋
200 OK 客戶端請求成功,即處理成功,這是我們最想看到的狀態碼
302 Found 指示所請求的資源已移動到由Location響應頭給定的 URL,瀏覽器會自動重新訪問到這個頁面
304 Not Modified 告訴客戶端,你請求的資源至上次取得後,服務端並未更改,你直接用你本地快取吧。隱式重定向
400 Bad Request 客戶端請求有語法錯誤,不能被伺服器所理解
403 Forbidden 伺服器收到請求,但是拒絕提供服務,比如:沒有許可權訪問相關資源
404 Not Found 請求資源不存在,一般是URL輸入有誤,或者網站資源被刪除了
405 Method Not Allowed 請求方式有誤,比如應該用GET請求方式的資源,用了POST
428 Precondition Required 伺服器要求有條件的請求,告訴客戶端要想訪問該資源,必須攜帶特定的請求頭
429 Too Many Requests 指示使用者在給定時間內傳送了太多請求(“限速”),配合 Retry-After(多長時間後可以請求)響應頭一起使用
431 Request Header Fields Too Large 請求頭太大,伺服器不願意處理請求,因為它的頭部欄位太大。請求可以在減少請求頭域的大小後重新提交。
500 Internal Server Error 伺服器發生不可預期的錯誤。伺服器出異常了,趕緊看日誌去吧
503 Service Unavailable 伺服器尚未準備好處理請求,伺服器剛剛啟動,還未初始化好

狀態碼大全:https://cloud.tencent.com/developer/chapter/13553

協議解析

image-20240710195842007

image-20240710201506342

Tomcat

image-20240710201406147

基本使用

image-20240710201731663

image-20240710201750243

配置埠號:

image-20240710202615254

部署:將檔案移動到webapps資料夾下即可

image-20240710202918101

image-20240710203957125

https://docs.spring.io/spring-boot/docs/2.7.4/reference/htmlsingle/#using.build-systems.starters

image-20240710204119487

請求響應

image-20240711110803650

請求

postman

image-20240711121245498

簡單引數

如果方法形參名稱與請求引數名稱不匹配,可以使用 @RequestParam 完成對映

原始方法(不要求掌握)

//原始方法
@RestController
public class HelloController {
    @RequestMapping("/simpleParam")
    public String simpleParam(HttpServletRequest request) {
//        獲取請求引數
        String name = request.getParameter("name");
        String ageStr = request.getParameter("age");
        int age = Integer.parseInt(ageStr);
        System.out.println(name + ":" + age);
        return "OK";
    }
}

image-20240711123328280

image-20240711123339388

Springboot方式

@RestController
public class HelloController {    
//    Springboot方式
    @RequestMapping("/simpleParam")
    public String simpleParam(String name, int age) {
        System.out.println(name + ":" + age);
        return "OK";
    }
}

GET請求

image-20240711124046160

image-20240711124053167

POST請求

image-20240711124236196

image-20240711124244834

請求引數名與方法變數名不同,不能傳遞

    @RequestMapping("/simpleParam")
    public String simpleParam(String userName, int age) {
        System.out.println(userName + ":" + age);
        return "OK";
    }

image-20240711125056074

image-20240711125032405

強制傳遞:註釋@RequestParam(name/value="請求引數名", require = true(預設,必須傳遞name))

	@RequestMapping("/simpleParam")
    public String simpleParam(@RequestParam(name = "name") String userName, int age) {
        System.out.println(userName + ":" + age);
        return "OK";
    }

image-20240711125329677

image-20240711125422382

image-20240711125459798

不傳遞會報錯,因為預設required=true,除非required=false

image-20240711125552021

image-20240711125634325

required=false,不傳遞name:

image-20240711125956568

image-20240711125935768

image-20240711124752750

實體引數

要求:請求引數名與形參物件屬性名相同

簡單實體引數

實體類

public class User {
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Springboot方法

@RestController
public class HelloController {
//    實體引數
    @RequestMapping("/simplePojo")
    public String simplePojo(User user) {
        System.out.println(user);
        return "OK";
    }
}

image-20240711140008972

image-20240711140020470

複雜實體引數

實體類:address實體類不要封裝有參建構函式,否則報錯

public class Address {
    private String province;
    private String city;

//    不要寫有參建構函式
    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return "Address{" +
                "province='" + province + '\'' +
                ", city='" + city + '\'' +
                '}';
    }
}
public class User {
    private String name;
    private int age;
    private Address address;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

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

Springboot方法

@RestController
public class HelloController {
//  複雜實體方法
    @RequestMapping("/complexPojo")
    public String complexPojo(User user) {
        System.out.println(user);
        return "OK";
    }
}

image-20240711142633477

image-20240711142644825

陣列集合引數

image-20240711145749897

@RestController
public class HelloController {
//    陣列集合引數
    @RequestMapping("/arrayParam")
    public String arrayParam(String[] hobby) {
        System.out.println(Arrays.toString(hobby));
        return "OK";
    }
}
陣列引數

image-20240711144741417

image-20240711144721608

集合引數

請求引數名與形參集合名稱相同且請求引數為多個,@RequestParam 繫結引數關係

注意:一定要加註解image-20240711145449040

@RestController
public class HelloController {
//    集合引數
    @RequestMapping("/listParam")
    public String listParam(@RequestParam List<String> hobby) {
        System.out.println(hobby);
        return "OK";
    }
}

image-20240711145522033

image-20240711145310933

日期時間引數

使用 @DateTimeFormat 註解完成日期引數格式轉換

@RestController
public class HelloController {
//    日期時間引數
    @RequestMapping("/dateParam")
//    方法形參:加註解指定日期格式,宣告一個日期時間物件updateTime
    public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime updateTime) {
        System.out.println(updateTime);
        return "OK";
    }
}

image-20240711151746418

image-20240711151755037

JSON引數

JSON資料鍵名與形參物件屬性名相同,定義POJO型別形參即可接收引數,需要使用 @RequestBody 標識

注意:實體類不要寫有參構造器

@RestController
public class HelloController {
    @RequestMapping("/jsonParam")
    public String jsonParam(@RequestBody User user) {
        System.out.println(user);
        return "OK";
    }
}

image-20240711153821547

// Json引數如下
{
    "name": "itheima", 
    "age": 22, 
    "address": {
        "province": "安徽", 
        "city": "阜陽"
    }
}

image-20240711153138470

路徑引數

如果方法形參名稱與請求引數名稱不匹配,可以使用 @RequestParam 完成對映

@RestController
public class HelloController {
//    路徑引數-單個引數
    @RequestMapping("/path/{id}")
    public String pathParam(@PathVariable Integer id) {
        System.out.println(id);
        return "OK";
    }
}

image-20240711154632827

image-20240711154717633

多個引數

// 多個引數
@RequestMapping("/path/{id}/{name}")
public String pathParam(@PathVariable Integer id, @PathVariable String name) {
    System.out.println(id + ":" + name);
    return "OK";
}

image-20240711155220405

總結-引數

image-20240711155533572

響應

image-20240711200958031

@RestController
public class RequestController {
//		響應-字串
    @RequestMapping("/Hello")
    public String hello() {
        System.out.println("Hello!!!");
        return "Hello world!!!";
    }
//    響應-物件
    @RequestMapping("/getAddr")
    public Address getAddr() {
        Address addr = new Address();
        addr.setProvince("廣東");
        addr.setCity("深圳");
        return addr;
    }
//    響應-集合
    @RequestMapping("/listAddr")
    public List<Address> listAddr() {
        List<Address> list = new ArrayList<>();

        Address addr1 = new Address();
        addr1.setProvince("廣東");
        addr1.setCity("深圳");

        Address addr2 = new Address();
        addr2.setProvince("陝西");
        addr2.setCity("西安");

        list.add(addr1);
        list.add(addr2);
        return list;
    }
}

響應資料形式不一,不便管理,難以維護

image-20240711202342898

image-20240711202351688

image-20240711202405755

統一響應結果

image-20240711204736561

Result類

/**
 * 統一響應結果封裝類
 */
public class Result {
    private Integer code ;//1 成功 , 0 失敗
    private String msg; //提示資訊
    private Object data; //資料 data

    public Result() {
    }
    public Result(Integer code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public Object getData() {
        return data;
    }
    public void setData(Object data) {
        this.data = data;
    }

    public static Result success(Object data){
        return new Result(1, "success", data);
    }
    public static Result success(){
        return new Result(1, "success", null);
    }
    public static Result error(String msg){
        return new Result(0, msg, null);
    }

    @Override
    public String toString() {
        return "Result{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                ", data=" + data +
                '}';
    }
}
@RestController
public class ResponseController {
//    統一響應結果
    //     響應-字串
    @RequestMapping("/Hello")
    public Result hello() {
        System.out.println("Hello!!!");
        return Result.success("Hello world!!!");
    }
    //    響應-物件
    @RequestMapping("/getAddr")
    public Result getAddr() {
        Address addr = new Address();
        addr.setProvince("廣東");
        addr.setCity("深圳");
        System.out.println(addr);
        return Result.success(addr);
    }
    //    響應-集合
    @RequestMapping("/listAddr")
    public Result listAddr() {
        List<Address> list = new ArrayList<>();

        Address addr1 = new Address();
        addr1.setProvince("廣東");
        addr1.setCity("深圳");

        Address addr2 = new Address();
        addr2.setProvince("陝西");
        addr2.setCity("西安");

        list.add(addr1);
        list.add(addr2);
        System.out.println(addr1);
        System.out.println(addr2);
        System.out.println(list);
        return Result.success(list);
    }
}

image-20240711204431418

image-20240712103838316

image-20240711204452888

響應-案例

image-20240711204942051

image-20240711211038728

Springboot專案的靜態資源(html,css,js等前端資源)預設存放目錄為:classpath:/static 、 classpath:/public、 classpath:/resources

empController

package com.itheima.controller;

import com.itheima.pojo.Emp;
import com.itheima.pojo.Result;
import com.itheima.utils.XmlParserUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class empController {
    @RequestMapping("/listEmp")
    public Result listEmp() {
//        動態獲取獲取靜態檔案路徑,路徑中不含中文
        String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
//        實在不行就拿絕對路徑
//        String file = "C:\\Users\\bfs\\Desktop\\JavaWeb\\study\\JavaWeb_project\\springboot-web-quickstart\\src\\main\\resources\\emp.xml";
//        載入emp.xml,並解析資料
        List<Emp> empList = XmlParserUtils.parse(file, Emp.class);

//        處理gender、job欄位
        empList.stream().forEach(emp -> {
            String gender = emp.getGender(); // gender: 1 男 2 女
            if("1".equals(gender)) {
                emp.setGender("男");
            } else if("2".equals(gender)) {
                emp.setGender("女");
            }

            String job = emp.getJob(); // job: 1:講師 2:班主任 3:就業指導
            if("1".equals(job)) {
                emp.setJob("講師");
            } else if("2".equals(job)) {
                emp.setJob("班主任");
            } else if("3".equals(job)) {
                emp.setJob("就業指導");
            }
        });

//        返回結果
        return Result.success(empList);
    }
}

介面除錯

image-20240711214651173

前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>員工資訊</title>
</head>

<link rel="stylesheet" href="element-ui/index.css">
<script src="./js/vue.js"></script>
<script src="./element-ui/index.js"></script>
<script src="./js/axios-0.18.0.js"></script>

<body>
    <h1 align="center">員工資訊列表展示</h1>
    <div id="app">
        <el-table :data="tableData" style="width: 100%"  stripe border >
            <el-table-column prop="name" label="姓名" align="center" min-width="20%"></el-table-column>
            <el-table-column prop="age" label="年齡" align="center" min-width="20%"></el-table-column>
            <el-table-column label="影像" align="center"  min-width="20%">
                <template slot-scope="scope">
                    <el-image :src="scope.row.image" style="width: 80px; height: 50px;"></el-image>
                </template>
            </el-table-column>
            <el-table-column prop="gender" label="性別" align="center"  min-width="20%"></el-table-column>
            <el-table-column prop="job" label="職位" align="center"  min-width="20%"></el-table-column>
        </el-table>
    </div>
</body>

<style>
    .el-table .warning-row {
        background: oldlace;
    }
    .el-table .success-row {
        background: #f0f9eb;
    }
</style>

<script>
    new Vue({
        el: "#app",
        data() {
            return {
                tableData: []
            }
        },
        mounted(){
            axios.get('/listEmp').then(res=>{
                if(res.data.code){
                    this.tableData = res.data.data;
                }
            });
        },
        methods: {
        }
    });
</script>
</html>

渲染效果

image-20240711215003468

分層解耦

三層結構

image-20240712174037225

image-20240712174101121

image-20240712205524016

檔案結構

image-20240712205651627

dao介面

package com.itheima.dao;

import com.itheima.pojo.Emp;

import java.util.List;

public interface EmpDao {
    List<Emp> listEmp();
}

dao介面的實現類

package com.itheima.dao.impl;

import com.itheima.dao.EmpDao;
import com.itheima.pojo.Emp;
import com.itheima.utils.XmlParserUtils;

import java.util.List;

public class EmpDaoA implements EmpDao {
    @Override
    public List<Emp> listEmp() {
//        動態獲取獲取靜態檔案路徑,路徑中不含中文
        String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
//        實在不行就拿絕對路徑
//        String file = "C:\\Users\\bfs\\Desktop\\JavaWeb\\study\\JavaWeb_project\\springboot-web-quickstart\\src\\main\\resources\\emp.xml";
//        載入emp.xml,並解析資料
        List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
        return empList;
    }
}

service介面

package com.itheima.service;

import com.itheima.pojo.Emp;

import java.util.List;

public interface EmpService {
    List<Emp> listEmp();
}

service介面實現類

package com.itheima.service.impl;

import com.itheima.dao.EmpDao;
import com.itheima.dao.impl.EmpDaoA;
import com.itheima.pojo.Emp;
import com.itheima.service.EmpService;

import java.util.List;

public class EmpServiceA implements EmpService {
    private EmpDao empDao = new EmpDaoA();
    @Override
    public List<Emp> listEmp() {
        List<Emp> empList = empDao.listEmp();

//        處理gender、job欄位
        empList.stream().forEach(emp -> {
            String gender = emp.getGender(); // gender: 1 男 2 女
            if("1".equals(gender)) {
                emp.setGender("男");
            } else if("2".equals(gender)) {
                emp.setGender("女");
            }

            String job = emp.getJob(); // job: 1:講師 2:班主任 3:就業指導
            if("1".equals(job)) {
                emp.setJob("講師");
            } else if("2".equals(job)) {
                emp.setJob("班主任");
            } else if("3".equals(job)) {
                emp.setJob("就業指導");
            }
        });
        return empList;
    }
}

controller

package com.itheima.controller;

import com.itheima.pojo.Emp;
import com.itheima.pojo.Result;
import com.itheima.service.EmpService;
import com.itheima.service.impl.EmpServiceA;
import com.itheima.utils.XmlParserUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class empController {
    private EmpService empService = new EmpServiceA();
    @RequestMapping("/listEmpA")
    public Result listEmpA() {
        List<Emp> list = empService.listEmp();
        return Result.success(list);
    }
}

image-20240712210013089

存在的問題:耦合

image-20240712214311380

分層解耦

  • 內聚:軟體中各個功能模組內部的功能聯絡。
  • 耦合:衡量軟體中各個層/模組之間的依賴、關聯的程度。
  • 軟體設計原則:高內聚,低耦合

控制反轉: Inversion Of Control,簡稱IOC。物件的建立控制權由程式自身轉移到外部(容器),這種思想稱為控制反轉。

依賴注入: Dependency Injection,簡稱DI。容器為應用程式提供執行時,所依賴的資源,稱之為依賴注入。

Bean物件:IOC容器中建立、管理的物件,稱之為bean。

image-20240712212247135

image-20240712214735786

image-20240712214746554

IOC

Bean的宣告

要把某個物件交給IOC容器管理,需要在對應的類上加上如下註解之一

image-20240714150227500

宣告bean的時候,可以透過value屬性指定bean的名字,如果沒有指定,預設為類名首字母小寫。

使用以上四個註解都可以宣告bean,但是在springboot整合web開發中,宣告控制器bean只能用@Controller。

Bean元件掃描

image-20240714174813769

DI

image-20240714212833177

image-20240714212816267

image-20240714212751700

相關文章