" />

亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Springboot-Management的項(xiàng)目實(shí)踐

 更新時間:2022年05月29日 16:55:10   作者:奔走的王木木Sir  
本文主要介紹了Springboot-Management的項(xiàng)目實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

準(zhǔn)備工作

1.新建一個項(xiàng)目

next之后選擇SpringWebThymeleaf,然后直接next,F(xiàn)inish即可。

之后我們進(jìn)行測試,看是否搭建成功

ok,我們已經(jīng)項(xiàng)目創(chuàng)建好了。

2.導(dǎo)入靜態(tài)資源

根據(jù)下方的圖片展示將資源導(dǎo)入

3.創(chuàng)建實(shí)體類

首先我們先導(dǎo)入lombok

<dependency>
 	<groupId>org.projectlombok</groupId>
 	<artifactId>lombok</artifactId>
    <version>1.18.20</version>
</dependency>

創(chuàng)建pojo的包,在其下創(chuàng)建兩個實(shí)體類Department和Employee

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

//部門表
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Department {
    private Integer id;
    private String departmentName;
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

//員工表
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
    private Integer id;
    private String employeeName;
    private String email;
    private Integer gender; //0:女 1:男

    private Department department;
    private Date birth;
}

遇到的問題:有些人會遇到這個問題,為什么我的lombok導(dǎo)入了,也用將其方法生成了,但是最后不能用,就像下面的情況

其實(shí)不要你以為寫了那三行就是有了,我們打開structure看一下,發(fā)現(xiàn)雖然寫了,但是還是沒有方法。這又是為什么呢?

其實(shí)是因?yàn)槟愕腎DEA里面沒有Lombok的插件,只需要在Setting->Plugins->搜索lombok->Install->重新啟動idea

最后看下成果

4.編寫dao層

同樣建包dao,并在其下創(chuàng)建DepartmentDaoEmployeeDao

import com.hxl.pojo.Department;
import org.springframework.stereotype.Repository;

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

//部門dao
//注冊到IOC容器中
@Repository
public class DepartmentDao {
    //模擬數(shù)據(jù)庫中的數(shù)據(jù)
    private static Map<Integer, Department> departments = null;

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

        departments.put(1, new Department(1, "教學(xué)部"));
        departments.put(2, new Department(2, "市場部"));
        departments.put(3, new Department(3, "調(diào)研部"));
        departments.put(4, new Department(4, "后勤部"));
        departments.put(5, new Department(5, "運(yùn)營部"));
    }

    //獲得所有部門信息
    public Collection<Department> getDepartments(){
        return departments.values();
    }

    //通過id得到部門
    public Department getDepartmentById(Integer id){
        return departments.get(id);
    }
}
import com.hxl.pojo.Department;
import com.hxl.pojo.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

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

//員工dao
//注冊到IOC容器中
@Repository
public class EmployeeDao {
    //模擬數(shù)據(jù)庫中的數(shù)據(jù)
    static private Map<Integer, Employee> employees = null;

    //員工所屬的部門
    @Autowired
    private DepartmentDao departmentDao;

    static {
        employees = new HashMap<Integer, Employee>();//創(chuàng)建一個員工表
        employees.put(1, new Employee(1, "hxl", "1234@qq.com", 1, new Department(1, "教學(xué)部"), new Date()));
        employees.put(2, new Employee(2, "zmc", "5678@qq.com", 1, new Department(2, "市場部"), new Date()));
        employees.put(3, new Employee(3, "kwb", "9012@qq.com", 0, new Department(3, "調(diào)研部"), new Date()));
        employees.put(4, new Employee(4, "lqs", "3456@qq.com", 1, new Department(4, "后勤部"), new Date()));
        employees.put(5, new Employee(5, "wjr", "7890@qq.com", 1, new Department(5, "運(yùn)營部"), new Date()));
    }

    //主鍵自增
    private static Integer initialId = 6;

    //增加一個員工
    public void addEmployee(Employee employee) {
        if (employee.getId() == null) {
            employee.setId(initialId++);
        }
        employee.setDepartment(departmentDao.getDepartmentById(employee.getDepartment().getId()));
        employees.put(employee.getId(), employee);
    }

    //查詢?nèi)繂T工信息
    public Collection<Employee> getAllEmployees() {
        return employees.values();
    }

    //通過id查詢員工
    public Employee getEmployeeById(Integer id) {
        return employees.get(id);
    }

    //通過id刪除員工
    public void deleteEmployeeById(int id) {
        employees.remove(id);
    }
}

至此我們的準(zhǔn)備工作就完成了。

首頁實(shí)現(xiàn)

首先我們像之前創(chuàng)建一個config的包用來存放自定義的配置

創(chuàng)建一個MyMvcConfig的配置類,進(jìn)行首頁的視圖跳轉(zhuǎn)

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //添加一個,打了"/",然后讓他去index
        registry.addViewController("/").setViewName("index");
        registry.addViewController("index.html").setViewName("index");
    }
}

啟動程序,進(jìn)行測試訪問localhost:8080/或者locahost:8080/index.html出現(xiàn)下面的界面就ok了

在這塊中,我們發(fā)現(xiàn)僅有一些文字,樣式圖片等都沒有加載出來,這是因?yàn)槲覀冎皩?dǎo)入的靜態(tài)資源的html,沒有使用Thymeleaf的的語法。我們的模板引擎為Thymeleaf

我們將之前導(dǎo)入的html里面的都改為thymeleaf語法。

注意所有html都需要引入Thymeleaf命名空間

<xmlns:th="http://www.thymeleaf.org">

然后修改所有頁面靜態(tài)資源的引入,使用@{...} 鏈接表達(dá)式(只要是自己本地的鏈接資源,都需要根據(jù)這個語法來修改)

在標(biāo)簽前增加th:

index.html為例

注意:第一個/代表項(xiàng)目的classpath,也就是這里的resources目錄

修改之后我們再次運(yùn)行

中英文切換

首先我們要保證我們的編碼是UTF-8

Properties編寫

接下來我們進(jìn)行配置編寫,在resources目錄下創(chuàng)建一個文件夾i18n,然后在其下創(chuàng)建一個login.propertieslogin_zh_CN.properties創(chuàng)建完成后發(fā)現(xiàn)他們兩個合并了。

這樣我們就有了默認(rèn)配置和中文的配置,接下來再創(chuàng)建一個英語的,來看步驟:

這樣我們就有了三個文件。展示操作的時候到了

首先點(diǎn)擊這里,可以讓我們擁有可視化操作。沒有可視化選項(xiàng)的兄弟下載插件Flagiarism然后重啟就可以了

接下來將我們的內(nèi)容一次創(chuàng)建

直接點(diǎn)擊+號,創(chuàng)建文件名和輸入內(nèi)容即可。

之后我們就會發(fā)現(xiàn)這里也會增加內(nèi)容。

接下來按照圖片一次進(jìn)行創(chuàng)建

這里展示一個內(nèi)容

login.properties

login.btn=登錄
login.password=密碼
login.remember=記住我
login.tip=請登錄
login.username=用戶名

login_en_US.properties

login.btn=Sign in
login.password=Password
login.remember=Remember me
login.tip=Please sign in
login.username=Username

我們設(shè)置完之后,該怎么讓我們的項(xiàng)目識別呢。需要在我們的application.properties下進(jìn)行綁定

# 我們的配置文件的真實(shí)位置
spring.messages.basename=i18n.login

源碼分析:

我們?nèi)?code>MessageSourceAutoConfiguration這個類下,查看messageSource該方法

public MessageSource messageSource(MessageSourceProperties properties);

可以看到,他的參數(shù)是一個MessageSourceProperties對象,我們繼續(xù)查看,它首先是一個屬性basename,默認(rèn)值為message

  • 如果你不在springboot配置文件中指定以.分隔開的國際化資源文件名稱的話
  • 它默認(rèn)會去類路徑下找messages.properties作為國際化資源文件

這也就是我們?yōu)槭裁匆谂渲梦募羞M(jìn)行配置。

后面好了,那么我們的html頁面該怎么進(jìn)行呢。查閱資料發(fā)現(xiàn)Thymeleaf中取值需要進(jìn)行使用到#{}例如

<th:text="#{login.tip}">

根據(jù)上述步驟將其他的幾處也進(jìn)行修改

最后的效果

接下來就是可以中英文進(jìn)行切換,此時需要加一個組件

在我們的首頁界面中可以看到我們的兩個中英文標(biāo)簽

<a class="btn btn-sm">中文</a>
<a class="btn btn-sm">English</a>

此時我們需要對其加上跳轉(zhuǎn)鏈接同時加上參數(shù),原來我們的參數(shù)是現(xiàn)在不需要,用的是()。

<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}" rel="external nofollow" >中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}" rel="external nofollow" >English</a>

自定義地區(qū)的解析器組件

在spring中,有兩個關(guān)于國際化的類,一個是代表地區(qū)的Locale,每一個對象都代表了特定的區(qū)域,還有一個關(guān)于地區(qū)解析器LocaleResolver。

首先搜索WebMvcAutoConfiguration,可以在其中找到關(guān)于一個方法localeResolver()

@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
public LocaleResolver localeResolver() {
    //如果用戶配置了,則使用用戶配置好的,容器中沒有就自己配,有就用用戶的
   if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
      return new FixedLocaleResolver(this.mvcProperties.getLocale());
   }
    //用戶沒有配置,則使用默認(rèn)的,接收頭 國際化分解
   AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
   localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
   return localeResolver;
}

該方法就是獲取LocaleResolver地區(qū)對象解析器:

  1. 如果用戶配置了則使用用戶配置的地區(qū)解析器;
  2. 如果用戶沒有配置,則使用默認(rèn)的地區(qū)解析器

可以發(fā)現(xiàn)它繼承了LocaleResolver接口,實(shí)現(xiàn)了地區(qū)解析

因此我們想要實(shí)現(xiàn)上述自定義的國際化資源生效,只需要編寫一個自己的地區(qū)解析器,繼承LocaleResolver接口,重寫其方法即可

在config包下新建一個MyLocaleResolver

package com.hxl.config;

import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

public class MyLocaleResolver implements LocaleResolver {
    @Override
    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
        //獲取請求中的國際化參數(shù)
        String language = httpServletRequest.getParameter("l");
        //默認(rèn)的地區(qū)
        Locale locale = Locale.getDefault();
        //如果請求的鏈接參數(shù)不為空,攜帶了國際化參數(shù)
        if (!StringUtils.isEmpty(language)) {
            String[] split = language.split("_");//zh_CN(語言_地區(qū))
            locale = new Locale(split[0], split[1]);
        }
        return locale;
    }

    @Override
    public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {

    }
}

完成組件后,需要在MvcConfig配置類下添加上我們的Bean

//自定義的國際化組件生效
@Bean
public LocaleResolver localeResolver() {
    return new MyLocaleResolver();
}

重新啟動項(xiàng)目,我們就可以通過點(diǎn)擊下方的中英文來進(jìn)行切換。

總結(jié)

  • 我們需要配置i18n文件
  • 需要自定義一個組件MyLocaleResolver,以便在項(xiàng)目中進(jìn)行按鈕的自動切換。
  • 將自己的組件配置到spring容器中@Bean
  • 取值用的是#{}

登錄功能

1.頁面調(diào)整

我們需要將這里進(jìn)行修改。

查看頁面之后發(fā)現(xiàn),我們點(diǎn)擊登錄按鈕的時候會進(jìn)入dashboard頁面。

所以我們需要將這里的提交地址進(jìn)行修改,以及將用戶名和密碼框加上屬性以便傳參。

2.編寫LoginController

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class LoginController {
    @RequestMapping("/user/login")
    public String login(@RequestParam("username") String username,@RequestParam("password") String password, Model model){
        //如果用戶名和密碼都正確
        if("wangmm".equals(username) && "123456".equals(password)){
            return "dashboard";
        }else{
            //如果用戶名或者密碼不正確
            model.addAttribute("msg","用戶名或者密碼不正確");
            return "index";
        }
    }
}

我們需要在登錄頁面增加一個返回錯誤信息的標(biāo)簽。

此時啟動程序并訪問localhost:8080。輸入正確的賬號密碼訪問我們可以看到這個頁面

輸入錯誤的賬號密碼會呈現(xiàn)

好了,我們這里已經(jīng)成功了。但是當(dāng)我們成功登錄后我們的頁面顯示不全,這是因?yàn)橹疤岬降撵o態(tài)頁面展示的問題,需要把我們dashboard頁面下的本地靜態(tài)資源都用Thymeleaf語法進(jìn)行修改。修改成功后即可。

同時我們可以到瀏覽器頁面的url暴露了我們的信息。所以我們需要進(jìn)行修改。

在自定義的配置類MyMvcConfig中增加。這樣我們訪問main.html也就是訪問了dashboard頁面。

registry.addViewController("/main.html").setViewName("dashboard");

同時我們也要去將LoginController下的登錄頁面也重定向到main.html中。

@Controller
public class LoginController {
    @RequestMapping("/user/login")
    public String login(@RequestParam("username") String username,@RequestParam("password") String password, Model model){
        //如果用戶名和密碼都正確
        if("wangmm".equals(username) && "123456".equals(password)){
            return "redirect:/main.html";
        }else{
            //如果用戶名或者密碼不正確
            model.addAttribute("msg","用戶名或者密碼不正確");
            return "index";
        }
    }
}

之后我們運(yùn)行查看,瀏覽器上的url不再攜帶用戶的信息。

此時出現(xiàn)了新的問題,就是我們不管登錄不登錄,通過localhost:8080/main.html都可以訪問到我們的dashboard的頁面。

3.登錄攔截器

config目錄下,新建一個登錄攔截器類LoginHandlerInterceptor

目的:用戶登錄成功后得到用戶的信息。防止未登錄用戶查看頁面

得到用戶信息,我們需要先保存用戶的信息,所以我們需要在LoginController中當(dāng)用戶登錄成功后,存入用戶信息到session

@Controller
public class LoginController {
    @RequestMapping("/user/login")
    public String login(@RequestParam("username") String username,@RequestParam("password") String password, Model model, HttpSession session){
        //如果用戶名和密碼都正確
        if("wangmm".equals(username) && "123456".equals(password)){
            session.setAttribute("LoginUser", username);
            return "redirect:/main.html";
        }else{
            //如果用戶名或者密碼不正確
            model.addAttribute("msg","用戶名或者密碼不正確");
            return "index";
        }
    }
}

實(shí)現(xiàn)攔截器。需要繼承HandlerInterceptor接口

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //用戶登錄成功擁有session
        Object loginUser = request.getSession().getAttribute("LoginUser");
        if(loginUser == null){
            request.setAttribute("msg","用戶權(quán)限不夠,請登錄");
            //權(quán)限不夠就重定向到首頁
            request.getRequestDispatcher("/index.html").forward(request,response);
            return false;
        }else{
            return true;
        }
    }
}

有了攔截器就需要注冊到bean中,在MyMvcConfig配置類中,添加我們自定義的攔截器,注意屏蔽主頁、登錄相關(guān)請求、靜態(tài)資源的攔截

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LoginHandlerInterceptor())
            .addPathPatterns("/**")
            .excludePathPatterns("/index.html", "/", "/user/login", "/asserts/**");
}

注意這個地方,有些人不是在整一個文件夾中,所以需要分開寫"/css/**", "/js/**", "/img/**"

測試:啟動程序直接訪問http://localhost:8080/main.html

之后我們登錄,成功之后再重新進(jìn)入之前的鏈接http://localhost:8080/main.html發(fā)現(xiàn)也是可以訪問得到的。

這是因?yàn)榈卿浿笥脩舻男畔⒁呀?jīng)保存在了session中。攔截器自然不會攔截。

員工信息——查

實(shí)現(xiàn)界面中的Customers中的員工查詢。

  • th:fragment="sidebar"
  • th:replace="~{commons/commons::topbar}"
  • 如果要傳遞參數(shù),可以直接使用()傳參,接收判斷即可
  • 列表循環(huán)展示

首先我們先將模板中的跳轉(zhuǎn)鏈接進(jìn)行跳轉(zhuǎn)

同時將list.html中的代碼進(jìn)行修改

templates目錄下新建一個包emp用來存放員工的相關(guān)頁面

之后我們編寫對應(yīng)的Controller

package com.hxl.controller;

import com.hxl.dao.EmployeeDao;
import com.hxl.pojo.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.Collection;

@Controller
public class EmployeeController {
    @Autowired
    private EmployeeDao employeeDao;

    @RequestMapping("/emps")
    public String list(Model model){
        Collection<Employee> employees = employeeDao.getAllEmployees();
        model.addAttribute("emps",employees);
        return "emp/list";
    }
}

啟動測試,發(fā)現(xiàn)是這個頁面,這是由于咱們的語法有問題,和之前的一樣將本地靜態(tài)資源進(jìn)行修改。

之后進(jìn)行修改可以得到新的界面。

優(yōu)化

點(diǎn)擊員工管理之后應(yīng)該是高亮的狀態(tài),但是我們發(fā)現(xiàn)點(diǎn)擊之后高亮不在Customers而在Dashboard

同時我們可以將側(cè)邊欄以及頂部欄公共的部分進(jìn)行提煉

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">

<!--頂部導(dǎo)航欄,利用th:fragment提取出來,命名為topbar-->
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topbar">
    <a class="navbar-brand col-sm-3 col-md-2 mr-0"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >Company
        name</a>
    <input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
    <ul class="navbar-nav px-3">
        <li class="nav-item text-nowrap">
            <a class="nav-link"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >Sign out</a>
        </li>
    </ul>
</nav>

<!--側(cè)邊欄,利用th:fragment提取出來,命名為sidebar-->
<nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="siderbar">
    <div class="sidebar-sticky">
        <ul class="nav flex-column">
            <li class="nav-item">
                <a class="nav-link active"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-home">
                        <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
                        <polyline points="9 22 9 12 15 12 15 22"></polyline>
                    </svg>
                    Dashboard <span class="sr-only">(current)</span>
                </a>
            </li>
            <li class="nav-item">
                <a class="nav-link"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-file">
                        <path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path>
                        <polyline points="13 2 13 9 20 9"></polyline>
                    </svg>
                    Orders
                </a>
            </li>
            <li class="nav-item">
                <a class="nav-link"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-shopping-cart">
                        <circle cx="9" cy="21" r="1"></circle>
                        <circle cx="20" cy="21" r="1"></circle>
                        <path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path>
                    </svg>
                    Products
                </a>
            </li>
            <li class="nav-item">
                <a class="nav-link" th:href="@{/emps}" rel="external nofollow" >
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-users">
                        <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
                        <circle cx="9" cy="7" r="4"></circle>
                        <path d="M23 21v-2a4 4 0 0 0-3-3.87"></path>
                        <path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
                    </svg>
                    Customers
                </a>
            </li>
            <li class="nav-item">
                <a class="nav-link"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-bar-chart-2">
                        <line x1="18" y1="20" x2="18" y2="10"></line>
                        <line x1="12" y1="20" x2="12" y2="4"></line>
                        <line x1="6" y1="20" x2="6" y2="14"></line>
                    </svg>
                    Reports
                </a>
            </li>
            <li class="nav-item">
                <a class="nav-link"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-layers">
                        <polygon points="12 2 2 7 12 12 22 7 12 2"></polygon>
                        <polyline points="2 17 12 22 22 17"></polyline>
                        <polyline points="2 12 12 17 22 12"></polyline>
                    </svg>
                    Integrations
                </a>
            </li>
        </ul>

        <h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
            <span>Saved reports</span>
            <a class="d-flex align-items-center text-muted"
                rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >
                <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
                     stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
                     class="feather feather-plus-circle">
                    <circle cx="12" cy="12" r="10"></circle>
                    <line x1="12" y1="8" x2="12" y2="16"></line>
                    <line x1="8" y1="12" x2="16" y2="12"></line>
                </svg>
            </a>
        </h6>
        <ul class="nav flex-column mb-2">
            <li class="nav-item">
                <a class="nav-link"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-file-text">
                        <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
                        <polyline points="14 2 14 8 20 8"></polyline>
                        <line x1="16" y1="13" x2="8" y2="13"></line>
                        <line x1="16" y1="17" x2="8" y2="17"></line>
                        <polyline points="10 9 9 9 8 9"></polyline>
                    </svg>
                    Current month
                </a>
            </li>
            <li class="nav-item">
                <a class="nav-link"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-file-text">
                        <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
                        <polyline points="14 2 14 8 20 8"></polyline>
                        <line x1="16" y1="13" x2="8" y2="13"></line>
                        <line x1="16" y1="17" x2="8" y2="17"></line>
                        <polyline points="10 9 9 9 8 9"></polyline>
                    </svg>
                    Last quarter
                </a>
            </li>
            <li class="nav-item">
                <a class="nav-link"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-file-text">
                        <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
                        <polyline points="14 2 14 8 20 8"></polyline>
                        <line x1="16" y1="13" x2="8" y2="13"></line>
                        <line x1="16" y1="17" x2="8" y2="17"></line>
                        <polyline points="10 9 9 9 8 9"></polyline>
                    </svg>
                    Social engagement
                </a>
            </li>
            <li class="nav-item">
                <a class="nav-link"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-file-text">
                        <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
                        <polyline points="14 2 14 8 20 8"></polyline>
                        <line x1="16" y1="13" x2="8" y2="13"></line>
                        <line x1="16" y1="17" x2="8" y2="17"></line>
                        <polyline points="10 9 9 9 8 9"></polyline>
                    </svg>
                    Year-end sale
                </a>
            </li>
        </ul>
    </div>
</nav>
</html>

提取頁面的公共部分

我們可以將兩個頁面dashboard.htmllist.html`中頂部導(dǎo)航欄和側(cè)邊欄的代碼刪除

啟動測試查看:所有頂部和側(cè)邊都沒有了

將公共的部分引入

dashboard.htmllist.html刪除的部分插入提取出來的公共部分topbarsidebar

<!--頂部導(dǎo)航欄-->
<div th:replace="~{commons/commons::topbar}" }></div>
<!--側(cè)邊欄-->
<div th:replace="~{commons/commons::siderbar}"></div>

解決高亮

通過觀察,在頁面中高亮的部分是由于class="nav-link active"屬性

我們可以通過傳遞參數(shù)來進(jìn)行判斷說明自己的頁面應(yīng)該哪里高亮

dashboard.html的側(cè)邊欄標(biāo)簽傳遞參數(shù)activedashboard.html

<!--側(cè)邊欄-->
<div th:replace="~{commons/commons::siderbar(active='dashboard.html')}"></div>

list.html的側(cè)邊欄標(biāo)簽傳遞參數(shù)activelist.html

<!--頂部導(dǎo)航欄-->
<div th:replace="~{commons/commons::siderbar(active='list.html')}" }></div>

我們將頁面參數(shù)修改后需要在公共頁面部分接收參數(shù)active

th:class="${active=='dashboard.html'?'nav-link active':'nav-link'}"

th:class="${active=='list.html'?'nav-link active':'nav-link'}"

測試:

點(diǎn)擊Customers,Customers高亮,成功

顯示員工信息

list.html中數(shù)據(jù)進(jìn)行修改,顯示員工的信息,并添加編輯和刪除的標(biāo)簽

<table class="table table-striped table-sm">
							<thead>
								<tr>
									<th>id</th>
									<th>employeeName</th>
									<th>email</th>
									<th>gender</th>
									<th>department</th>
									<th>birth</th>
									<th>操作</th>
								</tr>
							</thead>
							<tbody>
								<tr th:each="emp:${emps}">
									<td th:text="${emp.getId()}"></td>
									<td th:text="${emp.getEmployeeName()}"></td>
									<td th:text="${emp.getEmail()}"></td>
									<td th:text="${emp.getGender()==0?'女':'男'}"></td>
									<td th:text="${emp.getDepartment().getDepartmentName()}"></td>
									<td th:text="${#dates.format(emp.getBirth(),'yyyy-MM-dd HH:mm:ss')}"></td>
									<td>
										<a class="btn btn-sm btn-primary">編輯</a>
										<a class="btn btn-sm btn-danger">刪除</a>
									</td>
								</tr>
							</tbody>
						</table>

修改成功后,測試

員工信息——增

  • 按鈕提交
  • 跳轉(zhuǎn)到添加頁面
  • 添加員工成功
  • 返回首頁

表單提交盡量用重定向:redirect,否則容易出現(xiàn)表單重復(fù)提交

首先增加提交按鈕

list.html中增加一個添加員工的按鈕,點(diǎn)擊按鈕時發(fā)起有一個/addEmps的請求

<a class="btn btn-sm btn-success" th:href="@{/addEmps}" rel="external nofollow" >添加員工</a>

這里去編寫對應(yīng)的controller,處理請求。

通過get的方式進(jìn)行請求提交,所以在EmployeeController中添加一個方法addEmps用來處理list頁面點(diǎn)擊提交按鈕的操作,返回到add.html添加員工頁面(頁面需要增加,原先沒有)

注意在最開始的地方將departmentDao進(jìn)行裝配

@Autowired
private DepartmentDao departmentDao;
@GetMapping("/addEmps")
public String add(Model model) {
    //查出所有的部門信息,添加到departments中,用于前端接收
    Collection<Department> departments = departmentDao.getDepartments();
    model.addAttribute("departments", departments);
    return "emp/add";//返回到添加員工頁面
}

創(chuàng)建員工界面add.html

在我們的templates/emp下新建一個add.html,只需要將list.html界面進(jìn)行復(fù)制,然后修改表單即可。修改內(nèi)容如下:

<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
   <form>
      <div class="form-group">
		<label>EmployeeName</label>
		<input type="text" name="employeeName" class="form-control" placeholder="employeeName:hxl">
		</div>
      <div class="form-group">
         <label>Email</label>
         <input type="email" name="email" class="form-control" placeholder="email:xxxxx@qq.com">
      </div>
      <div class="form-group">
         <label>Gender</label><br/>
         <div class="form-check form-check-inline">
            <input class="form-check-input" type="radio" name="gender" value="1">
            <label class="form-check-label">男</label>
         </div>
         <div class="form-check form-check-inline">
            <input class="form-check-input" type="radio" name="gender" value="0">
            <label class="form-check-label">女</label>
         </div>
      </div>
      <div class="form-group">
         <label>department</label>
         <!--注意這里的name是department.id,因?yàn)閭魅氲膮?shù)為id-->
          <!--我們在controller中接收的是一個Employee,所以我們需要提交的是其中的一個屬性-->
         <select class="form-control" name="department.id">
            <option th:each="department:${departments}" th:text="${department.getDepartmentName()}" th:value="${department.getId()}"></option>
         </select>
      </div>
      <div class="form-group">
         <label>Birth</label>
         <!--springboot默認(rèn)的日期格式為yy/MM/dd-->
         <input type="text" name="date" class="form-control" placeholder="birth:yyyy/MM/dd">
      </div>
      <button type="submit" class="btn btn-primary">添加</button>
   </form>

</main>

注意下拉框中的內(nèi)容應(yīng)該是我們自己部門名。通過遍歷得到

<!--通過遍歷得到部門的信息,顯示是部門的名字,傳入的是部門的id-->
<option th:each="department:${departments}" th:text="${department.getDepartmentName()}" th:value="${department.getId()}"></option>

測試:

員工請求addEmps

add.html頁面,當(dāng)我們填寫完信息,點(diǎn)擊添加按鈕,應(yīng)該完成添加返回到list頁面,展示新的員工信息;因此在add.html點(diǎn)擊添加按鈕的一瞬間,我們同樣發(fā)起一個請求/addEmps,與上述提交按鈕發(fā)出的請求路徑一樣,但這里發(fā)出的是post請求

編寫對應(yīng)的controller

@PostMapping("/addEmps")
public String addEmp(Employee employee) {
    employeeDao.addEmployee(employee);//添加一個員工
    return "redirect:/emps";//重定向到/emps,刷新列表,返回到list頁面
}

測試:

提交之后我們可以跳轉(zhuǎn)到員工頁面查看我們的新增加的員工

差一個添加成功的圖片

同時這里需要注意:日期格式必須是yyyy/MM/dd才能正確跳轉(zhuǎn),否則就會出錯。因?yàn)檫@是spring默認(rèn)的,如果要修改日期格式,需要在application.properties中進(jìn)行修改

spring.mvc.date-format=yyyy-MM-dd

這樣日期格式就變了,此時原來的格式就不能用了

鏈接形式處理是getMapping

員工信息——改

首頁編輯按鈕

當(dāng)我們點(diǎn)擊編輯時,應(yīng)該跳轉(zhuǎn)到更新員工的頁面update.html,在list.html中修改

<a class="btn btn-sm btn-primary" th:href="@{/update/{id}(id=${emp.getId()})}" rel="external nofollow" >編輯</a>

這里進(jìn)行跳轉(zhuǎn)就需要GetMapping

編寫對應(yīng)controller,在EmployeeController中添加一個方法update用來處理list頁面點(diǎn)擊編輯按鈕的操作,返回到update.html

//restful風(fēng)格接收參數(shù)
@GetMapping("/update/{id}")
public String update(@PathVariable("id") int id, Model model) {
    //查詢指定id的員工,添加到empByID中,用于前端接收
    Employee employeeByID = employeeDao.getEmployeeById(id);
    model.addAttribute("empByID", employeeByID);
    //查出所有的部門信息,添加到departments中,用于前端接收
    Collection<Department> departments = departmentDao.getDepartments();
    model.addAttribute("departments", departments);
    return "emp/update";//返回到編輯員工頁面
}

更新員工的頁面

復(fù)制add.html并修改

<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
					<form th:action="@{/update}" method="post">
						<input type="hidden" name="id" th:value="${empByID.getId()}">
						<div class="form-group">
							<label>employeeName</label>
							<input th:value="${empByID.getEmployeeName()}" type="text" name="employeeName" class="form-control"
								   placeholder="employeeName:hxl">
						</div>
						<div class="form-group">
							<label>Email</label>
							<input th:value="${empByID.getEmail()}" type="email" name="email" class="form-control"
								   placeholder="email:xxxxx@qq.com">
						</div>
						<div class="form-group">
							<label>Gender</label><br/>
							<div class="form-check form-check-inline">
								<input th:checked="${empByID.getGender()==1}" class="form-check-input" type="radio"
									   name="gender" value="1">
								<label class="form-check-label">男</label>
							</div>
							<div class="form-check form-check-inline">
								<input th:checked="${empByID.getGender()==0}" class="form-check-input" type="radio"
									   name="gender" value="0">
								<label class="form-check-label">女</label>
							</div>
						</div>
						<div class="form-group">
							<label>department</label>
							<!--注意這里的name是department.id,因?yàn)閭魅氲膮?shù)為id-->
							<select class="form-control" name="department.id">
								<option th:selected="${department.getId()==empByID.department.getId()}"
										th:each="department:${departments}" th:text="${department.getDepartmentName()}"
										th:value="${department.getId()}">
								</option>
							</select>
						</div>
						<div class="form-group">
							<label>Birth</label>
							<!--springboot默認(rèn)的日期格式為yyyy/MM/dd-->
							<input th:value="${#dates.format(empByID.getBirth(),'yyyy/MM/dd')}" type="text" name="date" class="form-control"
								   placeholder="birth:yyyy/MM/dd">
						</div>
						<button type="submit" class="btn btn-primary">修改</button>
					</form>
				</main>

這里已經(jīng)將日期格式進(jìn)行了修改,沒有修改之前的日期是不太正確的。

同時頁面跳轉(zhuǎn)的時候需要將Id攜帶過去。但是不能顯示出來,所以需要hidden在上方已經(jīng)有標(biāo)注。

頁面提交請求

頁面編輯完成后會發(fā)起一個請求

<form th:action="@{/update}" method="post">

這需要我們?nèi)ontroller中處理請求

@PostMapping("/update")
public String updateEmp(Employee employee) {
    employeeDao.addEmployee(employee);//添加一個員工
    return "redirect:/emps";//添加完成重定向到/emps,刷新列表
}

測試:

原來的信息:

點(diǎn)擊編輯之后:

修改之后:

?

成功將員工進(jìn)行了修改。

員工信息——刪

點(diǎn)擊刪除進(jìn)行請求跳轉(zhuǎn):修改我們的刪除標(biāo)簽

<a class="btn btn-sm btn-success" th:href="@{/delete/{id}(id=${emp.getId()})}" rel="external nofollow" >刪除</a>

然后編寫對應(yīng)的controller,處理點(diǎn)擊刪除按鈕的請求,刪除指定員工,重定向到/emps請求,更新員工信息

@GetMapping("/delete/{id}")
public String delete(@PathVariable("id") Integer id) {
    employeeDao.deleteEmployeeById(id);
    return "redirect:/emps";
}

測試:

刪除成功

錯誤頁面定制

404頁面定制

springboot中錯誤頁面定制比較簡單,比如說404。直接在thmplates下新建一個error文件夾,然后將404頁面直接丟進(jìn)去即可。

登錄測試一下

注銷

在我們提取出來的公共commons頁面,頂部導(dǎo)航欄處中的標(biāo)簽添加href屬性,實(shí)現(xiàn)點(diǎn)擊發(fā)起請求/user/logout

<a class="nav-link" th:href="@{/user/logout}" rel="external nofollow" >Sign out</a>

LoginController中編寫對應(yīng)的方法,清除session,并重定向到首頁

@RequestMapping("/user/logout")
public String logout(HttpSession session) {
    session.invalidate();
    return "redirect:/index.html";
}

測試:點(diǎn)擊右上角的Sign out就可以退出界面,訪問main.html是沒有權(quán)限的。

到此這篇關(guān)于Springboot-Management的項(xiàng)目實(shí)踐的文章就介紹到這了,更多相關(guān)Springboot Management內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java?WebSocket?服務(wù)端實(shí)現(xiàn)代碼

    java?WebSocket?服務(wù)端實(shí)現(xiàn)代碼

    WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議。它實(shí)現(xiàn)了瀏覽器與服務(wù)器全雙工(full-duplex)通信——允許服務(wù)器主動發(fā)送信息給客戶端,這篇文章主要介紹了java?WebSocket?服務(wù)端代碼,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-02-02
  • Java的增強(qiáng)for循環(huán)修改數(shù)組元素的問題小結(jié)

    Java的增強(qiáng)for循環(huán)修改數(shù)組元素的問題小結(jié)

    增強(qiáng)for循環(huán)的元素變量x,就是一個局部變量,它是引用數(shù)組當(dāng)前元素引用的副本(就相當(dāng)于上文所說的你復(fù)刻朋友的鑰匙),或者是基本數(shù)據(jù)類型的值的副本,這篇文章主要介紹了Java的增強(qiáng)for循環(huán)修改數(shù)組元素的問題小結(jié),需要的朋友可以參考下
    2024-02-02
  • Springboot如何操作redis數(shù)據(jù)

    Springboot如何操作redis數(shù)據(jù)

    這篇文章主要介紹了Springboot如何操作redis數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-04-04
  • Spring Boot2與Spring Boot3的區(qū)別小結(jié)

    Spring Boot2與Spring Boot3的區(qū)別小結(jié)

    SpringBoot2和SpringBoot3之間有一些重要的區(qū)別,本文就來探討SpringBoot2和SpringBoot3之間的區(qū)別,具有一定的參考價值,感興趣的可以了解一下
    2023-10-10
  • Java開發(fā)利器之Guava?Cache的使用教程

    Java開發(fā)利器之Guava?Cache的使用教程

    緩存技術(shù)被認(rèn)為是減輕服務(wù)器負(fù)載、降低網(wǎng)絡(luò)擁塞、增強(qiáng)Web可擴(kuò)展性的有效途徑之一。今天咱們就來聊聊Guava?Cache本地緩存,感興趣的可以了解一下
    2022-09-09
  • Java中String字符串常量池和intern方法源碼分析

    Java中String字符串常量池和intern方法源碼分析

    在之前的文章中,小編給大家介紹了String字符串的不可變性及其實(shí)現(xiàn)原理,其中給大家提到了字符串常量池的概念,那么什么是常量池,String字符串與常量池有什么關(guān)系,本文給大家嘮嘮字符串常量池及String#intern()方法的作用,需要的朋友可以參考下
    2023-05-05
  • 怎么運(yùn)行用記事本寫的java程序

    怎么運(yùn)行用記事本寫的java程序

    以下小編就為大家介紹一下,怎么運(yùn)行用記事本寫的java程序。需要的朋友可以過來參考下
    2013-08-08
  • Spring Boot框架中的@Conditional注解示例詳解

    Spring Boot框架中的@Conditional注解示例詳解

    這篇文章主要介紹了Spring Boot框架中的@Conditional系列注解,@ConditionalOnProperty注解的作用是解析application.yml/application.properties 里的配置生成條件來生效,也是與@Configuration注解一起使用,本文通過示例代碼給大家介紹的非常詳細(xì),需要的朋友一起看看吧
    2022-09-09
  • 關(guān)于Http持久連接和HttpClient連接池的深入理解

    關(guān)于Http持久連接和HttpClient連接池的深入理解

    眾所周知,httpclient是java開發(fā)中非常常見的一種訪問網(wǎng)絡(luò)資源的方式了,下面這篇文章主要給大家介紹了關(guān)于Http持久連接和HttpClient連接池的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-05-05
  • Java 中ConcurrentHashMap的實(shí)現(xiàn)

    Java 中ConcurrentHashMap的實(shí)現(xiàn)

    本文主要介紹Java 中ConcurrentHashMap的實(shí)現(xiàn),這里整理了詳細(xì)的資料,及簡單實(shí)例代碼,有興趣的小伙伴可以參考下
    2016-09-09

最新評論