詳細SpringBoot教程之Web開發(二)

寫在前面

鑑於有人留言說想要學習SpringBoot相關的知識,我這裏打算寫一個SpringBoot系列的相關博文,目標呢是想讓看了這一系列博文的同學呢,能夠對SpringBoot略窺門徑,這一系列的博文初步都定下來包括SpringBoot介紹、入門、配置、日誌相關、web開發、數據訪問、結合docker、緩存、消息隊列、檢索、任務安全、分佈式等等一系列的博文,工作量很大,是個漫長的過程,每一步我都儘量詳細,配上截圖說明,也希望對看的同學真的有用。
單純就是想分享技術博文,還想說一句就是,如果覺得有用,請點個關注、給個贊吧,也算對我來說是個寬慰,畢竟也得掉不少頭髮,嘿嘿嘿

系列文章傳送條

詳細SpringBoot教程之入門(一)
詳細SpringBoot教程之入門(二)
詳細SpringBoot教程之配置文件(一)
詳細SpringBoot教程之配置文件(二)
詳細SpringBoot教程之日誌框架
詳細SpringBoot教程之Web開發(一)
詳細SpringBoot教程之Web開發(二)
詳細SpringBoot教程之Web開發(三)

默認訪問首頁

開始正式講解之前呢,先把整個過程的項目源碼貼出來,方便邊看邊學項目GitHub地址,然後我們在講解的過程中還會用到Thymeleaf相關語法,可以邊打開我的另一篇博文當參考手冊,直接點擊那篇博文的目錄,可以快速導航到對應語法的示例,模板引擎Thymeleaf?來這一篇就夠用了

接上一篇博文創建的項目,我們先在properties配置文件中添加一個這個配置

#/接隨便啥名,我這裏用了dbc
server.servlet.context-path=/dbc

意思是應用的上下文路徑,也可以稱爲項目路徑,是構成url地址的一部分。也就是說server.servlet.context-path不配置時,默認爲 / ,如:localhost:8080/xxxxxx。當server.servlet.context-path有配置時,比如 /dbc,此時的訪問方式爲localhost:8080/dbc/xxxxxx,這樣我們就配置好了默認首頁路徑。

在這裏插入圖片描述

國際化

接着我們再來編寫國際化配置文件,在SpringBoot中使用ResouceBundleMessageSource管理國際化配置文件,如果在放在以前的SpringMVC中,我們使用了ResouceBundleMessageSource之後,需要在頁面中使用fmt:message取出國際化配置文件,我們我們在SpringBoot中就當然不需要這樣來寫啦,哈哈哈。在SpringBoot中怎麼使用呢,具體步驟如下

第一步

我們在Resources目錄下,創建一個i18n的包,然後創建三個國際化的properties配置文件
在這裏插入圖片描述
如圖,創建了三個國際化的properties配置文件之後,Idea會檢測到我們是創建了國際化配置文件,會自動幫我們創建國際化配置文件視圖。

接下來我們隨便點進一個國際化配置文件,這裏我點擊進入login.properties中,然後可以點擊Resources Bundle進入,如下
在這裏插入圖片描述
是不是很方便,然後我們這裏總共設置了五條國際化的屬性,意思一下就好了,不用寫那麼多,我們知道怎麼用就可以了,哈哈哈,如下。
在這裏插入圖片描述

第二步

SpringBoot自動配置好了管理國際化資源的文件的組件,即ResourceBundleMessageSource,所以我們只要在properties配置文件中啓用指定國際化文件就可以了,配置如下
在這裏插入圖片描述

第三步

去頁面獲取國際化的值,我們在HTML中使用Thymeleaf語法進行獲取
在這裏插入圖片描述
這裏還是要說明一下,如果出現了亂碼,是因爲properties默認是ASCII編碼,我們Idea是UTF-8編碼,所以會亂碼,怎麼設置之前的博文有說,這裏我就再強調一下,省的你們翻前面的博文。
在這裏插入圖片描述
在這裏插入圖片描述

第四步

現在我們已經設置好了國際化,怎麼測試呢?我們可以切換瀏覽器國際化信息用進行測試,項目會自動檢測瀏覽器語言環境,然後更換,我這裏使用Chrome舉例,點開Chrome的設置->高級,然後更換,如下
在這裏插入圖片描述
爲什麼會自動檢測呢?我們啥都沒有配置,我這裏簡單的說一下按原理,也就是SpringBoot有一個國際化Locale(區域信息對象)以及一個LocaleResolver(獲取區域信息對象),這個就是默認的根據請求頭裏面的,會根據請求頭裏面的Accept-language的值進行讀取配置值。
在這裏插入圖片描述
當然,如果我們不想讓瀏覽器自動檢測,而是通過我們點擊按鈕進行更換語言,像下面這樣。
在這裏插入圖片描述
我們可以自己寫一個實現LocaleResolver接口的類,我們就可以在鏈接上攜帶區域語言信息,不過要注意了,如果我們自己實現了LocaleResolver接口,默認的檢測瀏覽器語言就不生效了,就算我們更換瀏覽器語言也沒有用,我們自己編寫的國際化解析器如下
在這裏插入圖片描述
寫完了之後記得在主配置文件MyMvcConfig中註冊一下我們編寫的國際化解析器組件
在這裏插入圖片描述
HTML的按鈕發出相關請求,在請求後面帶上標記屬性,如下
在這裏插入圖片描述
然後現在就可以重啓測試了,我們點擊按鈕之後,就會在連接上出現屬性值,然後更換語言http://localhost:8080/index.html?l=zh_CN和http://localhost:8080/index.html?l=en_US

登錄進入主頁

我們在登錄頁面的內容如下,有幾個輸入框,用來輸入賬號和密碼的,然後我們寫入之後發送請求,請求的接口是/user/login
在這裏插入圖片描述
這裏我們把/user/login的Controller寫出來
在這裏插入圖片描述
在開發中可能會遇到緩存影響我們刷新頁面開發的情況,我們在可以在配置文件中將Thymeleaf的默認緩存給關掉
在這裏插入圖片描述
現在就可以重新啓動我們的項目了,然後發現可以進入到主頁
在這裏插入圖片描述

攔截器

我們弄好了登錄,這個時候就會想,如果我們不通過正常的登錄,而是直接通過主頁的連接進入到主頁,這樣子我們的登錄界面還有什麼意義呢?所以這裏我們需要對所有請求進行攔截,寫一個LoginHandlerInterceptor實現HandlerInterceptor的接口的攔截器
在這裏插入圖片描述
和LocaleResolver一樣,我們編寫了自己的攔截器之後呢,我們還是需要在主配置文件中進行註冊我們的攔截器組件,順便設置一些我們不需要進行攔截的請求路徑
在這裏插入圖片描述

用戶列表功能

用戶列表的功能效果如下,我們可以顯示用戶的信息,然後進行增刪改查的基本操作,所以我們需要創建Dao層和實體類,代碼內容如下
在這裏插入圖片描述

import com.example.demo.Entities.Department;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.Map;
import java.util.HashMap;

/**
 * @program: demo
 * @description:
 * @author: DBC
 * @create: 2020-02-24 22:54
 **/
@Repository
public class DepartmentDao {

    private static Map<Integer, Department> departments = null;

    static{
        departments = new HashMap<Integer, Department>();

        departments.put(101, new Department(101, "D-AA"));
        departments.put(102, new Department(102, "D-BB"));
        departments.put(103, new Department(103, "D-CC"));
        departments.put(104, new Department(104, "D-DD"));
        departments.put(105, new Department(105, "D-EE"));
    }

    public Collection<Department> getDepartments(){
        return departments.values();
    }

    public Department getDepartment(Integer id){
        return departments.get(id);
    }

}
import com.example.demo.Entities.Department;
import com.example.demo.Entities.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.Map;
import java.util.HashMap;

/**
 * @program: demo
 * @description:
 * @author: DBC
 * @create: 2020-02-24 22:56
 **/
@Repository
public class EmployeeDao {

    private static Map<Integer, Employee> employees = null;

    @Autowired
    private DepartmentDao departmentDao;

    static{
        employees = new HashMap<Integer, Employee>();

        employees.put(1001, new Employee(1001, "E-AA", "[email protected]", 1, new Department(101, "D-AA")));
        employees.put(1002, new Employee(1002, "E-BB", "[email protected]", 1, new Department(102, "D-BB")));
        employees.put(1003, new Employee(1003, "E-CC", "[email protected]", 0, new Department(103, "D-CC")));
        employees.put(1004, new Employee(1004, "E-DD", "[email protected]", 0, new Department(104, "D-DD")));
        employees.put(1005, new Employee(1005, "E-EE", "[email protected]", 1, new Department(105, "D-EE")));
    }

    private static Integer initId = 1006;

    public void save(Employee employee){
        if(employee.getId() == null){
            employee.setId(initId++);
        }

        employee.setDepartment(departmentDao.getDepartment(employee.getDepartment().getId()));
        employees.put(employee.getId(), employee);
    }

    //查詢所有員工
    public Collection<Employee> getAll(){
        return employees.values();
    }

    public Employee get(Integer id){
        return employees.get(id);
    }

    public void delete(Integer id){
        employees.remove(id);
    }
}
import com.example.demo.Dao.DepartmentDao;
import com.example.demo.Dao.EmployeeDao;
import com.example.demo.Entities.Department;
import com.example.demo.Entities.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;

/**
 * @program: demo
 * @description:
 * @author: DBC
 * @create: 2020-02-24 23:14
 **/
@Controller
public class EmployeeController {
    @Autowired
    EmployeeDao employeeDao;

    @Autowired
    DepartmentDao departmentDao;

    //查詢所有員工返回列表頁面
    @GetMapping("/emps")
    public String  list(Model model){
        Collection<Employee> employees = employeeDao.getAll();

        //放在請求域中
        model.addAttribute("emps",employees);
        // thymeleaf默認就會拼串
        // classpath:/templates/xxxx.html
        return "emp/list";
    }

    //來到員工添加頁面
    @GetMapping("/emp")
    public String toAddPage(Model model){
        //來到添加頁面,查出所有的部門,在頁面顯示
        Collection<Department> departments = departmentDao.getDepartments();
        model.addAttribute("depts",departments);
        return "emp/add";
    }

    //員工添加
    //SpringMVC自動將請求參數和入參對象的屬性進行一一綁定;要求請求參數的名字和javaBean入參的對象裏面的屬性名是一樣的
    @PostMapping("/emp")
    public String addEmp(Employee employee){
        //來到員工列表頁面

        System.out.println("保存的員工信息:"+employee);
        //保存員工
        employeeDao.save(employee);
        // redirect: 表示重定向到一個地址  /代表當前項目路徑
        // forward: 表示轉發到一個地址
        return "redirect:/emps";
    }

    //來到修改頁面,查出當前員工,在頁面回顯
    @GetMapping("/emp/{id}")
    public String toEditPage(@PathVariable("id") Integer id,Model model){
        Employee employee = employeeDao.get(id);
        model.addAttribute("emp",employee);

        //頁面要顯示所有的部門列表
        Collection<Department> departments = departmentDao.getDepartments();
        model.addAttribute("depts",departments);
        //回到修改頁面(add是一個修改添加二合一的頁面);
        return "emp/add";
    }

    //員工修改;需要提交員工id;
    @PutMapping("/emp")
    public String updateEmployee(Employee employee){
        System.out.println("修改的員工數據:"+employee);
        employeeDao.save(employee);
        return "redirect:/emps";
    }

    //員工刪除
    @DeleteMapping("/emp/{id}")
    public String deleteEmployee(@PathVariable("id") Integer id){
        employeeDao.delete(id);
        return "redirect:/emps";
    }

}

這裏順便說一下,我們在提交日期格式的字符串的時候,SpringBoot有着自己默認的字符串轉換日期格式的方法,而這個默認方法是需要日期通過“/”進行分離的,如果我們先想要通過“-”進行分離,那麼我們還是需要在主配置文件中設置日期格式的配置,如下
在這裏插入圖片描述

HiddenHttpMethodFilter

  • SpringMVC中配置HiddenHttpMethodFilter;(SpringBoot自動配置好的)
  • 頁面創建一個post表單
  • 創建一個input項,name="_method";值就是我們指定的請求方式

在這裏插入圖片描述
像上面這樣子指定請求的方式,通過這種方式,我們就可以使用同一個路徑請求進行不同的處理操作
在這裏插入圖片描述

下一篇

這裏我們大致上是已經將SpringBoot開發流程走了一遍,不過還有一些web開發相關的操作需要了解,比如錯誤請求等等,將在下一篇博文中進行講解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章